From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Fri, 20 May 2011 23:27:05 -0400 To: 9fans@9fans.net Message-ID: In-Reply-To: References: <309c101f23bbb6ec6a92b2bf1c525fd7@brasstown.quanstro.net> <4be7f81375a5450a8b6536d66f756703@brasstown.quanstro.net> MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] a pair nec bugs Topicbox-Message-UUID: e7a15e8e-ead6-11e9-9d60-3106f5b1d025 here's an improved version. the previous version had a problem when shared memory but not shared fd in this situation p0: nsec() -> fd 3 ... p1: open() -> fd 3 nsec() -> fail one potential modification is to ditch the malloc and allocate two privalloc entries. one interesting bit that is not documented in the privalloc(2) man page is that privalloc() allocations are shared and inherited when a process forks, but the memory spaces are not. thus a privalloc for each new pid would be an error. it would require a modification to kexit() to change this. but it might make sense, because sharing privalloc entries seems exactly the opposite of what privalloc is supposed to be doing. - erik --- #include #include #include 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 = *nsecpriv; 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; }