kernel: awake() wake up only truly blocking syscalls

If a syscall did not entered sleep(), the pendingWakeup is not consumed.
This commit is contained in:
Giacomo Tesio 2017-05-17 02:04:08 +02:00
parent 1dc8991331
commit 22d90985a5
6 changed files with 17 additions and 7 deletions

View File

@ -238,6 +238,7 @@ syscall(Syscalls scallnr, Ureg* ureg)
m->syscall++;
up->inkernel = 1;
up->cursyscall = (Syscalls)scallnr;
up->blockingsc = 0;
up->pc = ureg->ip;
up->dbgreg = ureg;
if(up->trace && (pt = proctrace) != nil)
@ -354,8 +355,13 @@ syscall(Syscalls scallnr, Ureg* ureg)
splhi();
if(scallnr != SysRfork && (up->procctl || up->nnote))
notify(ureg);
else if(canwakeup(scallnr))
awokeproc(up);
else if(up->blockingsc){
if(up->blockingsc != scallnr)
panic("syscall: up->blockingsc dirty");
if(canwakeup(scallnr))
awokeproc(up);
up->blockingsc = 0;
}
/* if we delayed sched because we held a lock, sched now */
if(up->delaysched){

View File

@ -43,10 +43,9 @@ static Rendez awaker;
int
canwakeup(Syscalls scall)
{
if(scall == 0){
/* on page fault */
return 0;
}
if(scall == 0)
panic("canwakeup on page fault");
switch(scall){
default:
panic("canwakeup: unknown scall %d\n", scall);

View File

@ -610,6 +610,9 @@ struct Proc
int inkernel; /* either on syscall or fault */
Syscalls cursyscall; /* zero on fault */
Syscalls blockingsc; /* set to cursyscall on sleep() and sysrendevouz
* reset by syscall
*/
int32_t blockingfd; /* fd currenly read/written */

View File

@ -33,7 +33,7 @@ int anyhigher(void);
int anyready(void);
void awakekproc(void*);
#define awokeproc(p) (p->lastWakeup = p->pendingWakeup)
#define awakeOnBlock(p) (p->lastWakeup < p->pendingWakeup)
#define awakeOnBlock(p) (p->blockingsc && p->lastWakeup < p->pendingWakeup)
Block* bl2mem(uint8_t*, Block*, int);
int blocklen(Block*);
void bootlinks(void);

View File

@ -712,6 +712,7 @@ sleep(Rendez *r, int (*f)(void*), void *arg)
*/
r->p = up;
up->blockingsc = up->cursyscall;
if((*f)(arg)
|| (up->notepending && !up->notedeferred)
|| (up->inkernel && awakeOnBlock(up) && canwakeup(up->cursyscall))){

View File

@ -839,6 +839,7 @@ sysrendezvous(void* tagp, void* rendvalp)
l = &p->rendhash;
}
up->blockingsc = up->cursyscall;
if(awakeOnBlock(up)){
unlock(&up->rgrp->l);
result = UINT2PTR(up->rendval);