772 "/ this safes a bit of memory allocation in the scheduler) |
772 "/ this safes a bit of memory allocation in the scheduler) |
773 |
773 |
774 dispatchAction := [self dispatch]. |
774 dispatchAction := [self dispatch]. |
775 |
775 |
776 handlerAction := [:ex | |
776 handlerAction := [:ex | |
777 ('Processor [info]: ignored signal (', ex signal printString, ')') infoPrintCR. |
777 ('Processor [info]: ignored signal (', ex signal printString, ')') infoPrintCR. |
778 ex return |
778 ex return |
779 ]. |
779 ]. |
780 |
780 |
781 ignoredSignals := SignalSet |
781 ignoredSignals := SignalSet |
782 with:TerminateProcessRequest |
782 with:TerminateProcessRequest |
783 with:AbortSignal. |
783 with:AbortSignal. |
784 |
784 |
785 "/ |
785 "/ |
786 "/ I made this an extra call to dispatch; this allows recompilation |
786 "/ I made this an extra call to dispatch; this allows recompilation |
787 "/ of the dispatch-handling code in the running system. |
787 "/ of the dispatch-handling code in the running system. |
788 "/ |
788 "/ |
789 [dispatching] whileTrue:[ |
789 [dispatching] whileTrue:[ |
790 ignoredSignals handle:handlerAction do:dispatchAction |
790 ignoredSignals handle:handlerAction do:dispatchAction |
791 ]. |
791 ]. |
792 |
792 |
793 "/ we arrive here in standalone Apps, |
793 "/ we arrive here in standalone Apps, |
794 "/ when the last process at or above UserSchedulingPriority process died. |
794 "/ when the last process at or above UserSchedulingPriority process died. |
795 "/ regular ST/X stays in above loop forever |
795 "/ regular ST/X stays in above loop forever |
842 timeoutProcessArray := Array new:5. |
842 timeoutProcessArray := Array new:5. |
843 |
843 |
844 anyTimeouts := false. |
844 anyTimeouts := false. |
845 dispatching := false. |
845 dispatching := false. |
846 exitWhenNoMoreUserProcesses isNil ifTrue:[ |
846 exitWhenNoMoreUserProcesses isNil ifTrue:[ |
847 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
847 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
848 ]. |
848 ]. |
849 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
849 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
850 gotIOInterrupt := false. |
850 gotIOInterrupt := false. |
851 osChildExitActions := Dictionary new. |
851 osChildExitActions := Dictionary new. |
852 gotChildSignalInterrupt := false. |
852 gotChildSignalInterrupt := false. |
989 This is only used with win32's native threads." |
989 This is only used with win32's native threads." |
990 |
990 |
991 |index pri aProcess l| |
991 |index pri aProcess l| |
992 |
992 |
993 OperatingSystem interruptsBlocked ifFalse:[ |
993 OperatingSystem interruptsBlocked ifFalse:[ |
994 MiniDebugger |
994 MiniDebugger |
995 enterWithMessage:'resumeImmediateInterrupt with no interruptsBlocked' |
995 enterWithMessage:'resumeImmediateInterrupt with no interruptsBlocked' |
996 mayProceed:true. |
996 mayProceed:true. |
997 ]. |
997 ]. |
998 index := KnownProcessIds identityIndexOf:id. |
998 index := KnownProcessIds identityIndexOf:id. |
999 index ~~ 0 ifTrue:[ |
999 index ~~ 0 ifTrue:[ |
1000 aProcess := KnownProcesses at:index. |
1000 aProcess := KnownProcesses at:index. |
1001 "/ |
1001 "/ |
1002 "/ CG: the situation below may happen, if the wrapCall |
1002 "/ CG: the situation below may happen, if the wrapCall |
1003 "/ finishes before the process was layed to sleep |
1003 "/ finishes before the process was layed to sleep |
1004 "/ (i.e. schedulerIRQ arrives before the threadSwitch |
1004 "/ (i.e. schedulerIRQ arrives before the threadSwitch |
1005 "/ was finished. |
1005 "/ was finished. |
1006 "/ In that case, simply resume it and everything is OK. |
1006 "/ In that case, simply resume it and everything is OK. |
1007 "/ |
1007 "/ |
1008 "/ aProcess state ~~ #wrapWait ifTrue:[ |
1008 "/ aProcess state ~~ #wrapWait ifTrue:[ |
1009 "/ 'ProcSched [info]: oops - resumeImmIRQ for non wrapWait process' infoPrintCR. |
1009 "/ 'ProcSched [info]: oops - resumeImmIRQ for non wrapWait process' infoPrintCR. |
1010 "/ ^ self |
1010 "/ ^ self |
1011 "/ ]. |
1011 "/ ]. |
1012 pri := aProcess priority. |
1012 pri := aProcess priority. |
1013 l := quiescentProcessLists at:pri. |
1013 l := quiescentProcessLists at:pri. |
1014 "if already running, ignore" |
1014 "if already running, ignore" |
1015 l notNil ifTrue:[ |
1015 l notNil ifTrue:[ |
1016 (l identityIndexOf:aProcess) ~~ 0 ifTrue:[ |
1016 (l identityIndexOf:aProcess) ~~ 0 ifTrue:[ |
1017 'ProcSched [info]: oops - resumeIRQ for already running process' infoPrintCR. |
1017 'ProcSched [info]: oops - resumeIRQ for already running process' infoPrintCR. |
1018 ^ self |
1018 ^ self |
1019 ] |
1019 ] |
1020 ] ifFalse:[ |
1020 ] ifFalse:[ |
1021 l := LinkedList new. |
1021 l := LinkedList new. |
1022 quiescentProcessLists at:pri put:l. |
1022 quiescentProcessLists at:pri put:l. |
1023 ]. |
1023 ]. |
1024 l addLast:aProcess. |
1024 l addLast:aProcess. |
1025 aProcess state:#run. |
1025 aProcess state:#run. |
1026 ] ifFalse:[ |
1026 ] ifFalse:[ |
1027 'ProcSched [info]: oops - resumeIRQ for unknown process: ' infoPrint. |
1027 'ProcSched [info]: oops - resumeIRQ for unknown process: ' infoPrint. |
1028 id infoPrintCR. |
1028 id infoPrintCR. |
1029 ] |
1029 ] |
1030 |
1030 |
1031 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1031 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1032 ! ! |
1032 ! ! |
1033 |
1033 |
1108 The method returns the value from aBlockReturningPid (i.e a pid or nil)." |
1108 The method returns the value from aBlockReturningPid (i.e a pid or nil)." |
1109 |
1109 |
1110 |pid blocked osProcessStatus| |
1110 |pid blocked osProcessStatus| |
1111 |
1111 |
1112 OperatingSystem supportsChildInterrupts ifTrue:[ |
1112 OperatingSystem supportsChildInterrupts ifTrue:[ |
1113 "/ SIGCHLD is supported, |
1113 "/ SIGCHLD is supported, |
1114 "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received. |
1114 "/ aBlock will be evaluated, as soon as a SIGCHLD interrupt for pid has been received. |
1115 |
1115 |
1116 OperatingSystem enableChildSignalInterrupts. |
1116 OperatingSystem enableChildSignalInterrupts. |
1117 blocked := OperatingSystem blockInterrupts. |
1117 blocked := OperatingSystem blockInterrupts. |
1118 pid := aBlockReturningPid value. |
1118 pid := aBlockReturningPid value. |
1119 pid notNil ifTrue:[ |
1119 pid notNil ifTrue:[ |
1120 osChildExitActions at:pid put:actionBlock. |
1120 osChildExitActions at:pid put:actionBlock. |
1121 ]. |
1121 ]. |
1122 blocked ifFalse:[ |
1122 blocked ifFalse:[ |
1123 OperatingSystem unblockInterrupts. |
1123 OperatingSystem unblockInterrupts. |
1124 ]. |
1124 ]. |
1125 ] ifFalse:[ |
1125 ] ifFalse:[ |
1126 "/ SIGCHLD is not supported, fork a high prio process |
1126 "/ SIGCHLD is not supported, fork a high prio process |
1127 "/ to poll for for the exit of pid. |
1127 "/ to poll for for the exit of pid. |
1128 |
1128 |
1129 blocked := OperatingSystem blockInterrupts. |
1129 blocked := OperatingSystem blockInterrupts. |
1130 pid := aBlockReturningPid value. |
1130 pid := aBlockReturningPid value. |
1131 pid notNil ifTrue:[ |
1131 pid notNil ifTrue:[ |
1132 osChildExitActions at:pid put:actionBlock. |
1132 osChildExitActions at:pid put:actionBlock. |
1133 ]. |
1133 ]. |
1134 blocked ifFalse:[ |
1134 blocked ifFalse:[ |
1135 OperatingSystem unblockInterrupts. |
1135 OperatingSystem unblockInterrupts. |
1136 ]. |
1136 ]. |
1137 |
1137 |
1138 pid notNil ifTrue:[ |
1138 pid notNil ifTrue:[ |
1139 [ |
1139 [ |
1140 [ |
1140 [ |
1141 |polling myDelay t| |
1141 |polling myDelay t| |
1142 |
1142 |
1143 polling := true. |
1143 polling := true. |
1144 myDelay := Delay forMilliseconds:(t := EventPollingInterval). |
1144 myDelay := Delay forMilliseconds:(t := EventPollingInterval). |
1145 [polling] whileTrue:[ |
1145 [polling] whileTrue:[ |
1146 t ~~ EventPollingInterval ifTrue:[ |
1146 t ~~ EventPollingInterval ifTrue:[ |
1147 "/ interval changed -> need a new delay |
1147 "/ interval changed -> need a new delay |
1148 myDelay delay:(t := EventPollingInterval). |
1148 myDelay delay:(t := EventPollingInterval). |
1149 ]. |
1149 ]. |
1150 myDelay wait. |
1150 myDelay wait. |
1151 (osChildExitActions includesKey:pid) ifFalse:[ |
1151 (osChildExitActions includesKey:pid) ifFalse:[ |
1152 polling := false. |
1152 polling := false. |
1153 ] ifTrue:[ |
1153 ] ifTrue:[ |
1154 osProcessStatus := OperatingSystem childProcessWait:false pid:pid. |
1154 osProcessStatus := OperatingSystem childProcessWait:false pid:pid. |
1155 osProcessStatus notNil ifTrue:[ |
1155 osProcessStatus notNil ifTrue:[ |
1156 (osProcessStatus pid = pid) ifTrue:[ |
1156 (osProcessStatus pid = pid) ifTrue:[ |
1157 osChildExitActions removeKey:pid ifAbsent:nil. |
1157 osChildExitActions removeKey:pid ifAbsent:nil. |
1158 actionBlock value:osProcessStatus. |
1158 actionBlock value:osProcessStatus. |
1159 polling := false. |
1159 polling := false. |
1160 ] ifFalse:[ |
1160 ] ifFalse:[ |
1161 osProcessStatus stillAlive |
1161 osProcessStatus stillAlive |
1162 ] |
1162 ] |
1163 ] |
1163 ] |
1164 ]. |
1164 ]. |
1165 ] |
1165 ] |
1166 ] valueOnUnwindDo:[ |
1166 ] valueOnUnwindDo:[ |
1167 osChildExitActions removeKey:pid ifAbsent:nil |
1167 osChildExitActions removeKey:pid ifAbsent:nil |
1168 ] |
1168 ] |
1169 ] forkAt:TimingPriority. |
1169 ] forkAt:TimingPriority. |
1170 ]. |
1170 ]. |
1171 ]. |
1171 ]. |
1172 ^ pid |
1172 ^ pid |
1173 |
1173 |
1174 "Created: / 25.3.1997 / 10:54:56 / stefan" |
1174 "Created: / 25.3.1997 / 10:54:56 / stefan" |
1175 "Modified: / 25.3.1997 / 11:21:05 / stefan" |
1175 "Modified: / 25.3.1997 / 11:21:05 / stefan" |
1256 activeProcess := oldProcess. |
1256 activeProcess := oldProcess. |
1257 activeProcessId := oldId. |
1257 activeProcessId := oldId. |
1258 currentPriority := oldProcess priority. |
1258 currentPriority := oldProcess priority. |
1259 |
1259 |
1260 ok == true ifFalse:[ |
1260 ok == true ifFalse:[ |
1261 " |
1261 " |
1262 switch failed for some reason - |
1262 switch failed for some reason - |
1263 destroy (hard-terminate) the bad process. |
1263 destroy (hard-terminate) the bad process. |
1264 This happens when: |
1264 This happens when: |
1265 - the stack went above the absolute limit |
1265 - the stack went above the absolute limit |
1266 (VM switches back to scheduler) |
1266 (VM switches back to scheduler) |
1267 - a halted process cannot execute its interrupt |
1267 - a halted process cannot execute its interrupt |
1268 actions (win32 only) |
1268 actions (win32 only) |
1269 " |
1269 " |
1270 (id := p id) ~~ 0 ifTrue:[ |
1270 (id := p id) ~~ 0 ifTrue:[ |
1271 id notNil ifTrue:[ |
1271 id notNil ifTrue:[ |
1272 'Processor [warning]: problem with process ' errorPrint. |
1272 'Processor [warning]: problem with process ' errorPrint. |
1273 id errorPrint. |
1273 id errorPrint. |
1274 (nm := p name) notNil ifTrue:[ |
1274 (nm := p name) notNil ifTrue:[ |
1275 ' (' errorPrint. nm errorPrint. ')' errorPrint. |
1275 ' (' errorPrint. nm errorPrint. ')' errorPrint. |
1276 ]. |
1276 ]. |
1277 |
1277 |
1278 ok == #halted ifTrue:[ |
1278 ok == #halted ifTrue:[ |
1279 "/ that process was halted (win32 only) |
1279 "/ that process was halted (win32 only) |
1280 p state:#halted. |
1280 p state:#halted. |
1281 '; stopped it.' errorPrintCR. |
1281 '; stopped it.' errorPrintCR. |
1282 self suspend:p. |
1282 self suspend:p. |
1283 ] ifFalse:[ |
1283 ] ifFalse:[ |
1284 '; hard-terminate it.' errorPrintCR. |
1284 '; hard-terminate it.' errorPrintCR. |
1285 'Processor [info]: cleanup may take a while if stack is huge' infoPrintCR. |
1285 'Processor [info]: cleanup may take a while if stack is huge' infoPrintCR. |
1286 p state:#cleanup. |
1286 p state:#cleanup. |
1287 self terminateNoSignal:p. |
1287 self terminateNoSignal:p. |
1288 ] |
1288 ] |
1289 ] |
1289 ] |
1290 ] |
1290 ] |
1291 ]. |
1291 ]. |
1292 zombie notNil ifTrue:[ |
1292 zombie notNil ifTrue:[ |
1293 self class threadDestroy:zombie. |
1293 self class threadDestroy:zombie. |
1294 zombie := nil |
1294 zombie := nil |
1295 ]. |
1295 ]. |
1296 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1296 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1297 ! |
1297 ! |
1298 |
1298 |
1299 threadSwitchFrom:oldProcess to:aProcess id:id singleStep:singleStep |
1299 threadSwitchFrom:oldProcess to:aProcess id:id singleStep:singleStep |
1961 "remove the process from the runnable list" |
1960 "remove the process from the runnable list" |
1962 |
1961 |
1963 pri := aProcess priority. |
1962 pri := aProcess priority. |
1964 l := quiescentProcessLists at:pri. |
1963 l := quiescentProcessLists at:pri. |
1965 l notNil ifTrue:[ |
1964 l notNil ifTrue:[ |
1966 (l remove:aProcess ifAbsent:nil) notNil ifTrue:[ |
1965 (l remove:aProcess ifAbsent:nil) notNil ifTrue:[ |
1967 l isEmpty ifTrue:[ |
1966 l isEmpty ifTrue:[ |
1968 quiescentProcessLists at:pri put:nil |
1967 quiescentProcessLists at:pri put:nil |
1969 ] |
1968 ] |
1970 ]. |
1969 ]. |
1971 ]. |
1970 ]. |
1972 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1971 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1973 |
1972 |
1974 aProcess == activeProcess ifTrue:[ |
1973 aProcess == activeProcess ifTrue:[ |
1975 " |
1974 " |
1976 hard case - its the currently running process |
1975 hard case - its the currently running process |
1977 we must have the next active process destroy this one |
1976 we must have the next active process destroy this one |
1978 (we cannot destroy the chair we are sitting on ... :-) |
1977 (we cannot destroy the chair we are sitting on ... :-) |
1979 " |
1978 " |
1980 zombie := id. |
1979 zombie := id. |
1981 self unRemember:aProcess. |
1980 self unRemember:aProcess. |
1982 self threadSwitch:scheduler. |
1981 self threadSwitch:scheduler. |
1983 "not reached" |
1982 "not reached" |
1984 ^ self |
1983 ^ self |
1985 ]. |
1984 ]. |
1986 self class threadDestroy:id. |
1985 self class threadDestroy:id. |
1987 self unRemember:aProcess. |
1986 self unRemember:aProcess. |
1988 ^ self |
1987 ^ self |
1989 |
1988 |
2408 "arrange for a semaphore to be triggered when input on aStream arrives. |
2407 "arrange for a semaphore to be triggered when input on aStream arrives. |
2409 This will do a select, if the OS supports selecting on that filedescriptor, |
2408 This will do a select, if the OS supports selecting on that filedescriptor, |
2410 otherwise, it will be polled every few milliseconds (MSDOS)." |
2409 otherwise, it will be polled every few milliseconds (MSDOS)." |
2411 |
2410 |
2412 aStream canBeSelected ifTrue:[ |
2411 aStream canBeSelected ifTrue:[ |
2413 "/ can this stream be selected on ? |
2412 "/ can this stream be selected on ? |
2414 self signal:aSemaphore onInput:aStream fileDescriptor orCheck:nil |
2413 self signal:aSemaphore onInput:aStream fileDescriptor orCheck:nil |
2415 ] ifFalse:[ |
2414 ] ifFalse:[ |
2416 "/ nope - must poll ... |
2415 "/ nope - must poll ... |
2417 self signal:aSemaphore onInput:nil orCheck:[aStream canReadWithoutBlocking] |
2416 self signal:aSemaphore onInput:nil orCheck:[aStream canReadWithoutBlocking] |
2418 ] |
2417 ] |
2419 |
2418 |
2420 "Modified: / 14.12.1999 / 23:58:50 / cg" |
2419 "Modified: / 14.12.1999 / 23:58:50 / cg" |
2421 ! |
2420 ! |
2422 |
2421 |
2482 "arrange for a semaphore to be triggered when output on aStream is possible. |
2481 "arrange for a semaphore to be triggered when output on aStream is possible. |
2483 This will do a select, if the OS supports selecting on that filedescriptor, |
2482 This will do a select, if the OS supports selecting on that filedescriptor, |
2484 otherwise, it will be polled every few milliseconds (MSDOS)." |
2483 otherwise, it will be polled every few milliseconds (MSDOS)." |
2485 |
2484 |
2486 aStream canBeSelected ifTrue:[ |
2485 aStream canBeSelected ifTrue:[ |
2487 "/ can this stream be selected on ? |
2486 "/ can this stream be selected on ? |
2488 self signal:aSemaphore onOutput:aStream fileDescriptor orCheck:nil |
2487 self signal:aSemaphore onOutput:aStream fileDescriptor orCheck:nil |
2489 ] ifFalse:[ |
2488 ] ifFalse:[ |
2490 "/ nope - must poll ... |
2489 "/ nope - must poll ... |
2491 self signal:aSemaphore onOutput:nil orCheck:[aStream canWriteWithoutBlocking] |
2490 self signal:aSemaphore onOutput:nil orCheck:[aStream canWriteWithoutBlocking] |
2492 ] |
2491 ] |
2493 |
2492 |
2494 "Modified: / 14.12.1999 / 23:59:19 / cg" |
2493 "Modified: / 14.12.1999 / 23:59:19 / cg" |
2495 ! ! |
2494 ! ! |
2496 |
2495 |
2503 If enabled, arrangements are made for data-availability to trigger an |
2502 If enabled, arrangements are made for data-availability to trigger an |
2504 interrupt. |
2503 interrupt. |
2505 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2504 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2506 (typically 2-7%). |
2505 (typically 2-7%). |
2507 Notice: |
2506 Notice: |
2508 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2507 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2509 and this feature is always disabled; |
2508 and this feature is always disabled; |
2510 Also notice: |
2509 Also notice: |
2511 we found that in some Xlib-implementations, interrupted reads are not |
2510 we found that in some Xlib-implementations, interrupted reads are not |
2512 handled correctly (especially in multi-headed applications), and this |
2511 handled correctly (especially in multi-headed applications), and this |
2513 feature should be disabled to avoid a blocking XPending. |
2512 feature should be disabled to avoid a blocking XPending. |
2514 |
2513 |
2515 If this method is used to disable IO interrupts in multi-headed apps, |
2514 If this method is used to disable IO interrupts in multi-headed apps, |
2516 it should be invoked BEFORE the display event dispatcher processes are started." |
2515 it should be invoked BEFORE the display event dispatcher processes are started." |
2517 |
2516 |
2518 OperatingSystem supportsIOInterrupts ifTrue:[ |
2517 OperatingSystem supportsIOInterrupts ifTrue:[ |
2519 useIOInterrupts := aBoolean |
2518 useIOInterrupts := aBoolean |
2520 ]. |
2519 ]. |
2521 |
2520 |
2522 "Created: / 15.7.1998 / 13:32:29 / cg" |
2521 "Created: / 15.7.1998 / 13:32:29 / cg" |
2523 ! ! |
2522 ! ! |
2524 |
2523 |
2835 |
2834 |
2836 "/ must enable interrupts, to be able to get out of a |
2835 "/ must enable interrupts, to be able to get out of a |
2837 "/ long wait (especially, to handle sigChild in the meantime) |
2836 "/ long wait (especially, to handle sigChild in the meantime) |
2838 |
2837 |
2839 (wasBlocked := OperatingSystem interruptsBlocked) ifTrue:[ |
2838 (wasBlocked := OperatingSystem interruptsBlocked) ifTrue:[ |
2840 OperatingSystem unblockInterrupts. |
2839 OperatingSystem unblockInterrupts. |
2841 ]. |
2840 ]. |
2842 |
2841 |
2843 fd := OperatingSystem |
2842 fd := OperatingSystem |
2844 selectOnAnyReadable:readFdArray |
2843 selectOnAnyReadable:readFdArray |
2845 writable:writeFdArray |
2844 writable:writeFdArray |
2846 exception:nil |
2845 exception:nil |
2847 withTimeOut:millis. |
2846 withTimeOut:millis. |
2848 |
2847 |
2849 wasBlocked ifTrue:[ |
2848 wasBlocked ifTrue:[ |
2850 OperatingSystem blockInterrupts. |
2849 OperatingSystem blockInterrupts. |
2851 ]. |
2850 ]. |
2852 |
2851 |
2853 fd isNil ifTrue:[ |
2852 fd isNil ifTrue:[ |
2854 "/ either still nothing to do, |
2853 "/ either still nothing to do, |
2855 "/ or error (which should not happen) |
2854 "/ or error (which should not happen) |
2856 |
2855 |
2857 (err := OperatingSystem lastErrorSymbol) notNil ifTrue:[ |
2856 (err := OperatingSystem lastErrorSymbol) notNil ifTrue:[ |
2858 err == #EBADF ifTrue:[ |
2857 err == #EBADF ifTrue:[ |
2859 |
2858 |
2860 "/ mhmh - one of the fd's given to me is corrupt. |
2859 "/ mhmh - one of the fd's given to me is corrupt. |
2861 "/ find out which one .... and remove it |
2860 "/ find out which one .... and remove it |
2862 |
2861 |
2863 'Processor [info]: obsolete FD in select - clearing' infoPrintCR. |
2862 'Processor [info]: obsolete FD in select - clearing' infoPrintCR. |
2864 OperatingSystem clearLastErrorNumber. |
2863 OperatingSystem clearLastErrorNumber. |
2865 self removeCorruptedFds |
2864 self removeCorruptedFds |
2866 ] ifFalse:[ |
2865 ] ifFalse:[ |
2867 err == #ENOENT ifTrue:[ |
2866 err == #ENOENT ifTrue:[ |
2868 'Processor [warning]: ENOENT in select; rd=' infoPrint. |
2867 'Processor [warning]: ENOENT in select; rd=' infoPrint. |
2869 readFdArray infoPrint. |
2868 readFdArray infoPrint. |
2870 ' wr=' infoPrint. |
2869 ' wr=' infoPrint. |
2871 writeFdArray infoPrintCR. |
2870 writeFdArray infoPrintCR. |
2872 ] ifFalse:[ |
2871 ] ifFalse:[ |
2873 'Processor [warning]: error in select: ' infoPrint. err infoPrintCR. |
2872 'Processor [warning]: error in select: ' infoPrint. err infoPrintCR. |
2874 ] |
2873 ] |
2875 ]. |
2874 ]. |
2876 ] |
2875 ] |
2877 ] ifFalse:[ |
2876 ] ifFalse:[ |
2878 index := readFdArray identityIndexOf:fd. |
2877 index := readFdArray identityIndexOf:fd. |
2879 index ~~ 0 ifTrue:[ |
2878 index ~~ 0 ifTrue:[ |
2880 sema := readSemaphoreArray at:index. |
2879 sema := readSemaphoreArray at:index. |
2881 sema notNil ifTrue:[ |
2880 sema notNil ifTrue:[ |
2882 sema signalOnce. |
2881 sema signalOnce. |
2883 ^ true |
2882 ^ true |
2884 ]. |
2883 ]. |
2885 action := readCheckArray at:index. |
2884 action := readCheckArray at:index. |
2886 action notNil ifTrue:[ |
2885 action notNil ifTrue:[ |
2887 action value. |
2886 action value. |
2888 ^ true |
2887 ^ true |
2889 ] |
2888 ] |
2890 ]. |
2889 ]. |
2891 index := writeFdArray identityIndexOf:fd. |
2890 index := writeFdArray identityIndexOf:fd. |
2892 index ~~ 0 ifTrue:[ |
2891 index ~~ 0 ifTrue:[ |
2893 sema := writeSemaphoreArray at:index. |
2892 sema := writeSemaphoreArray at:index. |
2894 sema notNil ifTrue:[ |
2893 sema notNil ifTrue:[ |
2895 sema signalOnce. |
2894 sema signalOnce. |
2896 ^ true |
2895 ^ true |
2897 ]. |
2896 ]. |
2898 action := writeCheckArray at:index. |
2897 action := writeCheckArray at:index. |
2899 action notNil ifTrue:[ |
2898 action notNil ifTrue:[ |
2900 action value. |
2899 action value. |
2901 ^ true |
2900 ^ true |
2902 ] |
2901 ] |
2903 ] |
2902 ] |
2904 ]. |
2903 ]. |
2905 ^ false |
2904 ^ false |
2906 |
2905 |
2907 "Modified: / 12.4.1996 / 09:31:22 / stefan" |
2906 "Modified: / 12.4.1996 / 09:31:22 / stefan" |
2908 "Modified: / 14.6.1998 / 17:31:51 / cg" |
2907 "Modified: / 14.6.1998 / 17:31:51 / cg" |
3053 |
3052 |
3054 |millis doingGC anySema dT| |
3053 |millis doingGC anySema dT| |
3055 |
3054 |
3056 doingGC := true. |
3055 doingGC := true. |
3057 [doingGC] whileTrue:[ |
3056 [doingGC] whileTrue:[ |
3058 anyTimeouts ifTrue:[ |
3057 anyTimeouts ifTrue:[ |
3059 millis := self timeToNextTimeout. |
3058 millis := self timeToNextTimeout. |
3060 (millis notNil and:[millis <= 0]) ifTrue:[ |
3059 (millis notNil and:[millis <= 0]) ifTrue:[ |
3061 ^ self "oops - hurry up checking" |
3060 ^ self "oops - hurry up checking" |
3062 ]. |
3061 ]. |
3063 ]. |
3062 ]. |
3064 |
3063 |
3065 " |
3064 " |
3066 if its worth doing, collect a bit of garbage; |
3065 if its worth doing, collect a bit of garbage; |
3067 but not, if a backgroundCollector is active |
3066 but not, if a backgroundCollector is active |
3068 " |
3067 " |
3069 ObjectMemory backgroundCollectorRunning ifTrue:[ |
3068 ObjectMemory backgroundCollectorRunning ifTrue:[ |
3070 doingGC := false |
3069 doingGC := false |
3071 ] ifFalse:[ |
3070 ] ifFalse:[ |
3072 doingGC := ObjectMemory gcStepIfUseful. |
3071 doingGC := ObjectMemory gcStepIfUseful. |
3073 ]. |
3072 ]. |
3074 |
3073 |
3075 "then do idle actions" |
3074 "then do idle actions" |
3076 (idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[ |
3075 (idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[ |
3077 idleActions do:[:aBlock | |
3076 idleActions do:[:aBlock | |
3078 aBlock value. |
3077 aBlock value. |
3079 ]. |
3078 ]. |
3080 ^ self "go back checking" |
3079 ^ self "go back checking" |
3081 ]. |
3080 ]. |
3082 |
3081 |
3083 doingGC ifTrue:[ |
3082 doingGC ifTrue:[ |
3084 (self checkForInputWithTimeout:0) ifTrue:[ |
3083 (self checkForInputWithTimeout:0) ifTrue:[ |
3085 ^ self "go back checking" |
3084 ^ self "go back checking" |
3086 ] |
3085 ] |
3087 ] |
3086 ] |
3088 ]. |
3087 ]. |
3089 |
3088 |
3090 exitWhenNoMoreUserProcesses ifTrue:[ |
3089 exitWhenNoMoreUserProcesses ifTrue:[ |
3091 "/ check if there are any processes at all |
3090 "/ check if there are any processes at all |
3092 "/ stop dispatching if there is none |
3091 "/ stop dispatching if there is none |
3093 "/ (and millis is nil, which means that no timeout blocks are present) |
3092 "/ (and millis is nil, which means that no timeout blocks are present) |
3094 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3093 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3095 "/ and no writeSemaphores are present |
3094 "/ and no writeSemaphores are present |
3096 |
3095 |
3097 anySema := false. |
3096 anySema := false. |
3098 anySema := (readSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3097 anySema := (readSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3099 anySema ifFalse:[ |
3098 anySema ifFalse:[ |
3100 anySema := (writeSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3099 anySema := (writeSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3101 ]. |
3100 ]. |
3102 anySema ifFalse:[ |
3101 anySema ifFalse:[ |
3103 self anyUserProcessAtAll ifFalse:[ |
3102 self anyUserProcessAtAll ifFalse:[ |
3104 dispatching := false. |
3103 dispatching := false. |
3105 ^ self |
3104 ^ self |
3106 ] |
3105 ] |
3107 ]. |
3106 ]. |
3108 ]. |
3107 ]. |
3109 |
3108 |
3110 "/ |
3109 "/ |
3111 "/ absolutely nothing to do - simply wait |
3110 "/ absolutely nothing to do - simply wait |
3112 "/ |
3111 "/ |
3113 OperatingSystem supportsSelect ifFalse:[ |
3112 OperatingSystem supportsSelect ifFalse:[ |
3114 "SCO instant ShitStation has a bug here, |
3113 "SCO instant ShitStation has a bug here, |
3115 waiting always 1 sec in the select - therefore we delay a bit and |
3114 waiting always 1 sec in the select - therefore we delay a bit and |
3116 return - effectively polling in 50ms cycles |
3115 return - effectively polling in 50ms cycles |
3117 " |
3116 " |
3118 (self checkForInputWithTimeout:0) ifTrue:[ |
3117 (self checkForInputWithTimeout:0) ifTrue:[ |
3119 ^ self "go back checking" |
3118 ^ self "go back checking" |
3120 ]. |
3119 ]. |
3121 OperatingSystem millisecondDelay:EventPollingInterval. |
3120 OperatingSystem millisecondDelay:EventPollingInterval. |
3122 ^ self |
3121 ^ self |
3123 ]. |
3122 ]. |
3124 |
3123 |
3125 useIOInterrupts ifTrue:[ |
3124 useIOInterrupts ifTrue:[ |
3126 dT := 999999 |
3125 dT := 999999 |
3127 ] ifFalse:[ |
3126 ] ifFalse:[ |
3128 dT := EventPollingInterval |
3127 dT := EventPollingInterval |
3129 ]. |
3128 ]. |
3130 |
3129 |
3131 millis isNil ifTrue:[ |
3130 millis isNil ifTrue:[ |
3132 millis := dT. |
3131 millis := dT. |
3133 ] ifFalse:[ |
3132 ] ifFalse:[ |
3134 millis := millis rounded min:dT. |
3133 millis := millis rounded min:dT. |
3135 ]. |
3134 ]. |
3136 self checkForInputWithTimeout:millis |
3135 self checkForInputWithTimeout:millis |
3137 |
3136 |
3138 "Modified: 14.12.1995 / 13:37:46 / stefan" |
3137 "Modified: 14.12.1995 / 13:37:46 / stefan" |
3139 "Modified: 18.7.1996 / 20:42:17 / cg" |
3138 "Modified: 18.7.1996 / 20:42:17 / cg" |
3140 ! ! |
3139 ! ! |
3141 |
3140 |
3142 !ProcessorScheduler class methodsFor:'documentation'! |
3141 !ProcessorScheduler class methodsFor:'documentation'! |
3143 |
3142 |
3144 version |
3143 version |
3145 ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.195 2001-12-06 08:52:25 cg Exp $' |
3144 ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.196 2002-02-04 14:31:14 cg Exp $' |
3146 ! ! |
3145 ! ! |
3147 ProcessorScheduler initialize! |
3146 ProcessorScheduler initialize! |