#include <u.h>
#include <libc.h>
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("");
}
|