📄 get_tv.c
字号:
static char *RCSID = "$Header: /host/kaukau/disk2/X11R5/R5-hp300/mit/server/ddx/hpbsd/input/RCS/get_tv.c,v 1.1 1992/09/30 03:14:10 root Exp $";/* * An alternative to gettimeofday(2) that is about 50 times faster * if used frequently. HP-PA specific. * Dave Holt, GSY Performance, dah@cup.hp.com */#include <time.h>#include <assert.h>#ifdef NOTDEFINED /* The following is not currently used. But * I will leave it for possible future use. * --kam 4/22/92 */#ifdef DEBUG#include <stdio.h>#else /* Not DEBUG. Don't bother with printf's. */#define printf(s, a)#endif /* DEBUG */#define MILLION 1000000#define BUNCH 8192 /* must be < 32767 */unsigned int cr16(); /* in cr16.s (assembly code) */static struct timeval slow_get_tv();void *malloc();static set_tix2usec();/* This initial value for last_tv forces initialization of tix2usec[]. */static struct timeval last_tv = {0, 2000000};static unsigned int last_tix;/* * tix2usec[BUNCH] is a table built by set_tix2usec() which converts * from CR16 ticks to microseconds: * microseconds = tix2usec[ticks >> shift] */static unsigned short *tix2usec;static int shift;struct timeval get_tv() /* the fast path */{ unsigned int tix, delta_tix; long delta_usec; tix = cr16(); delta_tix = tix - last_tix; last_tix = tix; if (delta_tix < BUNCH) { /* we can use the array */ delta_usec = tix2usec[delta_tix >> shift]; last_tv.tv_usec += delta_usec; if (last_tv.tv_usec < MILLION) { return(last_tv); } } return(slow_get_tv());}static struct timeval slow_get_tv() /* the slow path */{ struct timezone tz; static int first_time = 1; if (first_time) { set_tix2usec(); first_time = 0; } last_tix = cr16(); gettimeofday(&last_tv, &tz); return(last_tv);}/* * set_tix2usec() builds it by observing gettimeofday and CR16 over a * reasonable period (~50ms). */static set_tix2usec(){ struct timeval tv1, tv2; struct timezone tz; int i, tix_per_entry, delta_us; unsigned int tix1, tix2, cr16(), delta_tix; double tix_per_usec, usec_per_tix; /* make sure the code is in memory before we time it */ tix1 = cr16(); gettimeofday(&tv1, &tz); do { tix1 = cr16(); gettimeofday(&tv1, &tz); do { tix2 = cr16(); gettimeofday(&tv2, &tz); delta_us = (tv2.tv_sec - tv1.tv_sec) * MILLION + (tv2.tv_usec - tv1.tv_usec); delta_tix = tix2 - tix1; } while (delta_us < 50000); /* loop for at least 50ms */ } while (tv2.tv_sec - tv1.tv_sec > 2); /* retry if delta is too big */ tix_per_usec = 1.0 * delta_tix / delta_us; usec_per_tix = 1 / tix_per_usec; /* Table should convert at least 10ms deltas. */ tix_per_entry = tix_per_usec * 10000 / BUNCH; for (shift = 0; (1 << shift) < tix_per_entry; shift++) { } tix2usec = (unsigned short *) malloc(BUNCH * sizeof(unsigned short)); assert(tix2usec != NULL); for (i = 0; i < BUNCH; i++) { tix2usec[i] = i * (1 << shift) * usec_per_tix; } printf("tix_per_usec = %lf\n", tix_per_usec); printf("shift = %d\n", shift);}#endif /* NOTDEFINED */voidcalibrate_cr16(TicksPerMilli)unsigned long *TicksPerMilli;{ struct timeval start, end; register unsigned long cr_start, cr_end; unsigned long total_ticks = 0, total_millis = 0; int i, j; for(i = 0; i < 6; i++) { cr_start = cr16(); gettimeofday(&start, NULL); /* waste some time */ for(j=0; j< 200000; j++) ; cr_end = cr16(); gettimeofday(&end, NULL); if(start.tv_usec > end.tv_usec) { end.tv_usec += 1000000; end.tv_sec--; } /* if we have a rollover during all of this, toss this one. */ if(cr_end < cr_start) { i--; } else { total_millis += (end.tv_sec - start.tv_sec) * 1000 + (end.tv_usec - start.tv_usec) / 1000; total_ticks += cr_end - cr_start; } } *TicksPerMilli = total_ticks/total_millis;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -