Complete.Org: Mailing Lists: Archives: freeciv-dev: June 1999:
Re: [Freeciv-Dev] [PATCH] CHRONO
Home

Re: [Freeciv-Dev] [PATCH] CHRONO

[Top] [All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index] [Thread Index]
To: maage@xxxxxxxxx
Cc: freeciv-dev@xxxxxxxxxxx
Subject: Re: [Freeciv-Dev] [PATCH] CHRONO
From: David Pfitzner <dwp@xxxxxxxxxxxxxx>
Date: Mon, 28 Jun 1999 11:59:37 +1000 (EST)

Markus Linnala wrote:
> 
> This patch changes CHRONO to use getrusage and implements handy
> macros. With getrusage you are somewhat immune to other load on
> the machine. Macro interface is somewhat tricky. But I think
> that should not be problem, as this interface is purely to
> developers.

Ah, I also tried to tidy up the CHRONO stuff recently :-}
(And timing in general.)  Oops.

I was going to leave this till after the next release, but
now might as well post it here, so we can consider which
approach to use, or whether to merge ideas from both.
(Though either way I think changes to this should wait till
after 1.8.1.)  

Re your patch: should the getrusage stuff be protected by 
configure checks, or can we expect getrusage everywhere?  
Oh, ok, it's still only used if CHRONO is defined, so I guess 
only define CHRONO if you know what you're doing and know 
that it works, like the current situation with gettimeofday.

Notes for my patch:

: This patch isolates some timing code into a new module common/timing.
: The new module allows both CPU timing, and user ("wall clock") timing; 
: for the latter it uses gettimeofday() if available, or else falls
: back to time().  (For CPU timing it uses clock().)
:
: This patch replaces the old #ifdef CHRONO stuff, and a few other 
: places.  The old CHRONO stuff is actually a bit different after this, 
: since before it was doing user timing, whereas CPU timing is really 
: more appropriate.

I think my approach is a bit more general, but perhaps
also a bit more bloated...

Regards,
-- David
diff -N -u -r --exclude-from exclude freeciv-cvs/ai/aiunit.c fc-adv/ai/aiunit.c
--- freeciv-cvs/ai/aiunit.c     Tue Jun 22 21:05:08 1999
+++ fc-adv/ai/aiunit.c  Mon Jun 28 11:54:42 1999
@@ -16,11 +16,6 @@
 #include <string.h>
 #include <assert.h>
 
-#ifdef CHRONO
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
 #include "city.h"
 #include "game.h"
 #include "log.h"
@@ -28,6 +23,7 @@
 #include "packets.h"
 #include "player.h"
 #include "shared.h"
+#include "timing.h"
 #include "unit.h"
 
 #include "cityhand.h"
