In case the Rendez structure is backed by dynamic memory that might be freed after we ready the sleeping process, we must not touch it (unlock(&r->lk)) after procwakeup(). (Also remove unused copy of rendez.c).
Unified · Split
| @@ -1,89 +0,0 @@ | ||
| 1 | −#include "u.h" | |
| 2 | −#include "lib.h" | |
| 3 | −#include "dat.h" | |
| 4 | −#include "fns.h" | |
| 5 | −#include "error.h" | |
| 6 | − | |
| 7 | −void | |
| 8 | −sleep(Rendez *r, int (*f)(void*), void *arg) | |
| 9 | −{ | |
| 10 | − int s; | |
| 11 | − | |
| 12 | − s = splhi(); | |
| 13 | − | |
| 14 | − lock(&r->lk); | |
| 15 | − lock(&up->rlock); | |
| 16 | − if(r->p){ | |
| 17 | − print("double sleep %lud %lud\n", r->p->pid, up->pid); | |
| 18 | − } | |
| 19 | − | |
| 20 | − /* | |
| 21 | − * Wakeup only knows there may be something to do by testing | |
| 22 | − * r->p in order to get something to lock on. | |
| 23 | − * Flush that information out to memory in case the sleep is | |
| 24 | − * committed. | |
| 25 | − */ | |
| 26 | − r->p = up; | |
| 27 | − | |
| 28 | − if((*f)(arg) || up->notepending){ | |
| 29 | − /* | |
| 30 | − * if condition happened or a note is pending | |
| 31 | − * never mind | |
| 32 | − */ | |
| 33 | − r->p = nil; | |
| 34 | − unlock(&up->rlock); | |
| 35 | − unlock(&r->lk); | |
| 36 | − } else { | |
| 37 | − /* | |
| 38 | − * now we are committed to | |
| 39 | − * change state and call scheduler | |
| 40 | − */ | |
| 41 | − up->state = Wakeme; | |
| 42 | − up->r = r; | |
| 43 | − | |
| 44 | − /* statistics */ | |
| 45 | − /* m->cs++; */ | |
| 46 | − | |
| 47 | − unlock(&up->rlock); | |
| 48 | − unlock(&r->lk); | |
| 49 | − | |
| 50 | − procsleep(); | |
| 51 | − } | |
| 52 | − | |
| 53 | − if(up->notepending) { | |
| 54 | − up->notepending = 0; | |
| 55 | − splx(s); | |
| 56 | − error(Eintr); | |
| 57 | − } | |
| 58 | − | |
| 59 | − splx(s); | |
| 60 | −} | |
| 61 | − | |
| 62 | −Proc* | |
| 63 | −wakeup(Rendez *r) | |
| 64 | −{ | |
| 65 | − Proc *p; | |
| 66 | − int s; | |
| 67 | − | |
| 68 | − s = splhi(); | |
| 69 | − | |
| 70 | − lock(&r->lk); | |
| 71 | − p = r->p; | |
| 72 | − | |
| 73 | − if(p != nil){ | |
| 74 | − lock(&p->rlock); | |
| 75 | − if(p->state != Wakeme || p->r != r) | |
| 76 | − panic("wakeup: state"); | |
| 77 | − r->p = nil; | |
| 78 | − p->r = nil; | |
| 79 | − p->state = Running; | |
| 80 | − procwakeup(p); | |
| 81 | − unlock(&p->rlock); | |
| 82 | − } | |
| 83 | − unlock(&r->lk); | |
| 84 | − | |
| 85 | − splx(s); | |
| 86 | − | |
| 87 | − return p; | |
| 88 | −} | |
| 89 | − | |
| @@ -70,18 +70,19 @@ wakeup(Rendez *r) · 69 unmodified lines | ||
| 70 | 70 | lock(&r->lk); |
| 71 | 71 | p = r->p; |
| 72 | 72 | |
| 73 | − if(p != nil){ | |
| 73 | + if(p == nil) | |
| 74 | + unlock(&r->lk); | |
| 75 | + else { | |
| 74 | 76 | lock(&p->rlock); |
| 75 | 77 | if(p->state != Wakeme || p->r != r) |
| 76 | 78 | panic("wakeup: state"); |
| 79 | + p->state = Running; | |
| 77 | 80 | r->p = nil; |
| 78 | 81 | p->r = nil; |
| 79 | − p->state = Running; | |
| 80 | − procwakeup(p); | |
| 81 | 82 | unlock(&p->rlock); |
| 83 | + unlock(&r->lk); | |
| 84 | + procwakeup(p); | |
| 82 | 85 | } |
| 83 | − unlock(&r->lk); | |
| 84 | − | |
| 85 | 86 | splx(s); |
| 86 | 87 | |
| 87 | 88 | return p; |