From mboxrd@z Thu Jan 1 00:00:00 1970 From: erik quanstrom Date: Sat, 5 Sep 2015 08:27:30 -0700 To: 9fans@9fans.net Message-ID: In-Reply-To: References: MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Subject: Re: [9fans] Privalloc(2) and rfork(RFPROC|RFMEM) (was: a pair nec bugs) Topicbox-Message-UUID: 68c98336-ead9-11e9-9d60-3106f5b1d025 On Sat Sep 5 07:06:44 PDT 2015, giacomo@tesio.it wrote: > 2011-05-20 3:30 GMT+02:00 erik quanstrom : uh, wow. i hope this wasn't my mailer dragging the past up. > > one note is that while i'm aware of privalloc(2), i didn't use it. the > > implementation doesn't appear correct for shared-memory procs. > > i think there are two issues > > - locking is unnecessary. the only preemptable unit of execution is > > a process and each process is guarenteed to have its own instance > > of _privates and _nprivates. > > - for shared-memory procs, we will run out of privates because > > the static privinit will be falsely shared. privinit should be replaced > > by using a private entry. > > > > In a set of processes that share memory, I need a single per-process > location to store the address of structure (which is in turn allocated in > the global memory space). > > Privalloc(2) seemed what I need, but seem that I can't use it properly. > > In the parent process I do: > > 1) initialialize a global variable p = (MyStruct **)privalloc(); > 2) allocate a MyStruct for every process I'm going to spawn > 3) spawn processes with rfork(RFMEM|RFPROC) > > The spawn() function that call rfork takes a MyStruct* as argument and > assign it to *p in the new process. > For extra safety I added an assert(*p == nil) just after rfork, and after a > few (apparently?) successful spawns, the assert fails. hmm. in /sys/src/libc/amd64/arv0.s _privates and _nprivates are in the bss. GLOBL _privates(SB), $8 GLOBL _nprivates(SB), $4 so they can be set in the parent process. in /sys/src/libc/amd64/main9.s #define NPRIVATES 16 TEXT _main(SB), 1, $(2*8+NPRIVATES*8) MOVQ AX, _tos(SB) LEAQ 16(SP), AX MOVQ AX, _privates(SB) MOVL $NPRIVATES, _nprivates(SB) we see that the privates and nprivates are on the stack just below _tos. the only ways i can see your pointer not being nil is (a) kernel bug -- the stack is not cleared (b) the the parent has written to the privalloc'd element before forking, and the stack was copied faithfully. i think you can tell which case you have by assert(*p == nil) in the parent. i'm sure there could be other bugs as well. as to getpid() being "slow", you can always use _tos->pid - erik