@@ -1518,12 +1514,10 @@
 
 void ai_manage_units(struct player *pplayer) 
 {
-#ifdef CHRONO
-  int sec, usec;
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  sec = tv.tv_sec; usec = tv.tv_usec;
-#endif
+  static struct timer *t = NULL;      /* alloc once, never free */
+
+  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
+
   freelog(LOG_DEBUG, "Managing units for %s", pplayer->name);
   unit_list_iterate(pplayer->units, punit) {
     freelog(LOG_DEBUG, "Managing %s's %s %d@(%d,%d)", pplayer->name,
@@ -1534,11 +1528,10 @@
   }
   unit_list_iterate_end;
   freelog(LOG_DEBUG, "Managed units successfully.");
-#ifdef CHRONO
-  gettimeofday(&tv, 0);
-  freelog(LOG_VERBOSE, "%s's units consumed %ld microseconds.", pplayer->name,
-         (long)((tv.tv_sec - sec) * 1000000 + (tv.tv_usec - usec)));
-#endif
+  if (timer_in_use(t)) {
+    freelog(LOG_VERBOSE, "%s's units consumed %g milliseconds.",
+           pplayer->name, 1000.0*read_timer_seconds(t));
+  }
 }
 
 /**************************************************************************
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.am 
fc-adv/common/Makefile.am
--- freeciv-cvs/common/Makefile.am      Thu Jun 17 21:34:03 1999
+++ fc-adv/common/Makefile.am   Mon Jun 28 11:54:43 1999
@@ -39,6 +39,8 @@
                spaceship.h     \
                tech.c          \
                tech.h          \
+               timing.c        \
+               timing.h        \
                unit.c          \
                unit.h          \
                version.h
diff -N -u -r --exclude-from exclude freeciv-cvs/common/Makefile.in 
fc-adv/common/Makefile.in
--- freeciv-cvs/common/Makefile.in      Thu Jun 17 21:34:03 1999
+++ fc-adv/common/Makefile.in   Mon Jun 28 11:56:22 1999
@@ -84,7 +84,7 @@
 
 INCLUDES = 
 
-libcivcommon_a_SOURCES =               attribute.h                     
capability.c                    capability.h                    capstr.c        
                capstr.h                        city.c                          
city.h                          diptreaty.c                     diptreaty.h     
                events.h                        game.c                          
game.h                          genlist.c                       genlist.h       
                log.c                           log.h                           
map.c                           map.h                           packets.c       
                packets.h                       player.c                        
player.h                        mem.c                           mem.h           
                registry.c                      registry.h                      
sbuffer.c                       sbuffer.h                       shared.c        
                shared.h                        spaceship.c                     
spaceship.h                     tech.c                          tech.h          
                unit.c                          unit.h                          
version.h
+libcivcommon_a_SOURCES =               attribute.h                     
capability.c                    capability.h                    capstr.c        
                capstr.h                        city.c                          
city.h                          diptreaty.c                     diptreaty.h     
                events.h                        game.c                          
game.h                          genlist.c                       genlist.h       
                log.c                           log.h                           
map.c                           map.h                           packets.c       
                packets.h                       player.c                        
player.h                        mem.c                           mem.h           
                registry.c                      registry.h                      
sbuffer.c                       sbuffer.h                       shared.c        
                shared.h                        spaceship.c                     
spaceship.h                     tech.c                          tech.h          
                timing.c                        timing.h                        
unit.c                          unit.h                          version.h
 
 mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs
 CONFIG_HEADER = ../config.h
@@ -103,7 +103,7 @@
 libcivcommon_a_LIBADD = 
 libcivcommon_a_OBJECTS =  capability.o capstr.o city.o diptreaty.o \
 game.o genlist.o log.o map.o packets.o player.o mem.o registry.o \
-sbuffer.o shared.o spaceship.o tech.o unit.o
+sbuffer.o shared.o spaceship.o tech.o timing.o unit.o
 AR = ar
 CFLAGS = @CFLAGS@
 COMPILE = $(CC) $(DEFS) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) 
$(CFLAGS)
@@ -120,7 +120,7 @@
 .deps/diptreaty.P .deps/game.P .deps/genlist.P .deps/log.P .deps/map.P \
 .deps/mem.P .deps/packets.P .deps/player.P .deps/registry.P \
 .deps/sbuffer.P .deps/shared.P .deps/spaceship.P .deps/tech.P \
-.deps/unit.P
+.deps/timing.P .deps/unit.P
 SOURCES = $(libcivcommon_a_SOURCES)
 OBJECTS = $(libcivcommon_a_OBJECTS)
 
diff -N -u -r --exclude-from exclude freeciv-cvs/common/timing.c 
fc-adv/common/timing.c
--- freeciv-cvs/common/timing.c Thu Jan  1 10:00:00 1970
+++ fc-adv/common/timing.c      Mon Jun 28 11:54:43 1999
@@ -0,0 +1,374 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+/********************************************************************** 
+  Measuring times; original author: David Pfitzner <dwp@xxxxxxxxxxxxxx>
+
+  We assume we have at least ANSI/ISO C timing functions, so
+  that we can use:
+     clock_t clock() for CPU times
+     time_t time() for user-time
+  If we have HAVE_GETTIMEOFDAY we use gettimeofday() for user-time
+  to get (usually) better resolution than time().
+
+  As well as measuring single time intervals, these functions
+  support accumulating the time from multiple separate intervals.
+
+  Notice the struct timer is an opaque type: modules outside timing.c
+  can only use it as a pointer (cf FILE type).  This is done for two
+  main reasons:
+  
+   1. General principle of data hiding and encapsulation
+   
+   2. Means we don't have to include config.h and possibly system
+      specific header files in timing.h.  Such stuff is confined
+      inside timing.c.
+      
+  However there is a disadvantage: any code using a timer must do
+  memory allocation and deallocation for it.  Some of the functions
+  below are intended to make this reasonably convenient; see function
+  comments.
+***********************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <time.h>
+#include <assert.h>
+
+#ifdef HAVE_GETTIMEOFDAY
+#include <sys/time.h>
+#include <unistd.h>
+#endif
+
+#include "log.h"
+#include "mem.h"
+
+#include "timing.h"
+
+#ifndef CLOCKS_PER_SEC
+#ifdef CLOCKS_PER_SECOND
+#define CLOCKS_PER_SEC CLOCKS_PER_SECOND
+#else
+#define CLOCKS_PER_SEC 1000000 /* wild guess!! */
+#endif
+#endif
+
+#define N_USEC_PER_SEC 1000000L          /* not 1000! :-) */
+
+enum timer_state {
+  TIMER_STARTED,
+  TIMER_STOPPED
+};
+
+struct timer {
+  /* type: */
+  enum timer_timetype type;
+  enum timer_use use;
+  enum timer_state state;
+
+  /* this is accumulated time for previous timings: */
+  double sec;
+  long usec;           /* not always used, in which case zero,
+                          or if used may be negative, but >= -1000000 */
+
+  /* this is start of current timing, if state==TIMER_STARTED: */
+  union {
+    clock_t c;
+#ifdef HAVE_GETTIMEOFDAY
+    struct timeval tv;
+#else
+    time_t t;
+#endif
+  } start;
+};
+
+/********************************************************************** 
+  Report if clock() returns -1, but only the first time.
+  Ignore this timer from now on.
+***********************************************************************/
+static void report_clock_failed(struct timer *t)
+{
+  static int first = 1;
+
+  if (first) {
+    freelog(LOG_NORMAL, "clock() returned -1, ignoring timer");
+    first = 0;
+  }
+  t->use = TIMER_IGNORE;
+}
+
+#ifdef HAVE_GETTIMEOFDAY
+/********************************************************************** 
+  Report if gettimeofday() returns -1, but only the first time.
+  Ignore this timer from now on.
+***********************************************************************/
+static void report_gettimeofday_failed(struct timer *t)
+{
+  static int first = 1;
+
+  if (first) {
+    freelog(LOG_NORMAL, "gettimeofday() returned -1, ignoring timer");
+    first = 0;
+  }
+  t->use = TIMER_IGNORE;
+}
+#else
+/********************************************************************** 
+  Report if time() returns -1, but only the first time.
+  Ignore this timer from now on.
+***********************************************************************/
+static void report_time_failed(struct timer *t)
+{
+  static int first = 1;
+
+  if (first) {
+    freelog(LOG_NORMAL, "time() returned -1, ignoring timer");
+    first = 0;
+  }
+  t->use = TIMER_IGNORE;
+}
+#endif
+
+
+/********************************************************************** 
+  Allocate a new timer with specified "type" and "use".
+  The timer is created as cleared, and stopped.
+***********************************************************************/
+struct timer *new_timer(enum timer_timetype type, enum timer_use use)
+{
+  return renew_timer(NULL, type, use);
+}
+
+/********************************************************************** 
+  Allocate a new timer with specified "type" and "use".
+  The timer is created as cleared, and started.
+***********************************************************************/
+struct timer *new_timer_start(enum timer_timetype type, enum timer_use use)
+{
+  return renew_timer_start(NULL, type, use);
+}
+
+/********************************************************************** 
+  Allocate a new timer, or reuse t, with specified "type" and "use".
+  The timer is created as cleared, and stopped.
+  If t is NULL, allocate and return a new timer, else
+  just re-initialise t and return t.
+  This is intended to be useful to allocate a static t just once, eg:
+  {
+     static struct timer *t = NULL; 
+     t = renew_timer_start(t, TIMER_CPU, TIMER_USE);
+     ... stuff ...
+     freelog(LOG_VERBOSE, "That took %g seconds.", read_timer_seconds(t));
+     ... never free t ...
+  }
+***********************************************************************/
+struct timer *renew_timer(struct timer *t, enum timer_timetype type,
+                         enum timer_use use)
+{
+  if (t == NULL) {
+    t = fc_malloc(sizeof(struct timer));
+  }
+  t->type = type;
+  t->use = use;
+  clear_timer(t);
+  return t;
+}
+
+/********************************************************************** 
+  Allocate a new timer, or reuse t, with specified "type" and "use".
+  The timer is created as cleared, and started.
+  If t is NULL, allocate and return a new timer, else
+  just re-initialise t and return t; see above.
+***********************************************************************/
+struct timer *renew_timer_start(struct timer *t, enum timer_timetype type,
+                               enum timer_use use)
+{
+  struct timer *tt = renew_timer(t, type, use);
+  start_timer(tt);
+  return tt;
+}
+
+/********************************************************************** 
+  Free the memory associated with a timer.
+***********************************************************************/
+void free_timer(struct timer *t)
+{
+  free(t);
+}
+
+/********************************************************************** 
+  Return whether timer is in use.
+  t may be NULL, in which case returns 0
+***********************************************************************/
+int timer_in_use(struct timer *t)
+{
+  return (t && t->use != TIMER_IGNORE);
+}
+
+/********************************************************************** 
+  Reset accumulated time to zero, and stop timer if going.
+  That is, this may be called whether t is started or stopped;
+  in either case the timer is in the stopped state after this function.
+***********************************************************************/
+void clear_timer(struct timer *t)
+{
+  assert(t);
+  t->state = TIMER_STOPPED;
+  t->sec = 0.0;
+  t->usec = 0;
+}
+
+/********************************************************************** 
+  Start timing, adding to previous accumulated time if timer has not
+  been cleared.  A warning is printed if the timer is already started.
+***********************************************************************/
+void start_timer(struct timer *t)
+{
+  assert(t);
+
+  if (t->use == TIMER_IGNORE) {
+    return;
+  }
+  if (t->state == TIMER_STARTED) {
+    freelog(LOG_NORMAL, "tried to start already started timer");
+    return;
+  }
+  if (t->type == TIMER_CPU) {
+    t->start.c = clock();
+    if (t->start.c == -1) {
+      report_clock_failed(t);
+      return;
+    }
+  } else {
+#ifdef HAVE_GETTIMEOFDAY
+    int ret = gettimeofday(&t->start.tv, 0);
+    if (ret == -1) {
+      report_gettimeofday_failed(t);
+      return;
+    }
+#else
+    t->start.t = time(NULL);
+    if (t->start.t == -1) {
+      report_time_failed(t);
+      return;
+    }
+#endif
+  }
+  t->state = TIMER_STARTED;
+}
+
+/********************************************************************** 
+  Convenience function:
+***********************************************************************/
+void clear_timer_start(struct timer *t)
+{
+  clear_timer(t);
+  start_timer(t);
+}
+
+/********************************************************************** 
+  Stop timing, and accumulate time so far.
+  (The current time is stored in t->start, so that read_timer_seconds
+  can call this to take a point reading if the timer is active.)
+  A warning is printed if the timer is already stopped.
+***********************************************************************/
+void stop_timer(struct timer *t)
+{
+  assert(t);
+  
+  if (t->use == TIMER_IGNORE) {
+    return;
+  }
+  if (t->state == TIMER_STOPPED) {
+    freelog(LOG_NORMAL, "tried to stop already stopped timer");
+    return;
+  }
+  if (t->type == TIMER_CPU) {
+    clock_t now = clock();
+    if (now == -1) {
+      report_clock_failed(t);
+      return;
+    }
+    t->sec += (now - t->start.c) / (double)CLOCKS_PER_SEC;
+    t->start.c = now;
+  } else {
+#ifdef HAVE_GETTIMEOFDAY
+    struct timeval now;
+    int ret = gettimeofday(&now, 0);
+    if (ret == -1) {
+      report_gettimeofday_failed(t);
+      return;
+    }
+    t->usec += (now.tv_usec - t->start.tv.tv_usec);
+    t->sec += (now.tv_sec - t->start.tv.tv_sec);
+    if (t->usec < 0) {
+      t->usec += N_USEC_PER_SEC;
+      t->sec -= 1.0;
+    } else if (t->usec >= N_USEC_PER_SEC) {
+      long sec = t->usec / N_USEC_PER_SEC;
+      t->sec += sec;
+      t->usec -= sec * N_USEC_PER_SEC;
+    }
+    t->start.tv = now;
+#else
+    time_t now = time(NULL);
+    if (now == -1) {
+      report_time_failed(t);
+      return;
+    }
+    t->sec += difftime(now, t->start.t);
+    t->start.t = now;
+#endif
+  }
+  t->state = TIMER_STOPPED;
+}
+
+/********************************************************************** 
+  Read value from timer.  If the timer is not stopped, this stops the
+  timer, reads it (and accumulates), and then restarts it.
+  Returns 0.0 for unused timers.
+***********************************************************************/
+double read_timer_seconds(struct timer *t)
+{
+  assert(t);
+  
+  if (t->use == TIMER_IGNORE) {
+    return 0.0;
+  }
+  if (t->state == TIMER_STARTED) {
+    stop_timer(t);
+    t->state = TIMER_STARTED;
+  }
+  return t->sec + t->usec / (double)N_USEC_PER_SEC;
+}
+
+/********************************************************************** 
+  Read the timer, then free it.
+  This is intended to be useful for a simple one-off timing, eg:
+  {
+      struct timer *t = new_timer_start();
+      ...do stuff...
+      freelog(LOG_NORMAL, "That took %g seconds", read_timer_seconds_free(t));
+  }
+  (BUT: make sure the _free call really happens!
+  eg, freelog(LOG_DEBUG,...) might not actually evaluate its args.)
+***********************************************************************/
+double read_timer_seconds_free(struct timer *t)
+{
+  double val = read_timer_seconds(t);
+  free_timer(t);
+  return val;
+}
+
diff -N -u -r --exclude-from exclude freeciv-cvs/common/timing.h 
fc-adv/common/timing.h
--- freeciv-cvs/common/timing.h Thu Jan  1 10:00:00 1970
+++ fc-adv/common/timing.h      Mon Jun 28 11:54:43 1999
@@ -0,0 +1,63 @@
+/********************************************************************** 
+ Freeciv - Copyright (C) 1996 - A Kjeldberg, L Gregersen, P Unold
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+***********************************************************************/
+
+/* Measuring times; original author: David Pfitzner <dwp@xxxxxxxxxxxxxx> */
+
+#ifndef FC__TIMING_H
+#define FC__TIMING_H
+
+enum timer_timetype {
+  TIMER_CPU,                   /* time spent by the CPU */
+  TIMER_USER                   /* time as seen by the user ("wall clock") */
+};
+
+enum timer_use {
+  TIMER_ACTIVE,                        /* use this timer */
+  TIMER_IGNORE                 /* ignore this timer */
+};
+/*
+ * TIMER_IGNORE is to leave a timer in the code, but not actually
+ * use it, and not make any time-related system calls for it.
+ * It is also used internally to turn off timers if the system
+ * calls indicate that timing is not available.
+ * Also note TIMER_DEBUG below.
+ */
+
+#ifdef DEBUG
+#define TIMER_DEBUG TIMER_ACTIVE
+#else
+#define TIMER_DEBUG TIMER_IGNORE
+#endif
+
+struct timer;          /* opaque type; see comments in timing.c */
+
+struct timer *new_timer(enum timer_timetype type, enum timer_use use);
+struct timer *new_timer_start(enum timer_timetype type, enum timer_use use);
+
+struct timer *renew_timer(struct timer *t, enum timer_timetype type,
+                         enum timer_use use);
+struct timer *renew_timer_start(struct timer *t, enum timer_timetype type,
+                               enum timer_use use);
+
+void free_timer(struct timer *t);
+int timer_in_use(struct timer *t);
+
+void clear_timer(struct timer *t);
+void start_timer(struct timer *t);
+void stop_timer(struct timer *t);
+void clear_timer_start(struct timer *t);
+
+double read_timer_seconds(struct timer *t);
+double read_timer_seconds_free(struct timer *t);
+
+#endif  /* FC__TIMER_H */
diff -N -u -r --exclude-from exclude freeciv-cvs/config.h.in fc-adv/config.h.in
--- freeciv-cvs/config.h.in     Sat Jun 19 22:35:23 1999
+++ fc-adv/config.h.in  Mon Jun 28 11:54:43 1999
@@ -47,6 +47,9 @@
 /* Define if you have the gethostname function.  */
 #undef HAVE_GETHOSTNAME
 
+/* Define if you have the gettimeofday function.  */
+#undef HAVE_GETTIMEOFDAY
+
 /* Define if you have the select function.  */
 #undef HAVE_SELECT
 
diff -N -u -r --exclude-from exclude freeciv-cvs/configure fc-adv/configure
--- freeciv-cvs/configure       Fri Jun 25 22:30:31 1999
+++ fc-adv/configure    Mon Jun 28 11:55:13 1999
@@ -3955,7 +3955,7 @@
 
 fi
 
-for ac_func in gethostname select strerror strstr usleep
+for ac_func in gethostname select strerror strstr usleep gettimeofday
 do
 echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
 echo "configure:3962: checking for $ac_func" >&5
@@ -4009,7 +4009,6 @@
   echo "$ac_t""no" 1>&6
 fi
 done
-
 
 
 
diff -N -u -r --exclude-from exclude freeciv-cvs/configure.in 
fc-adv/configure.in
--- freeciv-cvs/configure.in    Fri Jun 25 22:30:31 1999
+++ fc-adv/configure.in Mon Jun 28 11:54:44 1999
@@ -242,11 +242,7 @@
 dnl Checks for library functions.
 AC_TYPE_SIGNAL
 AC_FUNC_VPRINTF
-AC_CHECK_FUNCS(gethostname select strerror strstr usleep)
-
-dnl autoscan also recommends gettimeofday in AC_CHECK_FUNCS, but in the code
-dnl that is already protected by ifdef CHRONO, and is for selective
-dnl developer use only -- dwp
+AC_CHECK_FUNCS(gethostname select strerror strstr usleep gettimeofday)
 
 dnl We would AC_CHECK_FUNCS for socket as well, except it is complicated
 dnl by the fact that the -lsocket is in X_EXTRA_LIBS and/or SERVER_LIBS,
diff -N -u -r --exclude-from exclude freeciv-cvs/server/autoattack.c 
fc-adv/server/autoattack.c
--- freeciv-cvs/server/autoattack.c     Tue Jun 22 21:05:08 1999
+++ fc-adv/server/autoattack.c  Mon Jun 28 11:54:44 1999
@@ -29,16 +29,12 @@
 #include <stdio.h>
 #include <stdlib.h>
 
-#ifdef CHRONO
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
 #include "events.h"
 #include "game.h"
 #include "log.h"
 #include "map.h"
 #include "player.h"
+#include "timing.h"
 #include "unit.h"
 
 #include "civserver.h"
@@ -239,13 +235,10 @@
 
 void auto_attack(void)
 {
+  static struct timer *t = NULL;      /* alloc once, never free */
   int i;
-#if CHRONO
-  int sec, usec;
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  sec = tv.tv_sec; usec = tv.tv_usec;
-#endif 
+
+  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
 
   /* re-use shuffle order from civserver.c */
   for (i = 0; i < game.nplayers; i++) {
@@ -253,10 +246,8 @@
       auto_attack_player(shuffled[i]);
     }
   }
-
-#if CHRONO
-  gettimeofday(&tv, 0);
-  freelog(LOG_VERBOSE, "autoattack consumed %ld microseconds.", 
-         (long)((tv.tv_sec - sec) * 1000000 + (tv.tv_usec - usec)));
-#endif
+  if (timer_in_use(t)) {
+    freelog(LOG_VERBOSE, "autoattack consumed %g milliseconds.",
+           1000.0*read_timer_seconds(t));
+  }
 }
