Semaphore.st
changeset 1 a27a279701f8
child 3 24d81bf47225
equal deleted inserted replaced
0:aa2498ef6470 1:a27a279701f8
       
     1 "
       
     2  COPYRIGHT (c) 1993 by Claus Gittinger
       
     3               All Rights Reserved
       
     4 
       
     5  This software is furnished under a license and may be used
       
     6  only in accordance with the terms of that license and with the
       
     7  inclusion of the above copyright notice.   This software may not
       
     8  be provided or otherwise made available to, or used by, any
       
     9  other person.  No title to or ownership of the software is
       
    10  hereby transferred.
       
    11 "
       
    12 
       
    13 LinkedList subclass:#Semaphore
       
    14          instanceVariableNames:'count waitingProcesses'
       
    15          classVariableNames:''
       
    16          poolDictionaries:''
       
    17          category:'Kernel-Processes'!
       
    18 
       
    19 Semaphore comment:'
       
    20 
       
    21 COPYRIGHT (c) 1993 by Claus Gittinger
       
    22               All Rights Reserved
       
    23 
       
    24 Semaphores are used to synchronize processes providing a nonBusy wait
       
    25 mechanism. A process can wait for the availability of some resource by
       
    26 performing a Semaphore-wait, which will suspend the process until the
       
    27 resource becomes available which is signalled by (another process performing)
       
    28 Semaphore-signal.
       
    29 If the resource has been alrady available before the wait, no suspending is
       
    30 done, but the resource immediately allocated.
       
    31 
       
    32 See samples in doc/coding.
       
    33 
       
    34 %W% %E%
       
    35 '!
       
    36 
       
    37 !Semaphore class methodsFor:'instance creation'!
       
    38 
       
    39 new
       
    40     "create & return a new semaphore which blocks until a signal is sent"
       
    41 
       
    42     ^ super new setCount:0
       
    43 !
       
    44 
       
    45 new:n
       
    46     "create & return a new semaphore which allows n waits before
       
    47      blocking"
       
    48 
       
    49     ^ super new setCount:n
       
    50 !
       
    51 
       
    52 forMutualExclusion
       
    53     "create & return a new semaphore which allows exactly one process to
       
    54      wait on it without blocking"
       
    55 
       
    56     ^ self new:1
       
    57 ! !
       
    58 
       
    59 !Semaphore methodsFor:'private accessing'!
       
    60 
       
    61 setCount:n
       
    62     count := n
       
    63 ! !
       
    64 
       
    65 !Semaphore methodsFor:'wait & signal'!
       
    66 
       
    67 wait
       
    68     "wait for the semaphore"
       
    69 
       
    70     |current|
       
    71 
       
    72     "
       
    73      need a while-loop here, since more than one process may
       
    74      wait for it and another one may also wake up.
       
    75      Thus count is not always non-zero after returning from
       
    76      suspend.
       
    77     "
       
    78 
       
    79     [count == 0] whileTrue:[
       
    80         current := Processor currentProcess.
       
    81         waitingProcesses isNil ifTrue:[
       
    82             waitingProcesses := OrderedCollection with:current
       
    83         ] ifFalse:[
       
    84             waitingProcesses add:current
       
    85         ].
       
    86         current suspend
       
    87     ].
       
    88     count := count - 1
       
    89 !
       
    90 
       
    91 signal
       
    92     "waking up waiters"
       
    93 
       
    94     count := count + 1.
       
    95     waitingProcesses notNil ifTrue:[
       
    96         waitingProcesses isEmpty ifFalse:[
       
    97             waitingProcesses removeFirst resume
       
    98         ]
       
    99     ]
       
   100 !
       
   101 
       
   102 critical:aBlock
       
   103     "evaluate aBlock as a critical region; the receiver must be
       
   104      created using Semaphore-forMutualExclusion"
       
   105 
       
   106     |value|
       
   107 
       
   108     self wait.
       
   109     value := aBlock value.
       
   110     self signal.
       
   111     ^ value
       
   112 ! !