/* Compare elapsed wall time and process CPU ticks on AIX. */ #include #include #include #include #include #include #include #include #include #define REPEATS 8 #define TARGET_USEC 250000L #define CHECK_MASK 16383UL struct sample { struct timeval wall; struct tms cpu; }; static int take_sample(s) struct sample *s; { if (gettimeofday(&s->wall, (struct timezone *)0) < 0) return -1; if (times(&s->cpu) == (clock_t)-1) return -1; return 0; } static long elapsed_usec(a, b) struct timeval *a; struct timeval *b; { return (long)(b->tv_sec - a->tv_sec) * 1000000L + (long)(b->tv_usec - a->tv_usec); } static long cpu_ticks(a, b) struct tms *a; struct tms *b; { return (long)((b->tms_utime + b->tms_stime) - (a->tms_utime + a->tms_stime)); } static int wait_quarter_second() { struct timeval delay; int rc; delay.tv_sec = 0; delay.tv_usec = TARGET_USEC; do { rc = select(0, (fd_set *)0, (fd_set *)0, (fd_set *)0, &delay); } while (rc < 0 && errno == EINTR); return rc; } static unsigned long burn_until(start) struct timeval *start; { struct timeval now; unsigned long i, sum; sum = 0UL; now = *start; i = 0UL; do { sum += (i ^ (sum << 1)) + 1UL; i++; if ((i & CHECK_MASK) == 0UL) { if (gettimeofday(&now, (struct timezone *)0) < 0) return sum; } } while (elapsed_usec(start, &now) < TARGET_USEC); return sum; } int main() { long tickrate; int n; unsigned long checksum; struct sample a, b; struct timeval wait_start; tickrate = sysconf(_SC_CLK_TCK); if (tickrate <= 0) { fprintf(stderr, "sysconf(_SC_CLK_TCK) failed\n"); return 1; } printf("# timeprobe 1; target_usec=%ld; repeats=%d; hz=%ld\n", TARGET_USEC, REPEATS, tickrate); printf("kind,trial,wall_usec,cpu_ticks,user_ticks\n"); checksum = 0UL; for (n = 1; n <= REPEATS; n++) { if (take_sample(&a) < 0 || wait_quarter_second() < 0 || take_sample(&b) < 0) { perror("wait sample"); return 1; } printf("wait,%d,%ld,%ld,%ld\n", n, elapsed_usec(&a.wall, &b.wall), cpu_ticks(&a.cpu, &b.cpu), (long)(b.cpu.tms_utime - a.cpu.tms_utime)); if (take_sample(&a) < 0 || gettimeofday(&wait_start, (struct timezone *)0) < 0) { perror("busy sample"); return 1; } checksum += burn_until(&wait_start); if (take_sample(&b) < 0) { perror("busy end sample"); return 1; } printf("busy,%d,%ld,%ld,%ld\n", n, elapsed_usec(&a.wall, &b.wall), cpu_ticks(&a.cpu, &b.cpu), (long)(b.cpu.tms_utime - a.cpu.tms_utime)); fflush(stdout); } fprintf(stderr, "checksum=%lu\n", checksum); return 0; }