diff -N -u -r --exclude-from exclude freeciv-cvs/server/civserver.c 
fc-adv/server/civserver.c
--- freeciv-cvs/server/civserver.c      Tue Jun 22 21:05:09 1999
+++ fc-adv/server/civserver.c   Mon Jun 28 11:54:45 1999
@@ -43,6 +43,7 @@
 #include "registry.h"
 #include "shared.h"
 #include "tech.h"
+#include "timing.h"
 #include "version.h"
 
 #include "autoattack.h"
@@ -70,14 +71,6 @@
 
 #include "civserver.h"
 
-#ifndef CLOCKS_PER_SEC
-#ifdef CLOCKS_PER_SECOND
-#define CLOCKS_PER_SEC CLOCKS_PER_SECOND
-#else
-#define CLOCKS_PER_SEC 1000000 /* wild guess!! */
-#endif
-#endif
-
 void end_game(void);
 void before_end_year(void); /* main() belongs at the bottom of files!! -- 
Syela */
 int end_turn(void);
@@ -294,10 +287,12 @@
   /* load a saved game */
   
   if(load_filename) {
-    clock_t loadtime;
+    struct timer *loadtimer, *uloadtimer;
     struct section_file file;
+    
     freelog(LOG_NORMAL,"Loading saved game: %s", load_filename);
-    loadtime = clock();
+    loadtimer = new_timer_start(TIMER_CPU, TIMER_ACTIVE);
+    uloadtimer = new_timer_start(TIMER_USER, TIMER_ACTIVE);
     if(!section_file_load(&file, load_filename)) { 
       freelog(LOG_FATAL, "Couldn't load savefile: %s", load_filename);
       exit(1);
@@ -318,9 +313,9 @@
       }
       while(is_id_allocated(global_id_counter++));
     }
