2005-08-08 16:50:13 +04:00
|
|
|
#include <u.h>
|
|
|
|
#include <libc.h>
|
|
|
|
|
2005-10-31 18:30:23 +03:00
|
|
|
static uvlong order = (uvlong) 0x0001020304050607ULL;
|
2005-08-08 16:50:13 +04:00
|
|
|
|
|
|
|
static void
|
|
|
|
be2vlong(vlong *to, uchar *f)
|
|
|
|
{
|
|
|
|
uchar *t, *o;
|
|
|
|
int i;
|
|
|
|
|
|
|
|
t = (uchar*)to;
|
|
|
|
o = (uchar*)ℴ
|
|
|
|
for(i = 0; i < 8; i++)
|
|
|
|
t[o[i]] = f[i];
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* After a fork with fd's copied, both fd's are pointing to
|
|
|
|
* the same Chan structure. Since the offset is kept in the Chan
|
|
|
|
* structure, the seek's and read's in the two processes can
|
|
|
|
* compete at moving the offset around. Hence the retry loop.
|
|
|
|
*
|
|
|
|
* Since the bintime version doesn't need a seek, it doesn't
|
|
|
|
* have the loop.
|
|
|
|
*/
|
|
|
|
vlong
|
|
|
|
nsec(void)
|
|
|
|
{
|
|
|
|
char b[12+1];
|
|
|
|
static int f = -1;
|
|
|
|
static int usebintime;
|
|
|
|
int retries;
|
|
|
|
vlong t;
|
|
|
|
|
|
|
|
if(f < 0){
|
|
|
|
usebintime = 1;
|
|
|
|
f = open("/dev/bintime", OREAD|OCEXEC);
|
|
|
|
if(f < 0){
|
|
|
|
usebintime = 0;
|
|
|
|
f = open("/dev/nsec", OREAD|OCEXEC);
|
|
|
|
if(f < 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if(usebintime){
|
|
|
|
if(read(f, b, sizeof(uvlong)) < 0)
|
|
|
|
goto error;
|
|
|
|
be2vlong(&t, (uchar*)b);
|
|
|
|
return t;
|
|
|
|
} else {
|
|
|
|
for(retries = 0; retries < 100; retries++){
|
|
|
|
if(seek(f, 0, 0) >= 0 && read(f, b, sizeof(b)-1) >= 0){
|
|
|
|
b[sizeof(b)-1] = 0;
|
|
|
|
return strtoll(b, 0, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
error:
|
|
|
|
close(f);
|
|
|
|
f = -1;
|
|
|
|
return 0;
|
|
|
|
}
|