kernel: rendezvous(~0, ...) unconditionally blocks
This commit introduce a special rendezvous point at (void*)~0 that cannot be reached by any process, since it's not added to the rendezvous group. This turns the rendezvous syscall to a cheap way to block until either a note or a wakeup from awake(2) occurs. This new feature is used in libc's sleep: the test qa/kern/fork_chain has shown that using a stack address as rendezvous point is not safe enougth for sleep, since two different process forked from the same function can call sleep with the same base pointer. This lead the wakeup variable in jehanne_sleep to have the same address on both process. TODO add a test that show this behaviour in the old code.
This commit is contained in:
parent
c13d386ab5
commit
1bc08b7631
@ -821,6 +821,15 @@ sysrendezvous(void* tagp, void* rendvalp)
|
||||
up->rendval = ~0;
|
||||
|
||||
lock(&up->rgrp->l);
|
||||
|
||||
/* NOTE:
|
||||
* In Jehanne, the rendezvous point ~0 is always private:
|
||||
* it can only be interrupted from a scheduled wakeup
|
||||
* (see sysawake) or from a note
|
||||
*/
|
||||
if(tag == (uintptr_t)~0)
|
||||
goto rendezvousBlocks;
|
||||
|
||||
for(p = *l; p; p = p->rendhash) {
|
||||
if(p->rendtag == tag) {
|
||||
*l = p->rendhash;
|
||||
@ -839,6 +848,7 @@ sysrendezvous(void* tagp, void* rendvalp)
|
||||
l = &p->rendhash;
|
||||
}
|
||||
|
||||
rendezvousBlocks:
|
||||
up->blockingsc = up->cursyscall;
|
||||
if(awakeOnBlock(up)){
|
||||
unlock(&up->rgrp->l);
|
||||
|
@ -26,7 +26,7 @@ jehanne_sleep(int32_t millisecs)
|
||||
|
||||
wakeup = awake(millisecs); // give up the processor, in any case
|
||||
if(millisecs > 0)
|
||||
while(rendezvous(&wakeup, (void*)1) == (void*)~0)
|
||||
while(rendezvous((void*)~0, (void*)1) == (void*)~0)
|
||||
if(jehanne_awakened(wakeup))
|
||||
return;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user