-    loadtime = clock() - loadtime;
-    freelog(LOG_VERBOSE, "Load time: %g seconds",
-           (float)loadtime/CLOCKS_PER_SEC);
+    freelog(LOG_VERBOSE, "Load time: %g seconds (%g apparent)",
+           read_timer_seconds_free(loadtimer),
+           read_timer_seconds_free(uloadtimer));
   }
   
   /* init network */  
@@ -546,16 +541,18 @@
 
 int send_server_info_to_metaserver(int do_send)
 {
-  static int time_last_send;
-  int time_now;
+  static struct timer *time_since_last_send = NULL;
   char desc[4096], info[4096];
   int i;
-  
-  
-  time_now=time(NULL);
-  
-  if(!do_send && time_now-time_last_send<METASERVER_UPDATE_INTERVAL)
+
+  if(!do_send && (time_since_last_send!=NULL)
+     && (read_timer_seconds(time_since_last_send)
+        < METASERVER_UPDATE_INTERVAL)) {
     return 0;
+  }
+  if (time_since_last_send == NULL) {
+    time_since_last_send = new_timer(TIMER_USER, TIMER_ACTIVE);
+  }
 
   /* build description block */
   desc[0]='\0';
@@ -597,7 +594,7 @@
            i, game.players[i].name, game.players[i].addr);
   }
 
