ftp.nice.ch/pub/next/tools/screen/backspace/Roaches.1.1.s.tar.gz#/Roaches/Pacemaker.m

This is Pacemaker.m in view mode; [Download] [Up]

/* RoachesView is Copyright 1994 by Brian Hill <bhill@physics.ucla.edu>. */

#ifdef DEBUG
#define INTERVAL_RECORD
#endif

#ifdef INTERVAL_RECORD
/* Watching the interval in the debugger is pointless, since that greatly
   affects the timing.  Instead, record the intervals, then break the debugger
   and examine them.  If more than one Pacemaker is instantiated, the 
   interval records will be interleaved. */
typedef struct {
  long dozeAmount; /* If negative, usleep. */
  long difference; /* Actual difference after sleeping */
} intervalRecord;
#define LOTS 1000
intervalRecord intervalRecords[LOTS];
#endif

#import "Pacemaker.h"

static void tv_difference(const struct timeval *tvNow, 
				 const struct timeval *tvThen, 
				 struct timeval *difference);

static inline void tv_add(struct timeval *tv, long timeToAdd);

static void tv_rationalize(struct timeval *tv);

static long tv2usec(const struct timeval *tv);

@implementation Pacemaker

- initInterval:(long)newInterval
{
  interval = newInterval;
  return [self reset];
}

- setInterval:(long)newInterval
{
  interval = newInterval;
  return self;
}

- reset
{
  gettimeofday(&then, NULL);
  return self;
}

- (long)doze
{
  struct timeval now, difference;
  long dozeAmount, differenceInMicroseconds;
  
  gettimeofday(&now, NULL);
  tv_difference(&now, &then, &difference);
  differenceInMicroseconds = tv2usec(&difference);
  dozeAmount = interval - differenceInMicroseconds;
  if (dozeAmount > 7500 /* Seems you can't doze less than about 15000us */) {
  /* Hack follows. */
  usleep((long)15000 /* dozeAmount replaced by a hard-coded value */);
    gettimeofday(&now, NULL);
    tv_difference(&now, &then, &difference);
    differenceInMicroseconds = tv2usec(&difference);
  }
#ifdef INTERVAL_RECORD
  {
    static unsigned i = 0;
    if (i >= 300 && i < LOTS + 300) {
      intervalRecords[i - 300].dozeAmount = dozeAmount;
      intervalRecords[i - 300].difference = differenceInMicroseconds;
    }
    ++i;
  }
#endif
  then = now;
  return differenceInMicroseconds;
}

@end

static void tv_difference(const struct timeval *tvNow, 
		   const struct timeval *tvThen, 
		   struct timeval *difference)
{
  difference->tv_sec = tvNow->tv_sec - tvThen->tv_sec;
  difference->tv_usec = tvNow->tv_usec - tvThen->tv_usec;
  tv_rationalize(difference);
  return;
}

static inline void tv_add(struct timeval *tv, long timeToAdd) 
{
  tv->tv_usec += timeToAdd;
  tv_rationalize(tv);
  return;
}

static void tv_rationalize(struct timeval *tv) 
{
  while (tv->tv_usec > 1000000) {
    tv->tv_usec -= 1000000;
    tv->tv_sec += 1;
  }
  while (tv->tv_usec < 0) {
    tv->tv_usec += 1000000;
    tv->tv_sec -= 1;
  }
  return;
}
    
static long tv2usec(const struct timeval *tv)
{
  return (tv->tv_sec * 1000000 + tv->tv_usec);
}

These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.