Semaphore.st
branchjv
changeset 18084 ab5b38bd8f81
parent 18079 7b5afc0ad3d5
parent 15635 1b42005ee234
child 18091 abbcac10730e
equal deleted inserted replaced
18083:5558dc303721 18084:ab5b38bd8f81
   440     "remove all waiting processes from the list of waiting processes
   440     "remove all waiting processes from the list of waiting processes
   441      and resume them. 
   441      and resume them. 
   442      NOTE: Must be called when known that waitingProcesses is nonNil and
   442      NOTE: Must be called when known that waitingProcesses is nonNil and
   443            also with blocked interrupts"
   443            also with blocked interrupts"
   444 
   444 
   445     |processes anyDead currentPriority needsReschedule|
   445     |processes anyDead needsReschedule|
   446 
   446 
   447     processes := waitingProcesses.
   447     processes := waitingProcesses.
   448 "/ do not set to nil - a waiting process may be suspended and will not be resumed...
   448 "/ do not set to nil - a waiting process may be suspended and will not be resumed by #makeRunnable: ...
   449 "/    waitingProcesses := nil.
   449 "/    waitingProcesses := nil.
   450 
   450 
   451     currentPriority := Processor currentPriority.
       
   452     needsReschedule := false.
   451     needsReschedule := false.
   453     anyDead := false.
   452     anyDead := false.
   454     processes do:[:eachProcess | 
   453     processes do:[:eachProcess | 
   455         (eachProcess isNil or:[eachProcess isDead]) ifTrue:[
   454         (Processor makeRunnable:eachProcess) ifTrue:[
   456             Transcript show:'oops: a dead process: '; showCR:eachProcess.
   455             needsReschedule := true.
   457             anyDead := true.
       
   458         ] ifFalse:[
   456         ] ifFalse:[
   459             (Processor makeRunnable:eachProcess) ifTrue:[
   457             "if process is nil or dead (or for other reasons) makeRunnable returns false.
   460                 needsReschedule := true.
   458              So check here."
       
   459             (eachProcess isNil or:[eachProcess isDead]) ifTrue:[
       
   460                 "printing to Transcript might not be a good idea while interrupts are blocked"
       
   461                 'Semaphore>>wakeupWaiters: removing a dead process: ' infoPrint. eachProcess infoPrintCR.
       
   462                 anyDead := true.
   461             ].
   463             ].
   462         ]
   464         ].
   463     ].
   465     ].
   464     anyDead ifTrue:[
   466     anyDead ifTrue:[
   465         "interrupts are already blocked by sender"
   467         "interrupts are already blocked by sender"
   466         waitingProcesses := processes reject:[:p | p isNil or:[p isDead]]
   468         waitingProcesses := processes reject:[:p | p isNil or:[p isDead]]
   467     ].
   469     ].
   582 
   584 
   583     needsReschedule := false.
   585     needsReschedule := false.
   584     wasBlocked := OperatingSystem blockInterrupts.
   586     wasBlocked := OperatingSystem blockInterrupts.
   585     [
   587     [
   586         count := count + 1.
   588         count := count + 1.
   587         waitingProcesses notNil ifTrue:[
   589         waitingProcesses size ~~ 0 ifTrue:[
   588             needsReschedule := self wakeupWaiters.
   590             needsReschedule := self wakeupWaiters.
   589         ].
   591         ].
   590     ] ensure:[
   592     ] ensure:[
   591         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   593         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   592     ].
   594     ].
   603      This can be used for process synchronization, if multiple processes are
   605      This can be used for process synchronization, if multiple processes are
   604      waiting for a common event."
   606      waiting for a common event."
   605 
   607 
   606     |wasBlocked needsReschedule|
   608     |wasBlocked needsReschedule|
   607 
   609 
   608     waitingProcesses notNil ifTrue:[
   610     waitingProcesses size ~~ 0 ifTrue:[
   609         needsReschedule := false.
   611         needsReschedule := false.
   610         wasBlocked := OperatingSystem blockInterrupts.
   612         wasBlocked := OperatingSystem blockInterrupts.
   611         [
   613         [
   612             "first, make them all runnable, but do not schedule
   614             "first, make them all runnable, but do not schedule
   613              (in case one has higher prio and goes into a wait immediately again.)"
   615              (in case one has higher prio and goes into a wait immediately again.)"
   661         "/ check again - now interrupts are blocked.
   663         "/ check again - now interrupts are blocked.
   662         [
   664         [
   663             count <= 0 ifTrue:[
   665             count <= 0 ifTrue:[
   664                 count := count + 1.
   666                 count := count + 1.
   665                 count == 1 ifTrue:[
   667                 count == 1 ifTrue:[
   666                     waitingProcesses notNil ifTrue:[
   668                     waitingProcesses size ~~ 0 ifTrue:[
   667                         needsReschedule := self wakeupWaiters.
   669                         needsReschedule := self wakeupWaiters.
   668                     ].
   670                     ].
   669                 ].
   671                 ].
   670             ].
   672             ].
   671         ] ensure:[
   673         ] ensure:[
   743 
   745 
   744         OperatingSystem blockInterrupts.
   746         OperatingSystem blockInterrupts.
   745         needsReschedule := false.
   747         needsReschedule := false.
   746         [
   748         [
   747             count := count + 1.
   749             count := count + 1.
   748             waitingProcesses notNil ifTrue:[
   750             waitingProcesses size ~~ 0 ifTrue:[
   749                 needsReschedule := self wakeupWaiters.
   751                 needsReschedule := self wakeupWaiters.
   750             ].
   752             ].
   751         ] ensure:[
   753         ] ensure:[
   752             wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   754             wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   753         ].
   755         ].
   811 
   813 
   812     wasBlocked := OperatingSystem blockInterrupts.
   814     wasBlocked := OperatingSystem blockInterrupts.
   813 
   815 
   814     count <= 0 ifTrue:[
   816     count <= 0 ifTrue:[
   815         activeProcess := Processor activeProcess.
   817         activeProcess := Processor activeProcess.
   816 
       
   817         "
   818         "
   818          need a while-loop here, since more than one process may
   819          need a while-loop here, since more than one process may
   819          wait for it and another one may also wake up.
   820          wait for it and another one may also wake up.
   820          Thus, the count is not always non-zero after returning from
   821          Thus, the count is not always non-zero after returning from
   821          suspend.
   822          suspend.
   838         ] doUntil:[count > 0].
   839         ] doUntil:[count > 0].
   839     ].
   840     ].
   840 
   841 
   841     count := count - 1.
   842     count := count - 1.
   842     count == 0 ifTrue:[
   843     count == 0 ifTrue:[
   843         lastOwner := Processor activeProcess.
   844         activeProcess isNil ifTrue:[activeProcess := Processor activeProcess].
       
   845         lastOwner := activeProcess.
   844     ].
   846     ].
   845     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   847     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   846 
   848 
   847     "Modified: / 13-12-1995 / 13:26:33 / stefan"
   849     "Modified: / 13-12-1995 / 13:26:33 / stefan"
   848     "Modified: / 11-08-2011 / 14:36:43 / cg"
   850     "Modified: / 11-08-2011 / 14:36:43 / cg"
   855     |activeProcess wasBlocked|
   857     |activeProcess wasBlocked|
   856 
   858 
   857     count > 0 ifTrue:[
   859     count > 0 ifTrue:[
   858         ^ self
   860         ^ self
   859     ].
   861     ].
   860 
       
   861     activeProcess := Processor activeProcess.
   862     activeProcess := Processor activeProcess.
   862 
   863 
   863     wasBlocked := OperatingSystem blockInterrupts.
   864     wasBlocked := OperatingSystem blockInterrupts.
   864     "
   865     "
   865      need a while-loop here, since more than one process may
   866      need a while-loop here, since more than one process may
   981             Processor removeTimedBlock:timeoutBlock.
   982             Processor removeTimedBlock:timeoutBlock.
   982             timeoutBlock := nil.
   983             timeoutBlock := nil.
   983         ].
   984         ].
   984     ].
   985     ].
   985 
   986 
   986     "if we come here, we have accquired the semaphore"
   987     "if we come here, we have acquired the semaphore"
   987     count := count - 1.
   988     count := count - 1.
   988     count == 0 ifTrue:[
   989     count == 0 ifTrue:[
   989         lastOwner := Processor activeProcess.
   990         activeProcess isNil ifTrue:[activeProcess := Processor activeProcess].
       
   991         lastOwner := activeProcess.
   990     ].
   992     ].
   991     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   993     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   992     ^ self
   994     ^ self
   993 
   995 
   994     "Modified: / 13-12-1995 / 13:27:24 / stefan"
   996     "Modified: / 13-12-1995 / 13:27:24 / stefan"
   996 ! !
   998 ! !
   997 
   999 
   998 !Semaphore class methodsFor:'documentation'!
  1000 !Semaphore class methodsFor:'documentation'!
   999 
  1001 
  1000 version
  1002 version
  1001     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.93 2013-07-25 09:22:14 cg Exp $'
  1003     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.94 2013-08-16 17:51:57 stefan Exp $'
  1002 !
  1004 !
  1003 
  1005 
  1004 version_CVS
  1006 version_CVS
  1005     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.93 2013-07-25 09:22:14 cg Exp $'
  1007     ^ '$Header: /cvs/stx/stx/libbasic/Semaphore.st,v 1.94 2013-08-16 17:51:57 stefan Exp $'
  1006 ! !
  1008 ! !
  1007 
  1009