1*8ccd4a63SDavid du Colombier #include <u.h>
2*8ccd4a63SDavid du Colombier #include <libc.h>
3*8ccd4a63SDavid du Colombier
4*8ccd4a63SDavid du Colombier static uvlong order = (uvlong) 0x0001020304050607ULL;
5*8ccd4a63SDavid du Colombier
6*8ccd4a63SDavid du Colombier static void
be2vlong(vlong * to,uchar * f)7*8ccd4a63SDavid du Colombier be2vlong(vlong *to, uchar *f)
8*8ccd4a63SDavid du Colombier {
9*8ccd4a63SDavid du Colombier uchar *t, *o;
10*8ccd4a63SDavid du Colombier int i;
11*8ccd4a63SDavid du Colombier
12*8ccd4a63SDavid du Colombier t = (uchar*)to;
13*8ccd4a63SDavid du Colombier o = (uchar*)ℴ
14*8ccd4a63SDavid du Colombier for(i = 0; i < 8; i++)
15*8ccd4a63SDavid du Colombier t[o[i]] = f[i];
16*8ccd4a63SDavid du Colombier }
17*8ccd4a63SDavid du Colombier
18*8ccd4a63SDavid du Colombier /*
19*8ccd4a63SDavid du Colombier * After a fork with fd's copied, both fd's are pointing to
20*8ccd4a63SDavid du Colombier * the same Chan structure. Since the offset is kept in the Chan
21*8ccd4a63SDavid du Colombier * structure, the seek's and read's in the two processes can
22*8ccd4a63SDavid du Colombier * compete at moving the offset around. Hence the retry loop.
23*8ccd4a63SDavid du Colombier *
24*8ccd4a63SDavid du Colombier * Since the bintime version doesn't need a seek, it doesn't
25*8ccd4a63SDavid du Colombier * have the loop.
26*8ccd4a63SDavid du Colombier */
27*8ccd4a63SDavid du Colombier vlong
nsec(void)28*8ccd4a63SDavid du Colombier nsec(void)
29*8ccd4a63SDavid du Colombier {
30*8ccd4a63SDavid du Colombier char b[12+1];
31*8ccd4a63SDavid du Colombier static int f = -1;
32*8ccd4a63SDavid du Colombier static int usebintime;
33*8ccd4a63SDavid du Colombier int retries;
34*8ccd4a63SDavid du Colombier vlong t;
35*8ccd4a63SDavid du Colombier
36*8ccd4a63SDavid du Colombier if(f < 0){
37*8ccd4a63SDavid du Colombier usebintime = 1;
38*8ccd4a63SDavid du Colombier f = open("/dev/bintime", OREAD|OCEXEC);
39*8ccd4a63SDavid du Colombier if(f < 0){
40*8ccd4a63SDavid du Colombier usebintime = 0;
41*8ccd4a63SDavid du Colombier f = open("/dev/nsec", OREAD|OCEXEC);
42*8ccd4a63SDavid du Colombier if(f < 0)
43*8ccd4a63SDavid du Colombier return 0;
44*8ccd4a63SDavid du Colombier }
45*8ccd4a63SDavid du Colombier }
46*8ccd4a63SDavid du Colombier
47*8ccd4a63SDavid du Colombier if(usebintime){
48*8ccd4a63SDavid du Colombier if(read(f, b, sizeof(uvlong)) < 0)
49*8ccd4a63SDavid du Colombier goto error;
50*8ccd4a63SDavid du Colombier be2vlong(&t, (uchar*)b);
51*8ccd4a63SDavid du Colombier return t;
52*8ccd4a63SDavid du Colombier } else {
53*8ccd4a63SDavid du Colombier for(retries = 0; retries < 100; retries++){
54*8ccd4a63SDavid du Colombier if(seek(f, 0, 0) >= 0 && read(f, b, sizeof(b)-1) >= 0){
55*8ccd4a63SDavid du Colombier b[sizeof(b)-1] = 0;
56*8ccd4a63SDavid du Colombier return strtoll(b, 0, 0);
57*8ccd4a63SDavid du Colombier }
58*8ccd4a63SDavid du Colombier }
59*8ccd4a63SDavid du Colombier }
60*8ccd4a63SDavid du Colombier
61*8ccd4a63SDavid du Colombier error:
62*8ccd4a63SDavid du Colombier close(f);
63*8ccd4a63SDavid du Colombier f = -1;
64*8ccd4a63SDavid du Colombier return 0;
65*8ccd4a63SDavid du Colombier }
66