ProcessorScheduler.st
changeset 20736 56ec188751e7
parent 20726 2736c31593ec
child 20745 2f29774fd342
equal deleted inserted replaced
20735:6dc31fd16564 20736:56ec188751e7
  1553 anyUserProcessAtAll
  1553 anyUserProcessAtAll
  1554     "return true, if there is any user process still running,
  1554     "return true, if there is any user process still running,
  1555      or waiting on a semaphore.
  1555      or waiting on a semaphore.
  1556      This is used to determine if we should stop scheduling
  1556      This is used to determine if we should stop scheduling
  1557      in standAlone applications.
  1557      in standAlone applications.
  1558      A user process has a non-zero processGroup."
  1558      A user process has a non-zero processGroup.
  1559 
  1559      Should be called with interrupts blocked."
  1560     |listArray l prio "{ Class: SmallInteger }"
  1560 
  1561      wasBlocked|
  1561     |listArray l prio "{ Class: SmallInteger }"|
  1562 
  1562 
  1563     prio := HighestPriority.
  1563     prio := HighestPriority.
  1564     wasBlocked := OperatingSystem blockInterrupts.
       
  1565 
  1564 
  1566     listArray := quiescentProcessLists.
  1565     listArray := quiescentProcessLists.
  1567 
  1566 
  1568     [prio >= 1] whileTrue:[
  1567     [prio >= 1] whileTrue:[
  1569 	l := listArray at:prio.
  1568         l := listArray at:prio.
  1570 	l notNil ifTrue:[
  1569         l notNil ifTrue:[
  1571 	    l linksDo:[:aProcess |
  1570             l linksDo:[:aProcess |
  1572 		aProcess isUserProcess ifTrue:[
  1571                 aProcess isUserProcess ifTrue:[
  1573 		    wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1572                     ^ true.
  1574 		    ^ true.
  1573                 ]
  1575 		]
  1574             ]
  1576 	    ]
  1575         ].
  1577 	].
  1576         prio := prio - 1
  1578 	prio := prio - 1
       
  1579     ].
  1577     ].
  1580 
  1578 
  1581     "/ any user process waiting on a sema?
  1579     "/ any user process waiting on a sema?
  1582     (readSemaphoreArray contains:[:sema |
  1580     (readSemaphoreArray contains:[:sema |
  1583 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1581         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1584     ) ifTrue:[
  1582     ) ifTrue:[
  1585 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1583         ^ true.
  1586 	^ true.
       
  1587     ].
  1584     ].
  1588     (writeSemaphoreArray contains:[:sema |
  1585     (writeSemaphoreArray contains:[:sema |
  1589 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1586         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1590     ) ifTrue:[
  1587     ) ifTrue:[
  1591 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1588         ^ true.
  1592 	^ true.
       
  1593     ].
  1589     ].
  1594     (timeoutSemaphoreArray contains:[:sema |
  1590     (timeoutSemaphoreArray contains:[:sema |
  1595 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1591         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1596     ) ifTrue:[
  1592     ) ifTrue:[
  1597 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1593         ^ true.
  1598 	^ true.
       
  1599     ].
  1594     ].
  1600     (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ]
  1595     (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ]
  1601     ) ifTrue:[
  1596     ) ifTrue:[
  1602 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1597         ^ true.
  1603 	^ true.
  1598     ].
  1604     ].
  1599 
  1605 
       
  1606     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
       
  1607     ^ false
  1600     ^ false
  1608 
  1601 
  1609     "
  1602     "
  1610      Processor anyUserProcessAtAll
  1603      Processor anyUserProcessAtAll
  1611     "
  1604     "
  2017 
  2010 
  2018     |pri id l wasBlocked|
  2011     |pri id l wasBlocked|
  2019 
  2012 
  2020     aProcess isNil ifTrue:[^ self].
  2013     aProcess isNil ifTrue:[^ self].
  2021 
  2014 
  2022 'terminate: ' errorPrint. aProcess errorPrintCR.
       
  2023     aProcess == scheduler ifTrue:[
  2015     aProcess == scheduler ifTrue:[
  2024         InvalidProcessSignal raiseWith:aProcess errorString:'attempt to terminate scheduler'.
  2016         InvalidProcessSignal raiseWith:aProcess errorString:'attempt to terminate scheduler'.
  2025         ^ self
  2017         ^ self
  2026     ].
  2018     ].
  2027 
  2019 
  2028     wasBlocked := OperatingSystem blockInterrupts.
  2020     wasBlocked := OperatingSystem blockInterrupts.
  2029 
  2021 
  2030     id := aProcess id.
  2022     id := aProcess id.
  2031     id isNil ifTrue:[   "already dead"
  2023     id isNil ifTrue:[   "already dead"
       
  2024         self checkForEndOfDispatch.
  2032         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2025         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2033         self checkForEndOfDispatch.
       
  2034         ^ self
  2026         ^ self
  2035     ].
  2027     ].
  2036 
  2028 
  2037     aProcess setId:nil state:#dead.
  2029     aProcess setId:nil state:#dead.
  2038 
  2030 
  2060         ].
  2052         ].
  2061 
  2053 
  2062         self unRemember:aProcess.
  2054         self unRemember:aProcess.
  2063         zombie := id.
  2055         zombie := id.
  2064 
  2056 
       
  2057         self checkForEndOfDispatch.
  2065         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2058         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2066 'checking2' errorPrintCR.
       
  2067         self checkForEndOfDispatch.
       
  2068         self threadSwitch:scheduler.
  2059         self threadSwitch:scheduler.
  2069         "not reached"
  2060         "not reached"
  2070         ^ self
  2061         ^ self
  2071     ].
  2062     ].
  2072 
  2063 
  2073     self unRemember:aProcess.
  2064     self unRemember:aProcess.
  2074     self class threadDestroy:id.
  2065     self class threadDestroy:id.
  2075 
  2066 
       
  2067     self checkForEndOfDispatch.
  2076     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2068     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2077 'checking3' errorPrintCR.
       
  2078     self checkForEndOfDispatch.
       
  2079 
  2069 
  2080     "Modified: / 23-09-1996 / 13:50:24 / stefan"
  2070     "Modified: / 23-09-1996 / 13:50:24 / stefan"
  2081     "Modified: / 20-03-1997 / 16:03:39 / cg"
  2071     "Modified: / 20-03-1997 / 16:03:39 / cg"
  2082     "Modified (comment): / 10-08-2011 / 19:57:08 / cg"
  2072     "Modified (comment): / 10-08-2011 / 19:57:08 / cg"
  2083 !
  2073 !
  2920 
  2910 
  2921     "Modified: 23.9.1996 / 14:34:18 / cg"
  2911     "Modified: 23.9.1996 / 14:34:18 / cg"
  2922 !
  2912 !
  2923 
  2913 
  2924 addTimedBlock:aBlock for:aProcess atMilliseconds:aMillisecondTime
  2914 addTimedBlock:aBlock for:aProcess atMilliseconds:aMillisecondTime
  2925     "add the argument, aBlock to the list of time-scheduled-blocks; to be
  2915     "add the argument, aBlock to the list of time-scheduled-blocks; 
  2926      evaluated by aProcess when the millisecondClock value passes
  2916      to be evaluated by aProcess when the millisecondClock value passes
  2927      aMillisecondTime.
  2917      aMillisecondTime.
  2928      If that block is already in the timeout list,
  2918      If that block is already in the timeout list, its trigger-time is changed.
  2929      its trigger-time is changed.
  2919      The process specified by the argument, aProcess 
  2930      The process specified by the argument, aProcess will be interrupted
  2920      will be interrupted for execution of the block.
  2931      for execution of the block.
       
  2932      If aProcess is nil, the block will be evaluated by the scheduler itself
  2921      If aProcess is nil, the block will be evaluated by the scheduler itself
  2933      (which is dangerous - the block should not raise any error conditions).
  2922      (which is dangerous: the block should not raise any error conditions).
  2934      If the process is active at trigger time, the interrupt will occur in
  2923      If the process is active at trigger time, the interrupt will occur in
  2935      whatever method it is executing; if suspended at trigger time, it will be
  2924      whatever method it is executing; 
  2936      resumed.
  2925      if suspended at trigger time, it will be resumed.
  2937      The block will be removed from the timed-block list after evaluation
  2926      The block will be removed from the timed-block list after evaluation
  2938      (i.e. it will trigger only once).
  2927      (i.e. it will trigger only once).
  2939      Returns an ID, which can be used in #removeTimeoutWidthID:"
  2928      Returns an ID, which can be used in #removeTimeoutWidthID:"
  2940 
  2929 
  2941     |index "{ Class: SmallInteger }"
  2930     |index "{ Class: SmallInteger }"
  2942      wasBlocked|
  2931      wasBlocked|
  2943 
  2932 
  2944     wasBlocked := OperatingSystem blockInterrupts.
  2933     wasBlocked := OperatingSystem blockInterrupts.
  2945     index := timeoutActionArray identityIndexOf:aBlock startingAt:1.
  2934     index := timeoutActionArray identityIndexOf:aBlock startingAt:1.
  2946     index ~~ 0 ifTrue:[
  2935     index ~~ 0 ifTrue:[
  2947 	timeoutArray at:index put:aMillisecondTime
  2936         timeoutArray at:index put:aMillisecondTime
  2948     ] ifFalse:[
  2937     ] ifFalse:[
  2949 	index := timeoutArray indexOf:nil.
  2938         index := timeoutArray indexOf:nil.
  2950 	index ~~ 0 ifTrue:[
  2939         index ~~ 0 ifTrue:[
  2951 	    timeoutArray at:index put:aMillisecondTime.
  2940             timeoutArray at:index put:aMillisecondTime.
  2952 	    timeoutActionArray at:index put:aBlock.
  2941             timeoutActionArray at:index put:aBlock.
  2953 	    timeoutSemaphoreArray at:index put:nil.
  2942             timeoutSemaphoreArray at:index put:nil.
  2954 	    timeoutProcessArray at:index put:aProcess
  2943             timeoutProcessArray at:index put:aProcess
  2955 	] ifFalse:[
  2944         ] ifFalse:[
  2956 	    timeoutArray := timeoutArray copyWith:aMillisecondTime.
  2945             timeoutArray := timeoutArray copyWith:aMillisecondTime.
  2957 	    timeoutActionArray := timeoutActionArray copyWith:aBlock.
  2946             timeoutActionArray := timeoutActionArray copyWith:aBlock.
  2958 	    timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:nil.
  2947             timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:nil.
  2959 	    timeoutProcessArray := timeoutProcessArray copyWith:aProcess.
  2948             timeoutProcessArray := timeoutProcessArray copyWith:aProcess.
  2960 	    index := timeoutArray size.
  2949             index := timeoutArray size.
  2961 	].
  2950         ].
  2962     ].
  2951     ].
  2963 
  2952 
  2964     anyTimeouts := true.
  2953     anyTimeouts := true.
  2965     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2954     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2966     ^ index
  2955     ^ index
  3045     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3034     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3046 
  3035 
  3047     now := OperatingSystem getMillisecondTime.
  3036     now := OperatingSystem getMillisecondTime.
  3048     n := timeoutArray size.
  3037     n := timeoutArray size.
  3049     1 to:n do:[:index |
  3038     1 to:n do:[:index |
  3050 	aTime := timeoutArray at:index.
  3039         aTime := timeoutArray at:index.
  3051 	aTime notNil ifTrue:[
  3040         aTime notNil ifTrue:[
  3052 	    (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[
  3041             (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[
  3053 		"this one should be triggered"
  3042                 "this one should be triggered"
  3054 
  3043 
  3055 		sema := timeoutSemaphoreArray at:index.
  3044                 sema := timeoutSemaphoreArray at:index.
  3056 		sema notNil ifTrue:[
  3045                 sema notNil ifTrue:[
  3057 		    timeoutSemaphoreArray at:index put:nil.
  3046                     timeoutSemaphoreArray at:index put:nil.
  3058 		    timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3047                     timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3059 		    sema signalOnce.
  3048                     sema signalOnce.
  3060 		] ifFalse:[
  3049                 ] ifFalse:[
  3061 		    "to support pure-events"
  3050                     "to support pure-events"
  3062 		    block := timeoutActionArray at:index.
  3051                     block := timeoutActionArray at:index.
  3063 		    block notNil ifTrue:[
  3052                     block notNil ifTrue:[
  3064 			"/ usually (>99%), there is only one single timeout action to call;
  3053                         "/ usually (>99%), there is only one single timeout action to call;
  3065 			"/ avoid creation of an OrderedCollection
  3054                         "/ avoid creation of an OrderedCollection
  3066 			firstBlockToEvaluate isNil ifTrue:[
  3055                         firstBlockToEvaluate isNil ifTrue:[
  3067 			    firstBlockToEvaluate := block.
  3056                             firstBlockToEvaluate := block.
  3068 			    firstProcess := timeoutProcessArray at:index.
  3057                             firstProcess := timeoutProcessArray at:index.
  3069 			] ifFalse:[
  3058                         ] ifFalse:[
  3070 			    blocksAndProcessesToEvaluate isNil ifTrue:[
  3059                             blocksAndProcessesToEvaluate isNil ifTrue:[
  3071 				blocksAndProcessesToEvaluate := OrderedCollection
  3060                                 blocksAndProcessesToEvaluate := OrderedCollection
  3072 								    with:firstBlockToEvaluate
  3061                                                                     with:firstBlockToEvaluate
  3073 								    with:firstProcess.
  3062                                                                     with:firstProcess.
  3074 			    ].
  3063                             ].
  3075 			    blocksAndProcessesToEvaluate add:block.
  3064                             blocksAndProcessesToEvaluate add:block.
  3076 			    blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index).
  3065                             blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index).
  3077 			].
  3066                         ].
  3078 			timeoutActionArray at:index put:nil.
  3067                         timeoutActionArray at:index put:nil.
  3079 			timeoutProcessArray at:index put:nil.
  3068                         timeoutProcessArray at:index put:nil.
  3080 		    ]
  3069                     ]
  3081 		].
  3070                 ].
  3082 		timeoutArray at:index put:nil.
  3071                 timeoutArray at:index put:nil.
  3083 	    ] ifFalse:[
  3072             ] ifFalse:[
  3084 		"there are still pending timeouts"
  3073                 "there are still pending timeouts"
  3085 		anyTimeouts := true.
  3074                 anyTimeouts := true.
  3086 		indexOfLastTimeout := index.
  3075                 indexOfLastTimeout := index.
  3087 	    ]
  3076             ]
  3088 	]
  3077         ]
  3089     ].
  3078     ].
  3090 
  3079 
  3091     "shrink the arrays, if they are 50% free"
  3080     "shrink the arrays, if they are 50% free"
  3092     n > 20 ifTrue:[
  3081     n > 20 ifTrue:[
  3093 	halfSize := n // 2.
  3082         halfSize := n // 2.
  3094 	(indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[
  3083         (indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[
  3095 	    wasBlocked := OperatingSystem blockInterrupts.
  3084             wasBlocked := OperatingSystem blockInterrupts.
  3096 	    (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[   "/ no new timeouts arrived
  3085             (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[   "/ no new timeouts arrived
  3097 		timeoutArray := timeoutArray copyTo:halfSize.
  3086                 timeoutArray := timeoutArray copyTo:halfSize.
  3098 		timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3087                 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3099 		timeoutActionArray := timeoutActionArray copyTo:halfSize.
  3088                 timeoutActionArray := timeoutActionArray copyTo:halfSize.
  3100 		timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
  3089                 timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
  3101 	    ].
  3090             ].
  3102 	    wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
  3091             wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
  3103 	].
  3092         ].
  3104     ].
  3093     ].
  3105 
  3094 
  3106     "/ usually (>99%), there is only one single timeout action to call;
  3095     "/ usually (>99%), there is only one single timeout action to call;
  3107     "/ above code avoided the creation of an OrderedCollection
  3096     "/ above code avoided the creation of an OrderedCollection
  3108     blocksAndProcessesToEvaluate isNil ifTrue:[
  3097     blocksAndProcessesToEvaluate isNil ifTrue:[
  3109 	firstBlockToEvaluate notNil ifTrue:[
  3098         firstBlockToEvaluate notNil ifTrue:[
  3110 	    timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3099             timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3111 	    (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3100             (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3112 		firstBlockToEvaluate value
  3101                 firstBlockToEvaluate value
  3113 	    ] ifFalse:[
  3102             ] ifFalse:[
  3114 		firstProcess isDead ifTrue:[
  3103                 firstProcess isDead ifTrue:[
  3115 		    "/ a timedBlock for a process which has already terminated
  3104                     "/ a timedBlock for a process which has already terminated
  3116 		    "/ issue a warning and do not execute it.
  3105                     "/ issue a warning and do not execute it.
  3117 		    "/ (exeuting here may be dangerous, since it would run at scheduler priority here,
  3106                     "/ (executing here may be dangerous, since it would run at scheduler priority here,
  3118 		    "/  and thereby could block the whole smalltalk system.
  3107                     "/  and thereby could block the whole smalltalk system.
  3119 		    "/  For this reason is it IGNORED here.)
  3108                     "/  For this reason is it IGNORED here.)
  3120 "/ Could handle it in timeoutProcess, but we don't,
  3109 
  3121 "/ because otherwise timeouts might be reissued forever...
  3110                     "/ Could handle it in timeoutProcess, but we don't,
  3122 "/                    (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3111                     "/ because otherwise timeouts might be reissued forever...
  3123 "/                        timeoutHandlerProcess interruptWith:block.
  3112                     "/      (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3124 "/                    ] ifFalse:[
  3113                     "/          timeoutHandlerProcess interruptWith:block.
  3125 			('ProcessorScheduler [warning]: cannot evaluate timedBlock (', firstBlockToEvaluate displayString, ') for dead process: ''' , firstProcess name , '''') infoPrintCR.
  3114                     "/      ] ifFalse:[
  3126 "/                    ].
  3115                         ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', firstBlockToEvaluate displayString, ') for dead process: ''' , firstProcess name , '''') infoPrintCR.
  3127 		] ifFalse:[
  3116                     "/      ].
  3128 		    firstProcess interruptWith:firstBlockToEvaluate
  3117                 ] ifFalse:[
  3129 		]
  3118                     firstProcess interruptWith:firstBlockToEvaluate
  3130 	    ]
  3119                 ]
  3131 	].
  3120             ]
       
  3121         ].
  3132     ] ifFalse:[
  3122     ] ifFalse:[
  3133 	n := blocksAndProcessesToEvaluate size.
  3123         n := blocksAndProcessesToEvaluate size.
  3134 	1 to:n by:2 do:[:index |
  3124         1 to:n by:2 do:[:index |
  3135 	    block := blocksAndProcessesToEvaluate at:index.
  3125             block := blocksAndProcessesToEvaluate at:index.
  3136 	    p := blocksAndProcessesToEvaluate at:index+1.
  3126             p := blocksAndProcessesToEvaluate at:index+1.
  3137 	    (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[
  3127             (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[
  3138 		block value.
  3128                 block value.
  3139 		timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3129                 timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3140 	    ] ifFalse:[
  3130             ] ifFalse:[
  3141 		p isDead ifTrue:[
  3131                 p isDead ifTrue:[
  3142 		    "/ a timedBlock for a process which has already terminated
  3132                     "/ a timedBlock for a process which has already terminated
  3143 		    "/ issue a warning and do not execute it.
  3133                     "/ issue a warning and do not execute it.
  3144 		    "/ (exeuting here may be dangerous, since it would run at scheduler priority here,
  3134                     "/ (executing here may be dangerous, since it would run at scheduler priority here,
  3145 		    "/  and thereby could block the whole smalltalk system.
  3135                     "/  and thereby could block the whole smalltalk system.
  3146 		    "/  For this reason is it IGNORED here.)
  3136                     "/  For this reason is it IGNORED here.)
  3147 "/ Could handle it in timeoutProcess, but we don't,
  3137 
  3148 "/ because otherwise timeouts might be reissued forever...
  3138                     "/ Could handle it in timeoutProcess, but we don't,
  3149 "/                    (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3139                     "/ because otherwise timeouts might be reissued forever...
  3150 "/                        timeoutHandlerProcess interruptWith:block.
  3140                     "/      (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3151 "/                    ] ifFalse:[
  3141                     "/          timeoutHandlerProcess interruptWith:block.
  3152 			('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , p name , '''') infoPrintCR.
  3142                     "/      ] ifFalse:[
  3153 "/                    ].
  3143                         ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , p name , '''') infoPrintCR.
  3154 		] ifFalse:[
  3144                     "/      ].
  3155 		    timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3145                 ] ifFalse:[
  3156 		    p interruptWith:block
  3146                     timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3157 		]
  3147                     p interruptWith:block
  3158 	    ]
  3148                 ]
  3159 	]
  3149             ]
       
  3150         ]
  3160     ].
  3151     ].
  3161 
  3152 
  3162     "Modified: / 30-07-2013 / 19:33:24 / cg"
  3153     "Modified: / 30-07-2013 / 19:33:24 / cg"
  3163 !
  3154 !
  3164 
  3155 
  3189      wasBlocked|
  3180      wasBlocked|
  3190 
  3181 
  3191     wasBlocked := OperatingSystem blockInterrupts.
  3182     wasBlocked := OperatingSystem blockInterrupts.
  3192 
  3183 
  3193     index := 0.
  3184     index := 0.
  3194     [index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:index+1.
  3185     [
  3195      index ~~ 0] whileTrue:[
  3186         index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:index+1.
  3196 	timeoutArray at:index put:nil.
  3187         index ~~ 0
  3197 	timeoutSemaphoreArray at:index put:nil.
  3188     ] whileTrue:[
  3198 	timeoutActionArray at:index put:nil.
  3189         timeoutArray at:index put:nil.
  3199 	timeoutProcessArray at:index put:nil.
  3190         timeoutSemaphoreArray at:index put:nil.
       
  3191         timeoutActionArray at:index put:nil.
       
  3192         timeoutProcessArray at:index put:nil.
  3200     ].
  3193     ].
  3201 
  3194 
  3202     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3195     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3203 !
  3196 !
  3204 
  3197 
  3326 ! !
  3319 ! !
  3327 
  3320 
  3328 !ProcessorScheduler methodsFor:'waiting'!
  3321 !ProcessorScheduler methodsFor:'waiting'!
  3329 
  3322 
  3330 checkForEndOfDispatch
  3323 checkForEndOfDispatch
       
  3324     |wasBlocked|
       
  3325     
  3331     exitWhenNoMoreUserProcesses ifTrue:[
  3326     exitWhenNoMoreUserProcesses ifTrue:[
  3332         "/ check if there are any processes at all
  3327         "/ check if there are any processes at all
  3333         "/ stop dispatching if there is none
  3328         "/ stop dispatching if there is none
  3334         "/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3329         "/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3335         "/ and no readSemaphores are present (which means that noone is waiting for input)
  3330         "/ and no readSemaphores are present (which means that noone is waiting for input)
  3336         "/ and no writeSemaphores are present
  3331         "/ and no writeSemaphores are present
  3337         self noMoreUserProcesses ifTrue:[
  3332         wasBlocked := OperatingSystem blockInterrupts.
  3338 'end of dispatch' errorPrintCR.
  3333 
       
  3334         self anyUserProcessAtAll ifFalse:[
       
  3335             'end of dispatch' errorPrintCR.
  3339             dispatching := false.
  3336             dispatching := false.
  3340             ^ self
       
  3341         ].
  3337         ].
       
  3338         
       
  3339         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3342     ].
  3340     ].
  3343 !
  3341 !
  3344 
  3342 
  3345 checkForIOWithTimeout:millis
  3343 checkForIOWithTimeout:millis
  3346     "this is called, when there is absolutely nothing to do;
  3344     "this is called, when there is absolutely nothing to do;
  3534 
  3532 
  3535     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3533     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3536     "Modified: 4.8.1997 / 14:23:08 / cg"
  3534     "Modified: 4.8.1997 / 14:23:08 / cg"
  3537 !
  3535 !
  3538 
  3536 
  3539 noMoreUserProcesses
       
  3540     "/ check if there are any processes at all
       
  3541     "/ stop dispatching if there is none
       
  3542     "/ (and anyTimeouts is false, which means that no timeout blocks are present)
       
  3543     "/ and no readSemaphores are present (which means that noone is waiting for input)
       
  3544     "/ and no writeSemaphores are present
       
  3545 
       
  3546     anyTimeouts ifFalse:[
       
  3547         ^ self anyUserProcessAtAll not.
       
  3548     ].
       
  3549     ^ false
       
  3550 "/    |anySema|
       
  3551 "/
       
  3552 "/
       
  3553 "/    anyTimeouts ifFalse:[
       
  3554 "/        anySema := (readSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0.
       
  3555 "/        anySema ifFalse:[
       
  3556 "/            anySema := (writeSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0.
       
  3557 "/            anySema ifFalse:[
       
  3558 "/                self anyUserProcessAtAll ifFalse:[
       
  3559 "/                    ^ true
       
  3560 "/                ]
       
  3561 "/            ].
       
  3562 "/        ].
       
  3563 "/    ].
       
  3564 "/    ^ false
       
  3565 
       
  3566     "
       
  3567      Processor noMoreUserProcesses
       
  3568     "
       
  3569 !
       
  3570 
       
  3571 removeCorruptedFds
  3537 removeCorruptedFds
  3572     "this is sent when select returns an error due to some invalid
  3538     "this is sent when select returns an error due to some invalid
  3573      fileDescriptor. May happen, if someone does a readWait/writeWait on a
  3539      fileDescriptor. May happen, if someone does a readWait/writeWait on a
  3574      socket connection, which somehow got corrupted
  3540      socket connection, which somehow got corrupted
  3575      (shutdown by partner, or closed by another thread, while being in a read/write-wait).
  3541      (shutdown by partner, or closed by another thread, while being in a read/write-wait).