Semaphore.st
changeset 2262 4c4d810f006f
parent 2235 c6a15bd9a33c
child 2265 775feb718a9d
equal deleted inserted replaced
2261:61096f935f76 2262:4c4d810f006f
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
    13 Object subclass:#Semaphore
    13 Object subclass:#Semaphore
    14 	instanceVariableNames:'count waitingProcesses'
    14 	instanceVariableNames:'count waitingProcesses lastOwnerID name'
    15 	classVariableNames:''
    15 	classVariableNames:''
    16 	poolDictionaries:''
    16 	poolDictionaries:''
    17 	category:'Kernel-Processes'
    17 	category:'Kernel-Processes'
    18 !
    18 !
    19 
    19 
    55     under some condition.
    55     under some condition.
    56     See 'Processor>>signal:afterSeconds:', 'Processor>>signal:onInput:' etc.
    56     See 'Processor>>signal:afterSeconds:', 'Processor>>signal:onInput:' etc.
    57 
    57 
    58     See examples in doc/coding (found in the CodingExamples-nameSpace).
    58     See examples in doc/coding (found in the CodingExamples-nameSpace).
    59 
    59 
       
    60     [instance variables:]
       
    61 	count			<SmallInteger>		the number of waits, that will go through
       
    62 							without blocking.
       
    63 							Incremented on #signal; decremented on #wait.
       
    64 
       
    65 	waitingProcesses	<OrderedCollection>	waiting processes - will be served first
       
    66 							come first served when signalled.
       
    67 
       
    68 	lastOwnerID		<SmallInteger>		a debugging aid: set when count drops
       
    69 							to zero to the current processes id.
       
    70 							Helps in finding deadlocks.
       
    71 
       
    72 	name			<String>		a debugging aid: an optional userFriendly
       
    73 							name; helps to identify a semaphore easier.
       
    74 
    60     [see also:]
    75     [see also:]
    61         SemaphoreSet RecursionLock Monitor
    76         SemaphoreSet RecursionLock Monitor
    62         SharedQueue Delay 
    77         SharedQueue Delay 
    63         Process ProcessorScheduler
    78         Process ProcessorScheduler
    64 
    79 
    95 !Semaphore methodsFor:'friend-class interface'!
   110 !Semaphore methodsFor:'friend-class interface'!
    96 
   111 
    97 checkAndRegisterProcess:process
   112 checkAndRegisterProcess:process
    98     "interface for SemaphoreSet.
   113     "interface for SemaphoreSet.
    99      If the semaphore is available, decrement it and return true.
   114      If the semaphore is available, decrement it and return true.
   100      Otherwise register our process to be wakened up once the semaphore is available.
   115      Otherwise register our process to be wakened up once the semaphore is available
   101     "
   116      and return false..
   102 
   117     "
   103     "
   118 
       
   119     "
       
   120      bad ST/X trick (needs change, when multiProcessor support is added):
   104      this works only since interrupts are only serviced at 
   121      this works only since interrupts are only serviced at 
   105      message send and method-return time ....
   122      message send and method-return time ....
   106      If you add a message send into the ifTrue:-block, things will
   123      If you add a message send into the ifTrue:-block, things will
   107      go mad ... (especially be careful when adding a debugPrint-here)
   124      go mad ... (especially be careful when adding a debugPrint-here)
   108     "
   125     "
   109     count ~~ 0 ifTrue:[
   126     count ~~ 0 ifTrue:[
   110         count := count - 1.
   127         count := count - 1.
       
   128 	count == 0 ifTrue:[
       
   129 	    lastOwnerID := Processor activeProcessId.
       
   130 	].
   111         ^ true
   131         ^ true
   112     ].
   132     ].
   113     (waitingProcesses identityIndexOf:process) == 0 ifTrue:[
   133     (waitingProcesses identityIndexOf:process) == 0 ifTrue:[
   114         waitingProcesses add:process.
   134         waitingProcesses add:process.
   115     ].
   135     ].
   129     "Modified: 10.1.1997 / 21:42:29 / cg"
   149     "Modified: 10.1.1997 / 21:42:29 / cg"
   130 ! !
   150 ! !
   131 
   151 
   132 !Semaphore methodsFor:'printing & storing'!
   152 !Semaphore methodsFor:'printing & storing'!
   133 
   153 
       
   154 name
       
   155     "return the semaphores userFriendly name"
       
   156 
       
   157     ^ name
       
   158 !
       
   159 
       
   160 name:aString
       
   161     "set the semaphores userFriendly name"
       
   162 
       
   163     name := aString
       
   164 !
       
   165 
   134 displayString
   166 displayString
   135     "return a string to display the receiver - include the
   167     "return a string to display the receiver - include the
   136      count for your convenience"
   168      count for your convenience"
   137 
   169 
   138     ^ self class name , '(' , count printString , ')'
   170     |n|
       
   171 
       
   172     name isNil ifTrue:[
       
   173 	n := 'unnamed'
       
   174     ] ifFalse:[
       
   175 	n := name
       
   176     ].
       
   177 
       
   178     ^ self class name , '(' , count printString , ' name: ' , n , ')'
   139 
   179 
   140     "Modified: 10.1.1997 / 21:43:04 / cg"
   180     "Modified: 10.1.1997 / 21:43:04 / cg"
   141 ! !
   181 ! !
   142 
   182 
   143 !Semaphore methodsFor:'private accessing'!
   183 !Semaphore methodsFor:'private accessing'!
   322     "wait for the semaphore"
   362     "wait for the semaphore"
   323 
   363 
   324     |activeProcess wasBlocked|
   364     |activeProcess wasBlocked|
   325 
   365 
   326     "
   366     "
       
   367      bad ST/X trick (needs change, when multiProcessor support is added):
   327      this works only since interrupts are only serviced at 
   368      this works only since interrupts are only serviced at 
   328      message send and method-return time ....
   369      message send and method-return time ....
   329      If you add a message send into the ifTrue:-block, things will
   370      If you add a message send between the compare and the decrement,
   330      go mad ... (especially be careful when adding a debugPrint-here)
   371      things will go mad ... (especially be careful when adding a debugPrint-here)
   331     "
   372     "
   332     count ~~ 0 ifTrue:[
   373     count ~~ 0 ifTrue:[
   333         count := count - 1.
   374         count := count - 1.
       
   375 	count == 0 ifTrue:[
       
   376 	    lastOwnerID := Processor activeProcessId.
       
   377 	].
   334         ^ self
   378         ^ self
   335     ].
   379     ].
   336 
   380 
   337     activeProcess := Processor activeProcess.
   381     activeProcess := Processor activeProcess.
   338 
   382 
   361             "/ being multiple times on waitingProcesses
   405             "/ being multiple times on waitingProcesses
   362             waitingProcesses remove:activeProcess ifAbsent:[].
   406             waitingProcesses remove:activeProcess ifAbsent:[].
   363         ]
   407         ]
   364     ].
   408     ].
   365     count := count - 1.
   409     count := count - 1.
       
   410     count == 0 ifTrue:[
       
   411 	lastOwnerID := Processor activeProcessId.
       
   412     ].
   366     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   413     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   367 
   414 
   368     "Modified: 13.12.1995 / 13:26:33 / stefan"
   415     "Modified: 13.12.1995 / 13:26:33 / stefan"
   369     "Modified: 10.1.1997 / 21:41:04 / cg"
   416     "Modified: 10.1.1997 / 21:41:04 / cg"
   370 !
   417 !
   374      (i.e. do not count down)"
   421      (i.e. do not count down)"
   375 
   422 
   376     |activeProcess wasBlocked|
   423     |activeProcess wasBlocked|
   377 
   424 
   378     "
   425     "
       
   426      bad ST/X trick (needs change, when multiProcessor support is added):
   379      this works only since interrupts are only serviced at 
   427      this works only since interrupts are only serviced at 
   380      message send and method-return time ....
   428      message send and method-return time ....
   381      If you add a message send into the ifTrue:-block, things will
   429      If you add a message send between the compare and the decrement,
   382      go mad ... (especially be careful when adding a debugPrint-here)
   430      things will go mad ... (especially be careful when adding a debugPrint-here)
   383     "
   431     "
   384     count ~~ 0 ifTrue:[
   432     count ~~ 0 ifTrue:[
   385         ^ self
   433         ^ self
   386     ].
   434     ].
   387 
   435 
   427      (which is not the intend of semaphores, though)."
   475      (which is not the intend of semaphores, though)."
   428 
   476 
   429     |activeProcess timeoutOccured wasBlocked unblock now endTime|
   477     |activeProcess timeoutOccured wasBlocked unblock now endTime|
   430 
   478 
   431     "
   479     "
       
   480      bad ST/X trick (needs change, when multiProcessor support is added):
   432      this works only since interrupts are only serviced at 
   481      this works only since interrupts are only serviced at 
   433      message send and method-return time ....
   482      message send and method-return time ....
   434      If you add a message send into the ifTrue:-block, things will
   483      If you add a message send between the compare and the decrement,
   435      go mad ... (especially be careful when adding a debugPrint-here)
   484      things will go mad ... (especially be careful when adding a debugPrint-here)
   436     "
   485     "
   437     count ~~ 0 ifTrue:[
   486     count ~~ 0 ifTrue:[
   438         count := count - 1.
   487         count := count - 1.
       
   488         count == 0 ifTrue:[
       
   489 	    lastOwnerID := Processor activeProcessId.
       
   490         ].
   439         ^ self
   491         ^ self
   440     ].
   492     ].
   441 
   493 
   442     "
   494     "
   443      with zero-timeout, this is a poll
   495      with zero-timeout, this is a poll
   486             ^ nil
   538             ^ nil
   487         ].
   539         ].
   488     ].
   540     ].
   489     Processor removeTimedBlock:unblock.
   541     Processor removeTimedBlock:unblock.
   490     count := count - 1.
   542     count := count - 1.
       
   543     count == 0 ifTrue:[
       
   544 	lastOwnerID := Processor activeProcessId.
       
   545     ].
   491     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   546     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   492     ^ self
   547     ^ self
   493 
   548 
   494     "Modified: 13.12.1995 / 13:27:24 / stefan"
   549     "Modified: 13.12.1995 / 13:27:24 / stefan"
   495     "Modified: 10.1.1997 / 21:41:24 / cg"
   550     "Modified: 10.1.1997 / 21:41:24 / cg"
   496 ! !
   551 ! !
   497 
   552 
   498 !Semaphore class methodsFor:'documentation'!
   553 !Semaphore class methodsFor:'documentation'!
   499 
   554 
   500 version
   555 version
   501     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.41 1997-01-23 02:24:48 cg Exp $'
   556     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.42 1997-01-24 22:11:02 cg Exp $'
   502 ! !
   557 ! !