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