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

View File

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

View File

@ -610,6 +610,9 @@ struct Proc
int inkernel; /* either on syscall or fault */ int inkernel; /* either on syscall or fault */
Syscalls cursyscall; /* zero on 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 */ int32_t blockingfd; /* fd currenly read/written */

View File

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

View File

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

View File

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