From mboxrd@z Thu Jan 1 00:00:00 1970 From: miller@hamnavoe.demon.co.uk To: 9fans@cse.psu.edu Subject: Re: [9fans] Kernel question: i386 test-and-set problem Date: Wed, 2 Aug 2000 15:51:33 +0100 MIME-Version: 1.0 Content-Type: text/plain; charset="US-ASCII" Content-Transfer-Encoding: 7bit Message-Id: Topicbox-Message-UUID: f2c6a0b6-eac8-11e9-9e20-41e7f4b1d025 > If it were at all possible for wakeup to be called with > r already freed, the code would be wrong to begin with > since r is an argument to wakeup. For things to go wrong it's not necessary for wakeup to be called after r is freed; what I said was "the free(r) and malloc() could happen *while* or even before wakeup(r) runs". It's sufficient to have sleep(r) and wakeup(r) racing on two processors. We could have this interleaving of events: sleep(r) is called wakeup(r) is called sleep tests wakeup condition, returns wakeup is delayed by an interrupt on its processor caller of sleep deallocates structure containing r some other process reallocates r and clobbers r->p wakeup resumes, dereferences r->p, ka-boom! If you think sleep and wakeup are sufficiently interlocked by higher level considerations that this can't happen, then let's use your scenario with postnote, mutatis mutandis to apply to the existing kernel algorithm: process x calls postnote: postnote(p): p->notepending = 1 lock(p->rlock) r = p->r if r != 0 if(r->p == p && p->r == r) r->p = 0 p->r = 0 ready(p) unlock(p->rlock) Immediately after the unlock(p->rlock) is executed, process q calls wakeup process q: wakeup(r): {wakeup condition is satisfied} coherence() p = r->p if p != 0 lock(p->rlock) if (r->p == p && p->r == r) r->p = 0 p->r = 0 ready(p) unlock(p->rlock) During the call to coherence() process q is interrupted. Process p now continues after the sleep: process p: sleep(r); free(r) Process y now does xxx = malloc(234); xxx->a = 12; And finally process q resumes, and loads and dereferences r->p which is no longer vald. ka-boom again. -- Richard