More Delay/Semaphore "fun"

Andreas Raab andreas.raab at gmx.de
Fri Oct 5 17:34:27 UTC 2007


Hi Simon -

I think I got it. Look at this:

Semaphore>>critical:
   caught := false.
   [
     caught := true.
     self wait.
     blockValue := mutuallyExcludedBlock value
   ] ensure: [
     caught ifTrue: [self signal].
   ].

Now let's run a little thought experiment:
* p1 enters the #critical:
* enters ensure: block
* sets "caught"
* waits on semaphore
* enters mutually excluded block; does its stuff

And then:
* p2 enters #critical:
* enters ensure: block
* sets "caught"
* waits on semaphore
* gets killed

At this point, we enter the ensure: handler for p2. And will 'ya look at 
that: "caught" is set even though p2 didn't ever own the critical 
section. This will make it signal the semaphore and screw up the rest of it.

Okay, obviously this needs to be changed to say, e.g.:

     self wait.
     caught := true. "entered semaphore successfully"

I have an image running in the background with your loop and it seems to 
be doing fine for now. Coincidentally, I have not seen the effect that 
too *few* signals were generated; are you certain you ever had that 
effect? It couldn't be explained with the above sequence at all.

Cheers,
   - Andreas

Simon Kirk wrote:
> Hi all. We've been playing with Semaphores and Delays recently, as we 
> were having some problems with said issues. We tried installing Andreas' 
> fixes, but if we do, the code below yields some strange results when 
> evaluated in a workspace:
> 
> 
> s _ Semaphore forMutualExclusion.
> i _ 1.
> 
> "Loop while there's not too many signals on the semaphore (should be 0 
> or 1)"
> [(s instVarNamed: #excessSignals) < 2] whileTrue: [
> 
> "Fork two processes to do things inside the semaphore"
> p _ [[true] whileTrue: [s critical: [(Delay forMilliseconds: 10) wait]]]
>     forkNamed: 'p', i printString.
>     
> q _ [[true] whileTrue: [s critical: [(Delay forMilliseconds: 10) wait]]]
>     forkNamed: 'q', i printString.
> 
> "Increment the counter just to make it easy to ID the processes"
> i _ i + 1.
> 
> "Delay to give the processes a chance to resume and potentially get into 
> the critical on the Semaphore"
> (Delay forMilliseconds: 500 atRandom) wait.
> p terminate.
> (Delay forMilliseconds: 500 atRandom) wait.
> q terminate.
> 
> "After terminating the two processes, the excess signals should be 1 on 
> the Semaphore because
> nothing is in critical any more, assuming the processes terminated 
> properly and the unwind happened
> as it should, but... "
> 
> "In our images with Andreas' recent Delay and Semaphore fixes, we always 
> get one of these two
> error conditions (although normally too many signals). This would cause 
> deadlock in 'real world' situations"
> (s instVarNamed: #excessSignals) = 0 ifTrue: [
>     WorldState addDeferredUIMessage: [self inform: 'Too few signals 
> after ', i printString, ' loops']]].
> self inform: 'Too many signals after ', i printString, ' loops'.
> 
> 
> Don't know if we've done something wrong here, but if not I hope it may 
> give cleverer people than me some more pointers to the root of the whole 
> Semaphore problem :)
> 
> S
> 
> 
> Pinesoft Computers are registered in England, Registered number: 
> 2914825. Registered office: 266-268 High Street, Waltham Cross, Herts, 
> EN8 7EA
> 
> 
> 
> This message has been scanned for viruses by BlackSpider MailControl - 
> www.blackspider.com
> 
> 
> 




More information about the Squeak-dev mailing list