-  time_last_send=time_now;
+  clear_timer_start(time_since_last_send);
   return send_to_metaserver(desc, info);
 }
 
diff -N -u -r --exclude-from exclude freeciv-cvs/server/settlers.c 
fc-adv/server/settlers.c
--- freeciv-cvs/server/settlers.c       Tue Jun 22 21:05:09 1999
+++ fc-adv/server/settlers.c    Mon Jun 28 11:54:45 1999
@@ -14,15 +14,11 @@
 #include <string.h>
 #include <assert.h>
 
-#ifdef CHRONO
-#include <sys/time.h>
-#include <unistd.h>
-#endif
-
 #include "game.h"
 #include "log.h"
 #include "map.h"
 #include "packets.h"
+#include "timing.h"
 
 #include "cityhand.h"
 #include "citytools.h"
@@ -1175,12 +1171,10 @@
 **************************************************************************/
 void auto_settlers_player(struct player *pplayer) 
 {
-#ifdef CHRONO
-  int sec, usec;
-  struct timeval tv;
-  gettimeofday(&tv, 0);
-  sec = tv.tv_sec; usec = tv.tv_usec; 
-#endif
+  static struct timer *t = NULL;      /* alloc once, never free */
+
+  t = renew_timer_start(t, TIMER_CPU, TIMER_DEBUG);
+
   city_list_iterate(pplayer->cities, pcity)
     initialize_infrastructure_cache(pcity); /* saves oodles of time -- Syela */
   city_list_iterate_end;
@@ -1204,12 +1198,10 @@
     }
   }
   unit_list_iterate_end;
-#ifdef CHRONO
-  gettimeofday(&tv, 0);
-  freelog(LOG_VERBOSE, "%s's autosettlers consumed %ld microseconds.",
-         pplayer->name, (long)((tv.tv_sec - sec) * 1000000
-                               + (tv.tv_usec - usec)));
-#endif
+  if (timer_in_use(t)) {
+    freelog(LOG_VERBOSE, "%s's autosettlers consumed %g milliseconds.",
+           pplayer->name, 1000.0*read_timer_seconds(t));
+  }
 }
 
 void assign_settlers_player(struct player *pplayer)

[Prev in Thread] Current Thread [Next in Thread]