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 | lock(&r->lk); | 70 | lock(&r->lk); |
| 71 | p = r->p; | 71 | p = r->p; |
| 72 | 72 | ||
| 73 | if(p != nil){ | 73 | if(p == nil) |
| 74 | unlock(&r->lk); | ||
| 75 | else { | ||
| 74 | lock(&p->rlock); | 76 | lock(&p->rlock); |
| 75 | if(p->state != Wakeme || p->r != r) | 77 | if(p->state != Wakeme || p->r != r) |
| 76 | panic("wakeup: state"); | 78 | panic("wakeup: state"); |
| 79 | p->state = Running; | ||
| 77 | r->p = nil; | 80 | r->p = nil; |
| 78 | p->r = nil; | 81 | p->r = nil; |
| 79 | p->state = Running; | ||
| 80 | procwakeup(p); | ||
| 81 | unlock(&p->rlock); | 82 | unlock(&p->rlock); |
| 83 | unlock(&r->lk); | ||
| 84 | procwakeup(p); | ||
| 82 | } | 85 | } |
| 83 | unlock(&r->lk); | ||
| 84 | |||
| 85 | splx(s); | 86 | splx(s); |
| 86 | 87 | ||
| 87 | return p; | 88 | return p; |