1 #include <u.h>
2 #include <libc.h>
3 #include <tos.h>
4
5 static uvlong order = 0x0001020304050607ULL;
6
7 static void
be2vlong(vlong * to,uchar * f)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 < sizeof order; i++)
16 t[o[i]] = f[i];
17 }
18
19 static int fd = -1;
20 static struct {
21 int pid;
22 int fd;
23 } fds[64];
24
25 vlong
nsec(void)26 nsec(void)
27 {
28 uchar b[8];
29 vlong t;
30 int pid, i, f, tries;
31
32 /*
33 * Threaded programs may have multiple procs
34 * with different fd tables, so we may need to open
35 * /dev/bintime on a per-pid basis
36 */
37
38 /* First, look if we've opened it for this particular pid */
39 if((pid = _tos->pid) == 0) /* 9vx bug, perhaps? */
40 _tos->pid = pid = getpid();
41 do{
42 f = -1;
43 for(i = 0; i < nelem(fds); i++)
44 if(fds[i].pid == pid){
45 f = fds[i].fd;
46 break;
47 }
48 tries = 0;
49 if(f < 0){
50 /* If it's not open for this pid, try the global pid */
51 if(fd >= 0)
52 f = fd;
53 else{
54 /* must open */
55 if((f = open("/dev/bintime", OREAD|OCEXEC)) < 0)
56 return 0;
57 fd = f;
58 for(i = 0; i < nelem(fds); i++)
59 if(fds[i].pid == pid || fds[i].pid == 0){
60 fds[i].pid = pid;
61 fds[i].fd = f;
62 break;
63 }
64 }
65 }
66 if(pread(f, b, sizeof b, 0) == sizeof b){
67 be2vlong(&t, b);
68 return t;
69 }
70 close(f);
71 if(i < nelem(fds))
72 fds[i].fd = -1;
73 }while(tries++ == 0); /* retry once */
74 USED(tries);
75 return 0;
76 }
77