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