#include #include enum { M = 1000000, }; extern void _cycles(vlong*); static uvlong order = 0x0001020304050607ULL; static void be2vlong(vlong *to, uchar *f) { uchar *t, *o; int i; t = (uchar*)to; o = (uchar*)ℴ for(i = 0; i < sizeof order; i++) t[o[i]] = f[i]; } vlong mynsec(void) { uchar b[8]; vlong t; int fd; t = 0; if((fd = open("/dev/bintime", OREAD)) >= 0) if(pread(fd, b, sizeof b, 0) == sizeof b) be2vlong(&t, b); close(fd); return t; } void checkwired(int mach) { char buf[128]; int fd; for(;;){ sleep(1); fd = open("/dev/mach", OREAD); if(fd == -1) /* old kernel; just hope */ return; buf[0] = ' '; buf[read(fd, buf, sizeof buf)] = 0; close(fd); if(atoi(buf) == mach) return; sysfatal("wire fails"); } } void procwired(int mach) { char buf[128]; int fd; snprint(buf, sizeof buf, "/proc/%d/ctl", getpid()); fd = open(buf, OWRITE); if(fprint(fd, "wired %d", mach) < 0) sysfatal("procwired: %r"); close(fd); checkwired(mach); /* don't trust kernel yet */ } uvlong cyclehz(void) { char buf[128], *f[30]; int fd, n; uvlong u; fd = open("/dev/cputype", OREAD); if(fd == -1) return 1; n = read(fd, buf, sizeof buf-1); if(n == -1) return 1; buf[n] = 0; n = tokenize(buf, f, nelem(f)); if(n == 0) return 1; u = strtoull(f[n-1], 0, 0); if(u == 0) return 1; return M*u; } void main(void) { vlong t, v, hz; procwired(0); /* don't mix rdtsc between maches */ t = -mynsec(); t += mynsec(); print("nsec latency %lldns\n", t); t = -mynsec(); t += mynsec(); print("nsec latency %lldns\n", t); hz = cyclehz(); print("cycle hz = %lld\n", hz); _cycles(&t); _cycles(&v); print("cycles latency %lld cycles; %lld ns\n", v - t, ((v-t)*M*1000)/hz); _cycles(&t); _cycles(&v); print("cycles latency %lld cycles; %lld ns\n", v - t, ((v-t)*M*1000)/hz); exits(""); }