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