diff options
| -rw-r--r-- | sys/src/libc/9sys/nsec.c | 80 | ||||
| -rw-r--r-- | sys/src/libc/9sys/time.c | 38 |
2 files changed, 34 insertions, 84 deletions
diff --git a/sys/src/libc/9sys/nsec.c b/sys/src/libc/9sys/nsec.c index f0e981d04..3519fae33 100644 --- a/sys/src/libc/9sys/nsec.c +++ b/sys/src/libc/9sys/nsec.c @@ -16,60 +16,48 @@ be2vlong(vlong *to, uchar *f) t[o[i]] = f[i]; } -static int fd = -1; -static struct { - int pid; - int fd; -} fds[64]; +static int +stillopen(int fd, char *name) +{ + char buf[64]; + + return fd >= 0 && fd2path(fd, buf, sizeof(buf)) == 0 && strcmp(buf, name) == 0; +} vlong nsec(void) { + static char name[] = "/dev/bintime"; + static int *pidp = nil, *fdp = nil, fd = -1; uchar b[8]; vlong t; - int pid, i, f, tries; - - /* - * Threaded programs may have multiple procs - * with different fd tables, so we may need to open - * /dev/bintime on a per-pid basis - */ + int f; - /* First, look if we've opened it for this particular pid */ - pid = _tos->pid; - do{ - f = -1; - for(i = 0; i < nelem(fds); i++) - if(fds[i].pid == pid){ - f = fds[i].fd; - break; - } - tries = 0; - if(f < 0){ - /* If it's not open for this pid, try the global pid */ - if(fd >= 0) - f = fd; - else{ - /* must open */ - if((f = open("/dev/bintime", OREAD|OCEXEC)) < 0) - return 0; - fd = f; - for(i = 0; i < nelem(fds); i++) - if(fds[i].pid == pid || fds[i].pid == 0){ - fds[i].pid = pid; - fds[i].fd = f; - break; - } - } + if(pidp != nil && *pidp == _tos->pid) + f = *fdp; + else{ +Reopen: + f = fd; + if(fdp != nil && *fdp != f && stillopen(*fdp, name)) + f = *fdp; + else if(!stillopen(f, name)){ + if((f = open(name, OREAD|OCEXEC)) < 0) + return 0; } - if(pread(f, b, sizeof b, 0) == sizeof b){ - be2vlong(&t, b); - return t; + fd = f; + if(fdp == nil){ + fdp = (int*)privalloc(); + pidp = (int*)privalloc(); } + *fdp = f; + *pidp = _tos->pid; + } + if(pread(f, b, sizeof b, 0) != sizeof b){ + if(!stillopen(f, name)) + goto Reopen; close(f); - if(i < nelem(fds)) - fds[i].fd = -1; - }while(tries++ == 0); /* retry once */ - USED(tries); - return 0; + return 0; + } + be2vlong(&t, b); + return t; } diff --git a/sys/src/libc/9sys/time.c b/sys/src/libc/9sys/time.c index 3e5f83b04..23ef3d1ba 100644 --- a/sys/src/libc/9sys/time.c +++ b/sys/src/libc/9sys/time.c @@ -1,50 +1,12 @@ #include <u.h> #include <libc.h> - -/* - * 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 unusual loop - * in the middle of this routine. - */ -static long -oldtime(long *tp) -{ - char b[20]; - static int f = -1; - int i, retries; - long t; - - memset(b, 0, sizeof(b)); - for(retries = 0; retries < 100; retries++){ - if(f < 0) - f = open("/dev/time", OREAD|OCEXEC); - if(f < 0) - break; - if(seek(f, 0, 0) < 0 || (i = read(f, b, sizeof(b))) < 0){ - close(f); - f = -1; - } else { - if(i != 0) - break; - } - } - t = atol(b); - if(tp) - *tp = t; - return t; -} - long time(long *tp) { vlong t; t = nsec()/1000000000LL; - if(t == 0) - t = oldtime(0); if(tp != nil) *tp = t; return t; |
