On Sat Sep 5 07:06:44 PDT 2015, [email protected] wrote:
> 2011-05-20 3:30 GMT+02:00 erik quanstrom <[email protected]>:
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