libc: dont cache /dev/bintime filedescriptor for nsec()
This commit is contained in:
parent
c7be3ba9e6
commit
7abf926bcf
3 changed files with 9 additions and 92 deletions
|
@ -28,8 +28,7 @@ is not zero then
|
|||
is also set to the answer.
|
||||
.PP
|
||||
These functions work by reading
|
||||
.BR /dev/bintime ,
|
||||
opening that file when they are first called.
|
||||
.BR /dev/bintime .
|
||||
.SH SOURCE
|
||||
.B /sys/src/libc/9sys/time.c
|
||||
.br
|
||||
|
@ -40,5 +39,3 @@ opening that file when they are first called.
|
|||
.SH DIAGNOSTICS
|
||||
Sets
|
||||
.IR errstr .
|
||||
.SH BUGS
|
||||
These routines maintain a static file descriptor.
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
#include <u.h>
|
||||
#include <libc.h>
|
||||
#include <tos.h>
|
||||
|
||||
static uvlong order = 0x0001020304050607ULL;
|
||||
|
||||
|
@ -16,60 +15,19 @@ be2vlong(vlong *to, uchar *f)
|
|||
t[o[i]] = f[i];
|
||||
}
|
||||
|
||||
static int fd = -1;
|
||||
static struct {
|
||||
int pid;
|
||||
int fd;
|
||||
} fds[64];
|
||||
|
||||
vlong
|
||||
nsec(void)
|
||||
{
|
||||
uchar b[8];
|
||||
vlong t;
|
||||
int pid, i, f, tries;
|
||||
int fd;
|
||||
|
||||
/*
|
||||
* Threaded programs may have multiple procs
|
||||
* with different fd tables, so we may need to open
|
||||
* /dev/bintime on a per-pid basis
|
||||
*/
|
||||
|
||||
/* 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(pread(f, b, sizeof b, 0) == sizeof b){
|
||||
t = 0;
|
||||
fd = open("/dev/bintime", OREAD);
|
||||
if(fd >= 0){
|
||||
if(pread(fd, b, sizeof b, 0) == sizeof b)
|
||||
be2vlong(&t, b);
|
||||
return t;
|
||||
}
|
||||
close(f);
|
||||
if(i < nelem(fds))
|
||||
fds[i].fd = -1;
|
||||
}while(tries++ == 0); /* retry once */
|
||||
USED(tries);
|
||||
return 0;
|
||||
close(fd);
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue