mirror of
git://git.9front.org/plan9front/plan9front
synced 2025-01-12 11:10:06 +00:00
kernel: handle errors in semacquire
Move waserror()/poperror() out of the loop, so we can also catch errors from canacquire(). This is theoretically possible if memory has been paged out and we get I/O errors when trying to page it back in.
This commit is contained in:
parent
16c1cc99ec
commit
e38d42b4a7
2 changed files with 27 additions and 33 deletions
|
@ -109,6 +109,9 @@ putseg(Segment *s)
|
||||||
} else if(decref(s) != 0)
|
} else if(decref(s) != 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
assert(s->sema.prev == &s->sema);
|
||||||
|
assert(s->sema.next = &s->sema);
|
||||||
|
|
||||||
if(s->mapsize > 0){
|
if(s->mapsize > 0){
|
||||||
emap = &s->map[s->mapsize];
|
emap = &s->map[s->mapsize];
|
||||||
for(pte = s->map; pte < emap; pte++)
|
for(pte = s->map; pte < emap; pte++)
|
||||||
|
|
|
@ -236,7 +236,6 @@ sysrfork(va_list list)
|
||||||
wm = up->wired;
|
wm = up->wired;
|
||||||
if(wm != nil)
|
if(wm != nil)
|
||||||
procwired(p, wm->machno);
|
procwired(p, wm->machno);
|
||||||
p->psstate = nil;
|
|
||||||
ready(p);
|
ready(p);
|
||||||
sched();
|
sched();
|
||||||
return pid;
|
return pid;
|
||||||
|
@ -1141,19 +1140,15 @@ semacquire(Segment *s, long *addr, int block)
|
||||||
return 1;
|
return 1;
|
||||||
if(!block)
|
if(!block)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
acquired = 0;
|
|
||||||
semqueue(s, addr, &phore);
|
semqueue(s, addr, &phore);
|
||||||
for(;;){
|
if(acquired = !waserror()){
|
||||||
phore.waiting = 1;
|
for(;;){
|
||||||
coherence();
|
phore.waiting = 1;
|
||||||
if(canacquire(addr)){
|
coherence();
|
||||||
acquired = 1;
|
if(canacquire(addr))
|
||||||
break;
|
break;
|
||||||
|
sleep(&phore, semawoke, &phore);
|
||||||
}
|
}
|
||||||
if(waserror())
|
|
||||||
break;
|
|
||||||
sleep(&phore, semawoke, &phore);
|
|
||||||
poperror();
|
poperror();
|
||||||
}
|
}
|
||||||
semdequeue(s, &phore);
|
semdequeue(s, &phore);
|
||||||
|
@ -1169,7 +1164,7 @@ semacquire(Segment *s, long *addr, int block)
|
||||||
static int
|
static int
|
||||||
tsemacquire(Segment *s, long *addr, ulong ms)
|
tsemacquire(Segment *s, long *addr, ulong ms)
|
||||||
{
|
{
|
||||||
int acquired, timedout;
|
int timedout, acquired;
|
||||||
ulong t;
|
ulong t;
|
||||||
Sema phore;
|
Sema phore;
|
||||||
|
|
||||||
|
@ -1177,36 +1172,32 @@ tsemacquire(Segment *s, long *addr, ulong ms)
|
||||||
return 1;
|
return 1;
|
||||||
if(ms == 0)
|
if(ms == 0)
|
||||||
return 0;
|
return 0;
|
||||||
acquired = timedout = 0;
|
timedout = 0;
|
||||||
semqueue(s, addr, &phore);
|
semqueue(s, addr, &phore);
|
||||||
for(;;){
|
if(acquired = !waserror()){
|
||||||
phore.waiting = 1;
|
for(;;){
|
||||||
coherence();
|
phore.waiting = 1;
|
||||||
if(canacquire(addr)){
|
coherence();
|
||||||
acquired = 1;
|
if(canacquire(addr))
|
||||||
break;
|
break;
|
||||||
|
t = MACHP(0)->ticks;
|
||||||
|
tsleep(&phore, semawoke, &phore, ms);
|
||||||
|
t = TK2MS(MACHP(0)->ticks - t);
|
||||||
|
if(t >= ms){
|
||||||
|
timedout = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
ms -= t;
|
||||||
}
|
}
|
||||||
if(waserror())
|
|
||||||
break;
|
|
||||||
t = MACHP(0)->ticks;
|
|
||||||
tsleep(&phore, semawoke, &phore, ms);
|
|
||||||
t = TK2MS(MACHP(0)->ticks - t);
|
|
||||||
poperror();
|
poperror();
|
||||||
if(t >= ms){
|
|
||||||
timedout = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
ms -= t;
|
|
||||||
}
|
}
|
||||||
semdequeue(s, &phore);
|
semdequeue(s, &phore);
|
||||||
coherence(); /* not strictly necessary due to lock in semdequeue */
|
coherence(); /* not strictly necessary due to lock in semdequeue */
|
||||||
if(!phore.waiting)
|
if(!phore.waiting)
|
||||||
semwakeup(s, addr, 1);
|
semwakeup(s, addr, 1);
|
||||||
if(timedout)
|
|
||||||
return 0;
|
|
||||||
if(!acquired)
|
if(!acquired)
|
||||||
nexterror();
|
nexterror();
|
||||||
return 1;
|
return !timedout;
|
||||||
}
|
}
|
||||||
|
|
||||||
uintptr
|
uintptr
|
||||||
|
|
Loading…
Reference in a new issue