here's what i settled on for now. i believe it to be correct in all cases, but if you are sharing file descriptors among many processes, you may have /dev/bintime open many more times that necessary.
i put off solving other instances of fd-group private until later, since the solution in hand is not very satisfying. in the future, i believe it might make sense to make file descriptor groups, environment groups, etc. available via /dev/fdid to allow for sharing without false sharing. - erik ---- #include <u.h> #include <libc.h> #include <tos.h> typedef struct Nfd Nfd; struct Nfd { int pid; int fd; }; static void **nsecpriv; #define Fd ((Nfd*)nsecpriv[0]) static uvlong order = 0x0001020304050607ULL; static void be2vlong(vlong *to, uchar *f) { uchar *t, *o; int i; t = (uchar*)to; o = (uchar*)ℴ for(i = 0; i < sizeof order; i++) t[o[i]] = f[i]; } static Nfd* getfd(void) { Nfd *p; if(nsecpriv != nil && Fd->pid == _tos->pid) return Fd; if(nsecpriv == nil){ /* * privalloc's allocates slots on a shared * basis, even though the memory slots * themselves are proc-private. */ nsecpriv = privalloc(); if(nsecpriv == nil) return nil; *nsecpriv = p = malloc(sizeof *p); if(p == nil) return nil; }else p = Fd; p->fd = -1; return p; } vlong nsec(void) { uchar b[8]; vlong t; Nfd *p; if((p = getfd()) == nil) return 0; if(p->fd == -1){ p->fd = open("/dev/bintime", OREAD|OCEXEC); p->pid = _tos->pid; } if(pread(p->fd, b, sizeof b, 0) == sizeof b){ be2vlong(&t, b); return t; } return 0; }