--- a/Semaphore.st Wed Jun 25 10:56:11 2014 +0200
+++ b/Semaphore.st Wed Jun 25 11:52:24 2014 +0200
@@ -813,37 +813,36 @@
wasBlocked := OperatingSystem blockInterrupts.
count <= 0 ifTrue:[
- activeProcess := Processor activeProcess.
- "
- need a while-loop here, since more than one process may
- wait for it and another one may also wake up.
- Thus, the count is not always non-zero after returning from
- suspend.
- "
- [
- self addWaitingProcess:activeProcess.
- "
- for some more descriptive info in processMonitor ...
- ... set the state to #wait (instead of #suspend)
- "
- [
- activeProcess suspendWithState:#wait
- ] ifCurtailed:[
- "interrupts are not blocked when entered through Processor>>#interruptActive"
- OperatingSystem blockInterrupts.
- self removeWaitingProcess:activeProcess.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
- self removeWaitingProcess:activeProcess.
+ activeProcess := Processor activeProcess.
+ "
+ need a while-loop here, since more than one process may
+ wait for it and another one may also wake up.
+ Thus, the count is not always non-zero after returning from
+ suspend.
+ "
+ [
+ self addWaitingProcess:activeProcess.
+ "
+ for some more descriptive info in processMonitor ...
+ ... set the state to #wait (instead of #suspend)
+ "
+ [
+ activeProcess suspendWithState:#wait
+ ] ifCurtailed:[
+ "interrupts are not blocked when entered through Processor>>#interruptActive"
+ OperatingSystem blockInterrupts.
+ self removeWaitingProcess:activeProcess.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ].
+ self removeWaitingProcess:activeProcess.
- count <= 0
- ] whileTrue.
+ count <= 0
+ ] whileTrue.
].
count := count - 1.
count == 0 ifTrue:[
- activeProcess isNil ifTrue:[activeProcess := Processor activeProcess].
- lastOwnerId := activeProcess id.
+ lastOwnerId := Processor activeProcessId.
].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
@@ -923,90 +922,178 @@
wasBlocked := OperatingSystem blockInterrupts.
count <= 0 ifTrue:[
- "with zero-timeout, this is a poll"
- milliSeconds == 0 ifTrue:[
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ^ nil
- ].
+ "with zero-timeout, this is a poll"
+ milliSeconds == 0 ifTrue:[
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ nil
+ ].
- activeProcess := Processor activeProcess.
- timeoutOccured := false.
+ activeProcess := Processor activeProcess.
+ timeoutOccured := false.
- milliSeconds notNil ifTrue:[
- "Wait with timeout: calculate the end-time"
- now := OperatingSystem getMillisecondTime.
- endTime := OperatingSystem millisecondTimeAdd:now and:milliSeconds.
+ milliSeconds notNil ifTrue:[
+ "Wait with timeout: calculate the end-time"
+ now := OperatingSystem getMillisecondTime.
+ endTime := OperatingSystem millisecondTimeAdd:now and:milliSeconds.
- timeoutBlock := [
- timeoutOccured := true.
- timeoutBlock:= nil.
- Processor resume:activeProcess.
- ].
- Processor addTimedBlock:timeoutBlock for:activeProcess atMilliseconds:endTime.
- ].
+ timeoutBlock := [
+ timeoutOccured := true.
+ timeoutBlock:= nil.
+ Processor resume:activeProcess.
+ ].
+ Processor addTimedBlock:timeoutBlock for:activeProcess atMilliseconds:endTime.
+ ].
- "
- need a while-loop here, since more than one process may
- wait for it and another one may also wake up.
- Thus, the count is not always non-zero after returning from
- suspend.
- "
- [
- self addWaitingProcess:activeProcess.
+ "
+ need a while-loop here, since more than one process may
+ wait for it and another one may also wake up.
+ Thus, the count is not always non-zero after returning from
+ suspend.
+ "
+ [
+ self addWaitingProcess:activeProcess.
- "
- for some more descriptive info in processMonitor ...
- ... set the state to #wait (instead of #suspend)
- "
- [
- "sleep until resumed..."
- activeProcess suspendWithState:#wait.
- ] ifCurtailed:[
- "interrupts are not blocked when entered through Processor>>#interruptActive"
- OperatingSystem blockInterrupts.
- timeoutBlock notNil ifTrue:[
- Processor removeTimedBlock:timeoutBlock.
- timeoutBlock := nil.
- ].
- self removeWaitingProcess:activeProcess.
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ].
+ "
+ for some more descriptive info in processMonitor ...
+ ... set the state to #wait (instead of #suspend)
+ "
+ [
+ "sleep until resumed..."
+ activeProcess suspendWithState:#wait.
+ ] ifCurtailed:[
+ "interrupts are not blocked when entered through Processor>>#interruptActive"
+ OperatingSystem blockInterrupts.
+ timeoutBlock notNil ifTrue:[
+ Processor removeTimedBlock:timeoutBlock.
+ timeoutBlock := nil.
+ ].
+ self removeWaitingProcess:activeProcess.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ].
- self removeWaitingProcess:activeProcess.
- timeoutOccured ifTrue:[
- wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
- ^ nil
- ].
+ self removeWaitingProcess:activeProcess.
+ timeoutOccured ifTrue:[
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ nil
+ ].
- count <= 0
- ] whileTrue.
+ count <= 0
+ ] whileTrue.
- timeoutBlock notNil ifTrue:[
- Processor removeTimedBlock:timeoutBlock.
- timeoutBlock := nil.
- ].
+ timeoutBlock notNil ifTrue:[
+ Processor removeTimedBlock:timeoutBlock.
+ timeoutBlock := nil.
+ ].
].
"if we come here, we have acquired the semaphore"
count := count - 1.
count == 0 ifTrue:[
- activeProcess isNil ifTrue:[activeProcess := Processor activeProcess].
- lastOwnerId := activeProcess id.
+ lastOwnerId := Processor activeProcessId.
].
wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
^ self
"Modified: / 13-12-1995 / 13:27:24 / stefan"
"Modified: / 11-08-2011 / 14:37:00 / cg"
+!
+
+waitWithTimeoutMs:milliSeconds state:waitStateSymbol
+ "wait for the semaphore, but abort the wait after some time.
+ return the receiver if the semaphore triggered normal, nil if we return
+ due to a timeout.
+ With zero timeout, this can be used to poll a semaphore (returning
+ the receiver if the semaphore is available, nil if not).
+ However, polling is not the intended use of semaphores, though.
+ If milliSeconds is nil, wait without timeout.
+
+ waitStateSymbol is the state the process is set to while waiting - normally #wait."
+
+ |activeProcess timeoutOccured wasBlocked timeoutBlock now endTime|
+
+ wasBlocked := OperatingSystem blockInterrupts.
+
+ count <= 0 ifTrue:[
+ "with zero-timeout, this is a poll"
+ milliSeconds == 0 ifTrue:[
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ nil
+ ].
+
+ activeProcess := Processor activeProcess.
+ timeoutOccured := false.
+
+ milliSeconds notNil ifTrue:[
+ "Wait with timeout: calculate the end-time"
+ now := OperatingSystem getMillisecondTime.
+ endTime := OperatingSystem millisecondTimeAdd:now and:milliSeconds.
+
+ timeoutBlock := [
+ timeoutOccured := true.
+ timeoutBlock:= nil.
+ Processor resume:activeProcess.
+ ].
+ Processor addTimedBlock:timeoutBlock for:activeProcess atMilliseconds:endTime.
+ ].
+
+ "
+ need a while-loop here, since more than one process may
+ wait for it and another one may also wake up.
+ Thus, the count is not always non-zero after returning from
+ suspend.
+ "
+ [
+ self addWaitingProcess:activeProcess.
+
+ "
+ for some more descriptive info in processMonitor ...
+ ... set the state to #wait (instead of #suspend)
+ "
+ [
+ "sleep until resumed..."
+ activeProcess suspendWithState:waitStateSymbol.
+ ] ifCurtailed:[
+ "interrupts are not blocked when entered through Processor>>#interruptActive"
+ OperatingSystem blockInterrupts.
+ timeoutBlock notNil ifTrue:[
+ Processor removeTimedBlock:timeoutBlock.
+ timeoutBlock := nil.
+ ].
+ self removeWaitingProcess:activeProcess.
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ].
+
+ self removeWaitingProcess:activeProcess.
+ timeoutOccured ifTrue:[
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ nil
+ ].
+
+ count <= 0
+ ] whileTrue.
+
+ timeoutBlock notNil ifTrue:[
+ Processor removeTimedBlock:timeoutBlock.
+ timeoutBlock := nil.
+ ].
+ ].
+
+ "if we come here, we have acquired the semaphore"
+ count := count - 1.
+ count == 0 ifTrue:[
+ lastOwnerId := Processor activeProcessId.
+ ].
+ wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
+ ^ self
! !
!Semaphore class methodsFor:'documentation'!
version
- ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.97 2014-06-24 17:10:33 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.98 2014-06-25 09:52:24 stefan Exp $'
!
version_CVS
- ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.97 2014-06-24 17:10:33 stefan Exp $'
+ ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.98 2014-06-25 09:52:24 stefan Exp $'
! !