rnd-19980918
[rocksndiamonds.git] / src / misc.c
index 14007b7e3d20868f510911e8a4150e93060c864f..944458f5669d0bd63d486123b3978d773c5aa8cc 100644 (file)
 #include <sys/param.h>
 #include <sys/types.h>
 
-void microsleep(unsigned long usec)
-{
-  struct timeval delay;
-
-  delay.tv_sec  = usec / 1000000;
-  delay.tv_usec = usec % 1000000;
-
-  if (select(0,NULL,NULL,NULL,&delay)!=0)
-    fprintf(stderr,"%s: in function microsleep: select failed!\n",
-           progname);
-}
-
-long mainCounter(int mode)
+static unsigned long mainCounter(int mode)
 {
   static struct timeval base_time = { 0, 0 };
   struct timeval current_time;
-  long counter_ms;
+  unsigned long counter_ms;
+
+  gettimeofday(&current_time, NULL);
 
-  gettimeofday(&current_time,NULL);
   if (mode == INIT_COUNTER || current_time.tv_sec < base_time.tv_sec)
     base_time = current_time;
 
-  counter_ms = (current_time.tv_sec - base_time.tv_sec)*1000
-             + (current_time.tv_usec - base_time.tv_usec)/1000;
+  counter_ms = (current_time.tv_sec  - base_time.tv_sec)  * 1000
+             + (current_time.tv_usec - base_time.tv_usec) / 1000;
 
-  if (mode == READ_COUNTER_100)
-    return(counter_ms/10);     /* return 1/100 secs since last init */
-  else /*    READ_COUNTER_1000 */
-    return(counter_ms);                /* return 1/1000 secs since last init */
+  return counter_ms;           /* return milliseconds since last init */
 }
 
-void InitCounter() /* set counter back to zero */
+void InitCounter()             /* set counter back to zero */
 {
   mainCounter(INIT_COUNTER);
 }
 
-long Counter() /* returns 1/100 secs since last call of InitCounter() */
+unsigned long Counter()        /* get milliseconds since last call of InitCounter() */
 {
-  return(mainCounter(READ_COUNTER_100));
+  return(mainCounter(READ_COUNTER));
 }
 
-long Counter2()        /* returns 1/1000 secs since last call of InitCounter() */
+static void sleep_milliseconds(unsigned long milliseconds_delay)
 {
-  return(mainCounter(READ_COUNTER_1000));
-}
+  if (milliseconds_delay < 5 || !cpu_friendly)
+  {
+    /* we want to wait less than 5 ms -- if we assume that we have a
+       kernel timer resolution of 10 ms, we would wait far to long;
+       therefore it's better to do a short interval of busy waiting
+       to get our sleeping time more accurate */
 
-void WaitCounter(long value)   /* wait for counter to reach value */
-{
-  long wait;
+    unsigned long base_counter = Counter(), actual_counter = Counter();
 
-  while((wait=value-Counter())>0)
-    microsleep(wait*10000);
-}
+    while (actual_counter < base_counter + milliseconds_delay &&
+          actual_counter >= base_counter)
+      actual_counter = Counter();
+  }
+  else
+  {
+    struct timeval delay;
 
-void WaitCounter2(long value)  /* wait for counter to reach value */
-{
-  long wait;
+    delay.tv_sec  = milliseconds_delay / 1000;
+    delay.tv_usec = 1000 * (milliseconds_delay % 1000);
 
-  while((wait=value-Counter2())>0)
-    microsleep(wait*1000);
+    if (select(0, NULL, NULL, NULL, &delay) != 0)
+      fprintf(stderr,"%s: in function sleep_milliseconds: select() failed!\n",
+             progname);
+  }
 }
 
-void Delay(long value)
+void Delay(unsigned long delay)        /* Sleep specified number of milliseconds */
 {
-  microsleep(value);
+  sleep_milliseconds(delay);
 }
 
-BOOL DelayReached(long *counter_var, int delay)
+BOOL FrameReached(unsigned long *frame_counter_var, unsigned long frame_delay)
 {
-  long actual_counter = Counter();
+  unsigned long actual_frame_counter = FrameCounter;
 
-  if (actual_counter >= *counter_var+delay || actual_counter < *counter_var)
-  {
-    *counter_var = actual_counter;
-    return(TRUE);
-  }
-  else
+  if (actual_frame_counter < *frame_counter_var+frame_delay &&
+      actual_frame_counter >= *frame_counter_var)
     return(FALSE);
+
+  *frame_counter_var = actual_frame_counter;
+  return(TRUE);
 }
 
-BOOL FrameReached(long *frame_counter_var, int frame_delay)
+BOOL DelayReached(unsigned long *counter_var, unsigned long delay)
 {
-  long actual_frame_counter = FrameCounter;
+  unsigned long actual_counter = Counter();
 
-  if (actual_frame_counter >= *frame_counter_var+frame_delay
-      || actual_frame_counter < *frame_counter_var)
-  {
-    *frame_counter_var = actual_frame_counter;
-    return(TRUE);
-  }
-  else
+  if (actual_counter < *counter_var + delay &&
+      actual_counter >= *counter_var)
     return(FALSE);
+
+  *counter_var = actual_counter;
+  return(TRUE);
+}
+
+void WaitUntilDelayReached(unsigned long *counter_var, unsigned long delay)
+{
+  unsigned long actual_counter = Counter();
+
+  if (actual_counter < *counter_var + delay && actual_counter >= *counter_var)
+    sleep_milliseconds(*counter_var + delay - actual_counter);
+
+  *counter_var = actual_counter;
 }
 
 char *int2str(int ct, int nr)