ref: e38d42b4a7f278a7f7835e07983115e4ee1b0db4
parent: 16c1cc99ec6db23f8d7b056127c77a4dcf14f2b5
author: cinap_lenrek <cinap_lenrek@felloff.net>
date: Wed Jan 3 23:49:33 EST 2024
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.
--- a/sys/src/9/port/segment.c
+++ b/sys/src/9/port/segment.c
@@ -109,6 +109,9 @@
} else if(decref(s) != 0)
return;
+ assert(s->sema.prev == &s->sema);
+ assert(s->sema.next = &s->sema);
+
if(s->mapsize > 0){
emap = &s->map[s->mapsize];
for(pte = s->map; pte < emap; pte++)
--- a/sys/src/9/port/sysproc.c
+++ b/sys/src/9/port/sysproc.c
@@ -236,7 +236,6 @@
wm = up->wired;
if(wm != nil)
procwired(p, wm->machno);
- p->psstate = nil;
ready(p);
sched();
return pid;
@@ -1141,19 +1140,15 @@
return 1;
if(!block)
return 0;
-
- acquired = 0;
semqueue(s, addr, &phore);
- for(;;){
- phore.waiting = 1;
- coherence();
- if(canacquire(addr)){
- acquired = 1;
- break;
+ if(acquired = !waserror()){
+ for(;;){
+ phore.waiting = 1;
+ coherence();
+ if(canacquire(addr))
+ break;
+ sleep(&phore, semawoke, &phore);
}
- if(waserror())
- break;
- sleep(&phore, semawoke, &phore);
poperror();
}
semdequeue(s, &phore);
@@ -1169,7 +1164,7 @@
static int
tsemacquire(Segment *s, long *addr, ulong ms)
{
- int acquired, timedout;
+ int timedout, acquired;
ulong t;
Sema phore;
@@ -1177,36 +1172,32 @@
return 1;
if(ms == 0)
return 0;
- acquired = timedout = 0;
+ timedout = 0;
semqueue(s, addr, &phore);
- for(;;){
- phore.waiting = 1;
- coherence();
- if(canacquire(addr)){
- acquired = 1;
- break;
+ if(acquired = !waserror()){
+ for(;;){
+ phore.waiting = 1;
+ coherence();
+ if(canacquire(addr))
+ 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();
- if(t >= ms){
- timedout = 1;
- break;
- }
- ms -= t;
}
semdequeue(s, &phore);
coherence(); /* not strictly necessary due to lock in semdequeue */
if(!phore.waiting)
semwakeup(s, addr, 1);
- if(timedout)
- return 0;
if(!acquired)
nexterror();
- return 1;
+ return !timedout;
}
uintptr