More Delay/Semaphore "fun"

Andreas Raab andreas.raab at gmx.de
Sun Oct 7 18:31:51 UTC 2007


Paolo Bonzini wrote:
> GNU Smalltalk does it like this:
> 
>  | caught |
>  ^[
>      [
>          "The VM will not preempt the process between the two statements.
>           Note that it is *wrong* to set the variable to true before
>           obtaining the semaphore, but the exception handler straightens
>           that.  On the other hand, setting the variable to true after the
>           wait would be wrong if the process was preempted and terminated
>           after the wait (hence, with `caught' still set to false and the
>           semaphore obtained)."
>          caught := true.
>          self wait ] on: ProcessBeingTerminated do: [ :ex |
>              ex semaphore isNil ifFalse: [ caught := false ] ].
>      aBlock value ]
>          ensure: [caught ifTrue: [self signal] ]
> 
> 
> with Process>>#terminate sending a ProcessBeingTerminated notification 
> before issuing the final "suspend" call.  If the process was waiting on 
> a semaphore (as seen from the suspendingList), that semaphore is stored 
> into the notification.  Seems to work.

Hm ... it looks wrong to me unless there is a part which isn't shown 
here or GST works differently. In Squeak, when the semaphore gets 
signaled, the process gets transferred from the semaphore to one of 
Processor's suspendedList. So testing for nil wouldn't work in a 
situation like here:

   s := Semaphore new.

   "Create a process that enters the critical section at low priority"
   p := [s critical:[]] forkAt: Processor activePriority-1.
   [p suspendingList == s] whileFalse:[(Delay forMilliseconds: 10) wait].

   "At this point, the suspendingList is the semaphore"
   self assert:[p suspendingList == s].

   "Signal the semaphore"
   s signal.

   "At this point, the suspendingList is inside Processor (but non-nil)"
   self assert:[p suspendingList == (Processor waitingProcessesAt: p 
priority)].

   "Now terminate p"
   p terminate.

   "And check the signal count"
   self assert:[(s instVarNamed: 'excessSignals') = 1].

I would really expect that code above to to test for "ex semaphore == 
self" instead of nil, which would make a lot more sense to me. Also, how 
do you ensure atomicity in the operation when you manipulate the 
suspendingList itself?

Cheers,
   - Andreas



More information about the Squeak-dev mailing list