12 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
13 |
13 |
14 "{ NameSpace: Smalltalk }" |
14 "{ NameSpace: Smalltalk }" |
15 |
15 |
16 Object subclass:#ProcessorScheduler |
16 Object subclass:#ProcessorScheduler |
17 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
17 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
18 activeProcessId currentPriority readFdArray readSemaphoreArray |
18 activeProcessId currentPriority readFdArray readSemaphoreArray |
19 readCheckArray writeFdArray writeSemaphoreArray writeCheckArray |
19 readCheckArray writeFdArray writeSemaphoreArray writeCheckArray |
20 timeoutArray timeoutActionArray timeoutProcessArray |
20 timeoutArray timeoutActionArray timeoutProcessArray |
21 timeoutSemaphoreArray idleActions anyTimeouts dispatching |
21 timeoutSemaphoreArray idleActions anyTimeouts dispatching |
22 interruptedProcess useIOInterrupts gotIOInterrupt |
22 interruptedProcess useIOInterrupts gotIOInterrupt |
23 osChildExitActions gotChildSignalInterrupt |
23 osChildExitActions gotChildSignalInterrupt |
24 exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess |
24 exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess |
25 supportDynamicPriorities timeSliceNeededSemaphore |
25 supportDynamicPriorities timeSliceNeededSemaphore |
26 scheduledProcesses preWaitActions timeoutHandlerProcess |
26 scheduledProcesses preWaitActions timeoutHandlerProcess |
27 readableResultFdArray writableResultFdArray exceptFdArray |
27 readableResultFdArray writableResultFdArray exceptFdArray |
28 exceptResultFdArray exceptSemaphoreArray interruptCounter |
28 exceptResultFdArray exceptSemaphoreArray interruptCounter |
29 timedActionCounter' |
29 timedActionCounter' |
30 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
30 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
31 UserSchedulingPriority UserInterruptPriority TimingPriority |
31 UserSchedulingPriority UserInterruptPriority TimingPriority |
32 HighestPriority SchedulingPriority MaxNumberOfProcesses |
32 HighestPriority SchedulingPriority MaxNumberOfProcesses |
33 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
33 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
34 EventPollingInterval MaxProcessId' |
34 EventPollingInterval MaxProcessId' |
35 poolDictionaries:'' |
35 poolDictionaries:'' |
36 category:'Kernel-Processes' |
36 category:'Kernel-Processes' |
37 ! |
37 ! |
38 |
38 |
39 !ProcessorScheduler class methodsFor:'documentation'! |
39 !ProcessorScheduler class methodsFor:'documentation'! |
40 |
40 |
41 copyright |
41 copyright |
42 " |
42 " |
43 COPYRIGHT (c) 1993 by Claus Gittinger |
43 COPYRIGHT (c) 1993 by Claus Gittinger |
44 All Rights Reserved |
44 All Rights Reserved |
45 |
45 |
46 This software is furnished under a license and may be used |
46 This software is furnished under a license and may be used |
47 only in accordance with the terms of that license and with the |
47 only in accordance with the terms of that license and with the |
48 inclusion of the above copyright notice. This software may not |
48 inclusion of the above copyright notice. This software may not |
49 be provided or otherwise made available to, or used by, any |
49 be provided or otherwise made available to, or used by, any |
222 event. |
222 event. |
223 Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which |
223 Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which |
224 allows for critical processes to run unaffected to completion. |
224 allows for critical processes to run unaffected to completion. |
225 |
225 |
226 WARNING: |
226 WARNING: |
227 timesliced priority scheduling is an experimental feature. There is no warranty, |
227 timesliced priority scheduling is an experimental feature. There is no warranty, |
228 (at the moment), that the system runs reliable in this mode. |
228 (at the moment), that the system runs reliable in this mode. |
229 The problem is, that shared collections may now be easily modified by other |
229 The problem is, that shared collections may now be easily modified by other |
230 processes, running at the same time. |
230 processes, running at the same time. |
231 The class library has being investigated for such possible trouble spots |
231 The class library has being investigated for such possible trouble spots |
232 (we have eliminated many weak spots, and added critical regions at many places, |
232 (we have eliminated many weak spots, and added critical regions at many places, |
233 but cannot guarantee that all of them have been found so far ...) |
233 but cannot guarantee that all of them have been found so far ...) |
234 We found that many existing public domain programs are not prepared for |
234 We found that many existing public domain programs are not prepared for |
235 being interrupted by a same-prio process and therefore may corrupt their |
235 being interrupted by a same-prio process and therefore may corrupt their |
236 data. If in doubt, disable this fefature. |
236 data. If in doubt, disable this fefature. |
237 |
237 |
238 We think, that the timeSlicer is a useful add-on and that the system is fit enough |
238 We think, that the timeSlicer is a useful add-on and that the system is fit enough |
239 for it to be evaluated, therefore, its included. |
239 for it to be evaluated, therefore, its included. |
240 However, use it at your own risk. |
240 However, use it at your own risk. |
241 |
241 |
242 To demonstrate the effect of timeSlicing, do the following: |
242 To demonstrate the effect of timeSlicing, do the following: |
243 |
243 |
244 - disable timeSlicing (in the launchers misc-settings menu) |
244 - disable timeSlicing (in the launchers misc-settings menu) |
245 - open a workSpace |
245 - open a workSpace |
246 - in the workspace, evaluate: |
246 - in the workspace, evaluate: |
247 [true] whileTrue:[1000 factorial] |
247 [true] whileTrue:[1000 factorial] |
248 |
248 |
249 now, (since the workSpace runs at the same prio as other window-processes), |
249 now, (since the workSpace runs at the same prio as other window-processes), |
250 other views do no longer react - all CPU is used up by the workSpace. |
250 other views do no longer react - all CPU is used up by the workSpace. |
251 However, CTRL-C in the workspace is still possible to stop the endless loop, |
251 However, CTRL-C in the workspace is still possible to stop the endless loop, |
252 since that is handled by the (higher prio) event dispatcher process. |
252 since that is handled by the (higher prio) event dispatcher process. |
272 TimeSlicingPriorityLimit := 26. |
272 TimeSlicingPriorityLimit := 26. |
273 HighestPriority := 30. |
273 HighestPriority := 30. |
274 SchedulingPriority := 31. |
274 SchedulingPriority := 31. |
275 |
275 |
276 InvalidProcessSignal isNil ifTrue:[ |
276 InvalidProcessSignal isNil ifTrue:[ |
277 InvalidProcessSignal := Error newSignalMayProceed:true. |
277 InvalidProcessSignal := Error newSignalMayProceed:true. |
278 InvalidProcessSignal nameClass:self message:#invalidProcessSignal. |
278 InvalidProcessSignal nameClass:self message:#invalidProcessSignal. |
279 InvalidProcessSignal notifierString:'invalid process'. |
279 InvalidProcessSignal notifierString:'invalid process'. |
280 ]. |
280 ]. |
281 |
281 |
282 Processor isNil ifTrue:[ |
282 Processor isNil ifTrue:[ |
283 "create the one and only processor" |
283 "create the one and only processor" |
284 |
284 |
285 Smalltalk at:#Processor put:(self basicNew initialize). |
285 Smalltalk at:#Processor put:(self basicNew initialize). |
286 ]. |
286 ]. |
287 |
287 |
288 " |
288 " |
289 allow configurations without processes |
289 allow configurations without processes |
290 (but such configurations are no longer distributed) |
290 (but such configurations are no longer distributed) |
291 " |
291 " |
292 PureEventDriven := self threadsAvailable not. |
292 PureEventDriven := self threadsAvailable not. |
293 PureEventDriven ifTrue:[ |
293 PureEventDriven ifTrue:[ |
294 'Processor [error]: no process support - running event driven' errorPrintCR |
294 'Processor [error]: no process support - running event driven' errorPrintCR |
295 ]. |
295 ]. |
296 self initializeVMMaxProcessId |
296 self initializeVMMaxProcessId |
297 |
297 |
298 "Modified: / 23-09-1996 / 14:24:50 / stefan" |
298 "Modified: / 23-09-1996 / 14:24:50 / stefan" |
299 "Modified: / 10-01-1997 / 18:03:03 / cg" |
299 "Modified: / 10-01-1997 / 18:03:03 / cg" |
344 by sending #terminate." |
344 by sending #terminate." |
345 |
345 |
346 |id sz "{ Class: SmallInteger }"| |
346 |id sz "{ Class: SmallInteger }"| |
347 |
347 |
348 something == #ElementExpired ifTrue:[ |
348 something == #ElementExpired ifTrue:[ |
349 sz := KnownProcessIds size. |
349 sz := KnownProcessIds size. |
350 1 to:sz do:[:index | |
350 1 to:sz do:[:index | |
351 "/ (KnownProcesses at:index) isNil ifTrue:[ |
351 "/ (KnownProcesses at:index) isNil ifTrue:[ |
352 (KnownProcesses at:index) class == SmallInteger ifTrue:[ |
352 (KnownProcesses at:index) class == SmallInteger ifTrue:[ |
353 id := KnownProcessIds at:index. |
353 id := KnownProcessIds at:index. |
354 id notNil ifTrue:[ |
354 id notNil ifTrue:[ |
355 'Processor [warning]: terminating thread ' errorPrint. |
355 'Processor [warning]: terminating thread ' errorPrint. |
356 id errorPrint. |
356 id errorPrint. |
357 ' (no longer refd)' errorPrintCR. |
357 ' (no longer refd)' errorPrintCR. |
358 |
358 |
359 self threadDestroy:id. |
359 self threadDestroy:id. |
360 KnownProcessIds at:index put:nil. |
360 KnownProcessIds at:index put:nil. |
361 ]. |
361 ]. |
362 KnownProcesses at:index put:nil. |
362 KnownProcesses at:index put:nil. |
363 ] |
363 ] |
364 ] |
364 ] |
365 ] |
365 ] |
366 |
366 |
367 "Created: 7.1.1997 / 16:45:42 / stefan" |
367 "Created: 7.1.1997 / 16:45:42 / stefan" |
368 "Modified: 10.1.1997 / 19:10:48 / cg" |
368 "Modified: 10.1.1997 / 19:10:48 / cg" |
369 ! ! |
369 ! ! |
526 |
526 |
527 |idx "{Class: SmallInteger }" |
527 |idx "{Class: SmallInteger }" |
528 wasBlocked| |
528 wasBlocked| |
529 |
529 |
530 aFileDescriptor < 0 ifTrue:[ |
530 aFileDescriptor < 0 ifTrue:[ |
531 'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR. |
531 'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR. |
532 thisContext fullPrintAll. |
532 thisContext fullPrintAll. |
533 ^ self |
533 ^ self |
534 ]. |
534 ]. |
535 |
535 |
536 wasBlocked := OperatingSystem blockInterrupts. |
536 wasBlocked := OperatingSystem blockInterrupts. |
537 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
537 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
538 idx := readFdArray identityIndexOf:nil startingAt:1. |
538 idx := readFdArray identityIndexOf:nil startingAt:1. |
539 idx ~~ 0 ifTrue:[ |
539 idx ~~ 0 ifTrue:[ |
540 readFdArray at:idx put:aFileDescriptor. |
540 readFdArray at:idx put:aFileDescriptor. |
541 readCheckArray at:idx put:aBlock. |
541 readCheckArray at:idx put:aBlock. |
542 readSemaphoreArray at:idx put:nil |
542 readSemaphoreArray at:idx put:nil |
543 ] ifFalse:[ |
543 ] ifFalse:[ |
544 readFdArray := readFdArray copyWith:aFileDescriptor. |
544 readFdArray := readFdArray copyWith:aFileDescriptor. |
545 readCheckArray := readCheckArray copyWith:aBlock. |
545 readCheckArray := readCheckArray copyWith:aBlock. |
546 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
546 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
547 ]. |
547 ]. |
548 useIOInterrupts ifTrue:[ |
548 useIOInterrupts ifTrue:[ |
549 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
549 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
550 ]. |
550 ]. |
551 |
551 |
552 ]. |
552 ]. |
553 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
553 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
554 |
554 |
555 "Modified: 4.8.1997 / 15:17:28 / cg" |
555 "Modified: 4.8.1997 / 15:17:28 / cg" |
1018 " |
1018 " |
1019 lay all processes to rest, collect restartable ones |
1019 lay all processes to rest, collect restartable ones |
1020 " |
1020 " |
1021 processesToRestart := OrderedCollection new. |
1021 processesToRestart := OrderedCollection new. |
1022 KnownProcesses do:[:p | |
1022 KnownProcesses do:[:p | |
1023 (p notNil and:[p class ~~ SmallInteger]) ifTrue:[ |
1023 (p notNil and:[p class ~~ SmallInteger]) ifTrue:[ |
1024 "how, exactly should this be done ?" |
1024 "how, exactly should this be done ?" |
1025 |
1025 |
1026 p isRestartable == true ifTrue:[ |
1026 p isRestartable == true ifTrue:[ |
1027 p nextLink:nil. |
1027 p nextLink:nil. |
1028 processesToRestart add:p |
1028 processesToRestart add:p |
1029 ] ifFalse:[ |
1029 ] ifFalse:[ |
1030 p setId:nil state:#dead |
1030 p setId:nil state:#dead |
1031 ] |
1031 ] |
1032 ]. |
1032 ]. |
1033 ]. |
1033 ]. |
1034 scheduler setId:nil state:#dead. |
1034 scheduler setId:nil state:#dead. |
1035 |
1035 |
1036 " |
1036 " |
1037 now, start from scratch |
1037 now, start from scratch |
1038 " |
1038 " |
1039 KnownProcesses := nil. |
1039 KnownProcesses := nil. |
1040 self initialize. |
1040 self initialize. |
1041 |
1041 |
1042 processesToRestart do:[:p | |
1042 processesToRestart do:[:p | |
1043 p imageRestart |
1043 p imageRestart |
1044 ] |
1044 ] |
1045 |
1045 |
1046 "Modified: / 7.6.1998 / 02:23:56 / cg" |
1046 "Modified: / 7.6.1998 / 02:23:56 / cg" |
1047 ! ! |
1047 ! ! |
1048 |
1048 |
1056 <context: #return> |
1056 <context: #return> |
1057 |
1057 |
1058 |index pri aProcess l| |
1058 |index pri aProcess l| |
1059 |
1059 |
1060 OperatingSystem interruptsBlocked ifFalse:[ |
1060 OperatingSystem interruptsBlocked ifFalse:[ |
1061 MiniDebugger |
1061 MiniDebugger |
1062 enterWithMessage:'vmResumeInterrupt with no interruptsBlocked' |
1062 enterWithMessage:'vmResumeInterrupt with no interruptsBlocked' |
1063 mayProceed:true. |
1063 mayProceed:true. |
1064 ]. |
1064 ]. |
1065 |
1065 |
1066 index := KnownProcessIds identityIndexOf:id. |
1066 index := KnownProcessIds identityIndexOf:id. |
1067 index ~~ 0 ifTrue:[ |
1067 index ~~ 0 ifTrue:[ |
1068 aProcess := KnownProcesses at:index. |
1068 aProcess := KnownProcesses at:index. |
1069 pri := aProcess priority. |
1069 pri := aProcess priority. |
1070 l := quiescentProcessLists at:pri. |
1070 l := quiescentProcessLists at:pri. |
1071 l notNil ifTrue:[ |
1071 l notNil ifTrue:[ |
1072 (l includesIdentical:aProcess) ifTrue:[ |
1072 (l includesIdentical:aProcess) ifTrue:[ |
1073 "/ aProcess is on a run queue. |
1073 "/ aProcess is on a run queue. |
1074 "/ CG: this situation may happen, if the wrapCall |
1074 "/ CG: this situation may happen, if the wrapCall |
1075 "/ finishes before the process was layed to sleep |
1075 "/ finishes before the process was layed to sleep |
1076 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished). |
1076 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished). |
1077 "/ In that case, simply resume it and everything is OK. |
1077 "/ In that case, simply resume it and everything is OK. |
1078 "/ If the process is state running, ignore. |
1078 "/ If the process is state running, ignore. |
1079 |
1079 |
1080 |state| |
1080 |state| |
1081 |
1081 |
1082 state := aProcess state. |
1082 state := aProcess state. |
1083 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[ |
1083 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[ |
1084 aProcess state:#run. |
1084 aProcess state:#run. |
1085 ]. |
1085 ]. |
1086 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint. |
1086 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint. |
1087 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR. |
1087 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR. |
1088 ^ self |
1088 ^ self |
1089 ] |
1089 ] |
1090 ] ifFalse:[ |
1090 ] ifFalse:[ |
1091 l := LinkedList new. |
1091 l := LinkedList new. |
1092 quiescentProcessLists at:pri put:l. |
1092 quiescentProcessLists at:pri put:l. |
1093 ]. |
1093 ]. |
1094 l addLast:aProcess. |
1094 l addLast:aProcess. |
1095 aProcess state:#run. |
1095 aProcess state:#run. |
1096 ] ifFalse:[ |
1096 ] ifFalse:[ |
1097 'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint. |
1097 'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint. |
1098 id infoPrintCR. |
1098 id infoPrintCR. |
1099 ] |
1099 ] |
1100 |
1100 |
1101 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1101 "Modified: / 28.9.1998 / 11:36:53 / cg" |
1102 ! |
1102 ! |
1103 |
1103 |
1178 blocking := OperatingSystem isChildProcessWaitBlocking. |
1178 blocking := OperatingSystem isChildProcessWaitBlocking. |
1179 |
1179 |
1180 "/ no interrupt processing, to avoid races with monitorPid |
1180 "/ no interrupt processing, to avoid races with monitorPid |
1181 wasBlocked := OperatingSystem blockInterrupts. |
1181 wasBlocked := OperatingSystem blockInterrupts. |
1182 [ |
1182 [ |
1183 [ |
1183 [ |
1184 osProcessStatus := OperatingSystem childProcessWait:blocking pid:nil. |
1184 osProcessStatus := OperatingSystem childProcessWait:blocking pid:nil. |
1185 osProcessStatus notNil ifTrue:[ |
1185 osProcessStatus notNil ifTrue:[ |
1186 |pid action| |
1186 |pid action| |
1187 |
1187 |
1188 pid := osProcessStatus pid. |
1188 pid := osProcessStatus pid. |
1189 osProcessStatus stillAlive ifTrue:[ |
1189 osProcessStatus stillAlive ifTrue:[ |
1190 action := osChildExitActions at:pid ifAbsent:nil. |
1190 action := osChildExitActions at:pid ifAbsent:nil. |
1191 ] ifFalse:[ |
1191 ] ifFalse:[ |
1192 action := osChildExitActions removeKey:pid ifAbsent:nil. |
1192 action := osChildExitActions removeKey:pid ifAbsent:nil. |
1193 ]. |
1193 ]. |
1194 action notNil ifTrue:[ |
1194 action notNil ifTrue:[ |
1195 action value:osProcessStatus |
1195 action value:osProcessStatus |
1196 ]. |
1196 ]. |
1197 ]. |
1197 ]. |
1198 |
1198 |
1199 "/ if pollChildProcesses does block, poll only one status change. |
1199 "/ if pollChildProcesses does block, poll only one status change. |
1200 "/ we will get another SIGCHLD for other status changes. |
1200 "/ we will get another SIGCHLD for other status changes. |
1201 |
1201 |
1202 osProcessStatus notNil and:[blocking not] |
1202 osProcessStatus notNil and:[blocking not] |
1203 ] whileTrue. |
1203 ] whileTrue. |
1204 |
1204 |
1205 "/ if there are no more waiters, disable SIGCHILD handler. |
1205 "/ if there are no more waiters, disable SIGCHILD handler. |
1206 "/ this helps us with synchronous waiters (e.g. pclose), |
1206 "/ this helps us with synchronous waiters (e.g. pclose), |
1207 "/ But they should block SIGCHLD anyway. |
1207 "/ But they should block SIGCHLD anyway. |
1208 |
1208 |
1209 osChildExitActions isEmpty ifTrue:[ |
1209 osChildExitActions isEmpty ifTrue:[ |
1210 OperatingSystem disableChildSignalInterrupts. |
1210 OperatingSystem disableChildSignalInterrupts. |
1211 ]. |
1211 ]. |
1212 ] ensure:[ |
1212 ] ensure:[ |
1213 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1213 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1214 ] |
1214 ] |
1215 |
1215 |
1216 "Modified: 5.1.1996 / 16:56:11 / stefan" |
1216 "Modified: 5.1.1996 / 16:56:11 / stefan" |
1217 "Modified: 28.2.1996 / 21:36:31 / cg" |
1217 "Modified: 28.2.1996 / 21:36:31 / cg" |
1218 "Created: 12.4.1996 / 10:08:21 / stefan" |
1218 "Created: 12.4.1996 / 10:08:21 / stefan" |
1488 |
1488 |
1489 wasBlocked := OperatingSystem blockInterrupts. |
1489 wasBlocked := OperatingSystem blockInterrupts. |
1490 index := 1. |
1490 index := 1. |
1491 sz := KnownProcessIds size. |
1491 sz := KnownProcessIds size. |
1492 [index <= sz] whileTrue:[ |
1492 [index <= sz] whileTrue:[ |
1493 (KnownProcesses at:index) isNil ifTrue:[ |
1493 (KnownProcesses at:index) isNil ifTrue:[ |
1494 oldId := KnownProcessIds at:index. |
1494 oldId := KnownProcessIds at:index. |
1495 oldId notNil ifTrue:[ |
1495 oldId notNil ifTrue:[ |
1496 self class threadDestroy:oldId. |
1496 self class threadDestroy:oldId. |
1497 ]. |
1497 ]. |
1498 KnownProcesses at:index put:aProcess. |
1498 KnownProcesses at:index put:aProcess. |
1499 KnownProcessIds at:index put:aProcess id. |
1499 KnownProcessIds at:index put:aProcess id. |
1500 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1500 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1501 ^ self |
1501 ^ self |
1502 ]. |
1502 ]. |
1503 index := index + 1 |
1503 index := index + 1 |
1504 ]. |
1504 ]. |
1505 |
1505 |
1506 KnownProcessIds grow:index. |
1506 KnownProcessIds grow:index. |
1507 KnownProcessIds at:index put:aProcess id. |
1507 KnownProcessIds at:index put:aProcess id. |
1508 |
1508 |
1509 oldSize := KnownProcesses size. |
1509 oldSize := KnownProcesses size. |
1510 (index > oldSize) ifTrue:[ |
1510 (index > oldSize) ifTrue:[ |
1511 newShadow := WeakArray new:(oldSize * 2). |
1511 newShadow := WeakArray new:(oldSize * 2). |
1512 newShadow addDependent:self class. |
1512 newShadow addDependent:self class. |
1513 newShadow replaceFrom:1 with:KnownProcesses. |
1513 newShadow replaceFrom:1 with:KnownProcesses. |
1514 KnownProcesses := newShadow |
1514 KnownProcesses := newShadow |
1515 ]. |
1515 ]. |
1516 KnownProcesses at:index put:aProcess. |
1516 KnownProcesses at:index put:aProcess. |
1517 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1517 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1518 |
1518 |
1519 "Modified: 7.1.1997 / 16:48:39 / stefan" |
1519 "Modified: 7.1.1997 / 16:48:39 / stefan" |
1676 prio := HighestPriority. |
1676 prio := HighestPriority. |
1677 wasBlocked := OperatingSystem blockInterrupts. |
1677 wasBlocked := OperatingSystem blockInterrupts. |
1678 |
1678 |
1679 listArray := quiescentProcessLists. |
1679 listArray := quiescentProcessLists. |
1680 [prio >= 1] whileTrue:[ |
1680 [prio >= 1] whileTrue:[ |
1681 l := listArray at:prio. |
1681 l := listArray at:prio. |
1682 l notNil ifTrue:[ |
1682 l notNil ifTrue:[ |
1683 l notEmpty ifTrue:[ |
1683 l notEmpty ifTrue:[ |
1684 p := l firstLink. |
1684 p := l firstLink. |
1685 " |
1685 " |
1686 if it got corrupted somehow ... |
1686 if it got corrupted somehow ... |
1687 " |
1687 " |
1688 p isDead ifTrue:[ |
1688 p isDead ifTrue:[ |
1689 'Processor [warning]: dead process removed' errorPrintCR. |
1689 'Processor [warning]: dead process removed' errorPrintCR. |
1690 l removeFirst. |
1690 l removeFirst. |
1691 p := nil. |
1691 p := nil. |
1692 ]. |
1692 ]. |
1693 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1693 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1694 ^ p |
1694 ^ p |
1695 ] |
1695 ] |
1696 ]. |
1696 ]. |
1697 prio := prio - 1 |
1697 prio := prio - 1 |
1698 ]. |
1698 ]. |
1699 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1699 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1700 ^ nil |
1700 ^ nil |
1701 |
1701 |
1702 "Modified: 12.2.1997 / 12:41:49 / cg" |
1702 "Modified: 12.2.1997 / 12:41:49 / cg" |
1742 |
1742 |
1743 wasBlocked := OperatingSystem blockInterrupts. |
1743 wasBlocked := OperatingSystem blockInterrupts. |
1744 |
1744 |
1745 slot := KnownProcessIds indexOf:anInteger. |
1745 slot := KnownProcessIds indexOf:anInteger. |
1746 slot ~~ 0 ifTrue:[ |
1746 slot ~~ 0 ifTrue:[ |
1747 process := KnownProcesses at:slot ifAbsent:[]. |
1747 process := KnownProcesses at:slot ifAbsent:[]. |
1748 ]. |
1748 ]. |
1749 |
1749 |
1750 wasBlocked ifFalse:[ |
1750 wasBlocked ifFalse:[ |
1751 OperatingSystem unblockInterrupts. |
1751 OperatingSystem unblockInterrupts. |
1752 ]. |
1752 ]. |
1753 |
1753 |
1754 "Take care, the process may already have been collected" |
1754 "Take care, the process may already have been collected" |
1755 process == 0 ifTrue:[ |
1755 process == 0 ifTrue:[ |
1756 ^ nil. |
1756 ^ nil. |
1757 ]. |
1757 ]. |
1758 ^ process. |
1758 ^ process. |
1759 |
1759 |
1760 " |
1760 " |
1761 Processor processWithId:4 |
1761 Processor processWithId:4 |
1762 Processor processWithId:4711 |
1762 Processor processWithId:4711 |
1763 " |
1763 " |
1764 ! |
1764 ! |
1765 |
1765 |
1766 processesWithGroupId:anInteger |
1766 processesWithGroupId:anInteger |
1767 "answer a collection of processes with processGroupId, anInteger" |
1767 "answer a collection of processes with processGroupId, anInteger" |
1867 "/ the interrupt block should think it was called right |
1867 "/ the interrupt block should think it was called right |
1868 "/ from the originally interrupted context |
1868 "/ from the originally interrupted context |
1869 |
1869 |
1870 s := thisContext sender. |
1870 s := thisContext sender. |
1871 s selector == #threadSwitchFrom:to:id:singleStep: ifTrue:[ |
1871 s selector == #threadSwitchFrom:to:id:singleStep: ifTrue:[ |
1872 s := s sender. |
1872 s := s sender. |
1873 s selector == #threadSwitch: ifTrue:[ |
1873 s selector == #threadSwitch: ifTrue:[ |
1874 s := s sender. |
1874 s := s sender. |
1875 s selector == #timerInterrupt ifTrue:[ |
1875 s selector == #timerInterrupt ifTrue:[ |
1876 s := s sender |
1876 s := s sender |
1877 ] |
1877 ] |
1878 ] |
1878 ] |
1879 ]. |
1879 ]. |
1880 |
1880 |
1881 "/ the returned value here has a subtle effect: |
1881 "/ the returned value here has a subtle effect: |
1882 "/ if false, the interrupt is assumed to be not taken, |
1882 "/ if false, the interrupt is assumed to be not taken, |
1883 "/ and will be redelivered. |
1883 "/ and will be redelivered. |
2179 |l sz wasBlocked| |
2179 |l sz wasBlocked| |
2180 |
2180 |
2181 wasBlocked := OperatingSystem blockInterrupts. |
2181 wasBlocked := OperatingSystem blockInterrupts. |
2182 |
2182 |
2183 activeProcess == scheduler ifTrue:[ |
2183 activeProcess == scheduler ifTrue:[ |
2184 'Processor [warning]: scheduler tries to yield' errorPrintCR. |
2184 'Processor [warning]: scheduler tries to yield' errorPrintCR. |
2185 ^ self |
2185 ^ self |
2186 ]. |
2186 ]. |
2187 |
2187 |
2188 " |
2188 " |
2189 debugging consistency check - will be removed later |
2189 debugging consistency check - will be removed later |
2190 " |
2190 " |
2191 activeProcess priority ~~ currentPriority ifTrue:[ |
2191 activeProcess priority ~~ currentPriority ifTrue:[ |
2192 'Processor [warning]: process changed its priority' errorPrintCR. |
2192 'Processor [warning]: process changed its priority' errorPrintCR. |
2193 currentPriority := activeProcess priority. |
2193 currentPriority := activeProcess priority. |
2194 ]. |
2194 ]. |
2195 |
2195 |
2196 l := quiescentProcessLists at:currentPriority. |
2196 l := quiescentProcessLists at:currentPriority. |
2197 sz := l size. |
2197 sz := l size. |
2198 |
2198 |
2199 " |
2199 " |
2200 debugging consistency checks - will be removed later |
2200 debugging consistency checks - will be removed later |
2201 " |
2201 " |
2202 sz == 0 ifTrue:[ |
2202 sz == 0 ifTrue:[ |
2203 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2203 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2204 'Processor [warning]: empty runnable list' errorPrintCR. |
2204 'Processor [warning]: empty runnable list' errorPrintCR. |
2205 ^ self |
2205 ^ self |
2206 ]. |
2206 ]. |
2207 |
2207 |
2208 " |
2208 " |
2209 check if the running process is not the only one |
2209 check if the running process is not the only one |
2210 " |
2210 " |
2211 sz ~~ 1 ifTrue:[ |
2211 sz ~~ 1 ifTrue:[ |
2212 " |
2212 " |
2213 bring running process to the end |
2213 bring running process to the end |
2214 " |
2214 " |
2215 l removeFirst. |
2215 l removeFirst. |
2216 l addLast:activeProcess. |
2216 l addLast:activeProcess. |
2217 |
2217 |
2218 " |
2218 " |
2219 and switch to first in the list |
2219 and switch to first in the list |
2220 " |
2220 " |
2221 self threadSwitch:(l firstLink). |
2221 self threadSwitch:(l firstLink). |
2222 ]. |
2222 ]. |
2223 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2223 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2224 |
2224 |
2225 "Modified: / 02-08-2010 / 13:36:25 / cg" |
2225 "Modified: / 02-08-2010 / 13:36:25 / cg" |
2226 ! ! |
2226 ! ! |
2231 "recompute dynamic priorities." |
2231 "recompute dynamic priorities." |
2232 |
2232 |
2233 |processesToDecrease processesToIncrease| |
2233 |processesToDecrease processesToIncrease| |
2234 |
2234 |
2235 scheduledProcesses notNil ifTrue:[ |
2235 scheduledProcesses notNil ifTrue:[ |
2236 "/ this is written a bit cryptic - to avoid creation |
2236 "/ this is written a bit cryptic - to avoid creation |
2237 "/ of garbage objects (Id'sets) if possible. |
2237 "/ of garbage objects (Id'sets) if possible. |
2238 "/ since this runs 50 times a second and most of the |
2238 "/ since this runs 50 times a second and most of the |
2239 "/ time, no rescheduling is req'd |
2239 "/ time, no rescheduling is req'd |
2240 |
2240 |
2241 scheduledProcesses do:[:aProcess | |
2241 scheduledProcesses do:[:aProcess | |
2242 |range| |
2242 |range| |
2243 |
2243 |
2244 "/ decrease priority of processes that did run |
2244 "/ decrease priority of processes that did run |
2245 (range := aProcess priorityRange) notNil ifTrue:[ |
2245 (range := aProcess priorityRange) notNil ifTrue:[ |
2246 aProcess priority > range start ifTrue:[ |
2246 aProcess priority > range start ifTrue:[ |
2247 processesToDecrease isNil ifTrue:[ |
2247 processesToDecrease isNil ifTrue:[ |
2248 processesToDecrease := IdentitySet new. |
2248 processesToDecrease := IdentitySet new. |
2249 ]. |
2249 ]. |
2250 processesToDecrease add:aProcess. |
2250 processesToDecrease add:aProcess. |
2251 ] |
2251 ] |
2252 ] |
2252 ] |
2253 ]. |
2253 ]. |
2254 |
2254 |
2255 processesToDecrease notNil ifTrue:[ |
2255 processesToDecrease notNil ifTrue:[ |
2256 processesToDecrease do:[:aProcess | |
2256 processesToDecrease do:[:aProcess | |
2257 |newPri| |
2257 |newPri| |
2258 |
2258 |
2259 "/ newPri := aProcess priority - 1. |
2259 "/ newPri := aProcess priority - 1. |
2260 newPri := aProcess priorityRange start. |
2260 newPri := aProcess priorityRange start. |
2261 self changePriority:newPri for:aProcess. |
2261 self changePriority:newPri for:aProcess. |
2262 ]. |
2262 ]. |
2263 ]. |
2263 ]. |
2264 |
2264 |
2265 "/ and increase all prios of those that did not run, but are runnable |
2265 "/ and increase all prios of those that did not run, but are runnable |
2266 |
2266 |
2267 TimeSlicingPriorityLimit to:1 by:-1 do:[:i | |
2267 TimeSlicingPriorityLimit to:1 by:-1 do:[:i | |
2268 |list| |
2268 |list| |
2269 |
2269 |
2270 (list := quiescentProcessLists at:i) size > 0 ifTrue:[ |
2270 (list := quiescentProcessLists at:i) size > 0 ifTrue:[ |
2271 list linksDo:[:aProcess | |
2271 list linksDo:[:aProcess | |
2272 |range prio| |
2272 |range prio| |
2273 |
2273 |
2274 (range := aProcess priorityRange) notNil ifTrue:[ |
2274 (range := aProcess priorityRange) notNil ifTrue:[ |
2275 (processesToDecrease isNil |
2275 (processesToDecrease isNil |
2276 or:[(processesToDecrease includes:aProcess) not]) ifTrue:[ |
2276 or:[(processesToDecrease includes:aProcess) not]) ifTrue:[ |
2277 aProcess priority < range stop ifTrue:[ |
2277 aProcess priority < range stop ifTrue:[ |
2278 processesToIncrease isNil ifTrue:[ |
2278 processesToIncrease isNil ifTrue:[ |
2279 processesToIncrease := OrderedCollection new. |
2279 processesToIncrease := OrderedCollection new. |
2280 ]. |
2280 ]. |
2281 processesToIncrease add:aProcess |
2281 processesToIncrease add:aProcess |
2282 ] |
2282 ] |
2283 ] |
2283 ] |
2284 ] |
2284 ] |
2285 ] |
2285 ] |
2286 ] |
2286 ] |
2287 ]. |
2287 ]. |
2288 processesToIncrease notNil ifTrue:[ |
2288 processesToIncrease notNil ifTrue:[ |
2289 processesToIncrease do:[:aProcess | |
2289 processesToIncrease do:[:aProcess | |
2290 self changePriority:(aProcess priority + 1) for:aProcess. |
2290 self changePriority:(aProcess priority + 1) for:aProcess. |
2291 ]. |
2291 ]. |
2292 ]. |
2292 ]. |
2293 ]. |
2293 ]. |
2294 |
2294 |
2295 "Modified: / 30-07-2013 / 19:33:14 / cg" |
2295 "Modified: / 30-07-2013 / 19:33:14 / cg" |
2296 ! |
2296 ! |
2297 |
2297 |
2443 |idx "{ Class: SmallInteger }" |
2443 |idx "{ Class: SmallInteger }" |
2444 wasBlocked sema semaCollection| |
2444 wasBlocked sema semaCollection| |
2445 |
2445 |
2446 wasBlocked := OperatingSystem blockInterrupts. |
2446 wasBlocked := OperatingSystem blockInterrupts. |
2447 useIOInterrupts ifTrue:[ |
2447 useIOInterrupts ifTrue:[ |
2448 OperatingSystem disableIOInterruptsOn:aFileDescriptor. |
2448 OperatingSystem disableIOInterruptsOn:aFileDescriptor. |
2449 ]. |
2449 ]. |
2450 |
2450 |
2451 idx := readFdArray indexOf:aFileDescriptor startingAt:1. |
2451 idx := readFdArray indexOf:aFileDescriptor startingAt:1. |
2452 [idx ~~ 0] whileTrue:[ |
2452 [idx ~~ 0] whileTrue:[ |
2453 readFdArray at:idx put:nil. |
2453 readFdArray at:idx put:nil. |
2454 readCheckArray at:idx put:nil. |
2454 readCheckArray at:idx put:nil. |
2455 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
2455 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
2456 readSemaphoreArray at:idx put:nil. |
2456 readSemaphoreArray at:idx put:nil. |
2457 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2457 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2458 semaCollection add:sema. |
2458 semaCollection add:sema. |
2459 ]. |
2459 ]. |
2460 idx := readFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2460 idx := readFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2461 ]. |
2461 ]. |
2462 idx := writeFdArray indexOf:aFileDescriptor startingAt:1. |
2462 idx := writeFdArray indexOf:aFileDescriptor startingAt:1. |
2463 [idx ~~ 0] whileTrue:[ |
2463 [idx ~~ 0] whileTrue:[ |
2464 writeFdArray at:idx put:nil. |
2464 writeFdArray at:idx put:nil. |
2465 writeCheckArray at:idx put:nil. |
2465 writeCheckArray at:idx put:nil. |
2466 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
2466 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
2467 writeSemaphoreArray at:idx put:nil. |
2467 writeSemaphoreArray at:idx put:nil. |
2468 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2468 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2469 semaCollection add:sema. |
2469 semaCollection add:sema. |
2470 ]. |
2470 ]. |
2471 idx := writeFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2471 idx := writeFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2472 ]. |
2472 ]. |
2473 idx := exceptFdArray indexOf:aFileDescriptor startingAt:1. |
2473 idx := exceptFdArray indexOf:aFileDescriptor startingAt:1. |
2474 [idx ~~ 0] whileTrue:[ |
2474 [idx ~~ 0] whileTrue:[ |
2475 exceptFdArray at:idx put:nil. |
2475 exceptFdArray at:idx put:nil. |
2476 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
2476 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
2477 exceptSemaphoreArray at:idx put:nil. |
2477 exceptSemaphoreArray at:idx put:nil. |
2478 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2478 semaCollection isNil ifTrue:[semaCollection := Set new]. |
2479 semaCollection add:sema. |
2479 semaCollection add:sema. |
2480 ]. |
2480 ]. |
2481 idx := exceptFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2481 idx := exceptFdArray indexOf:aFileDescriptor startingAt:idx+1. |
2482 ]. |
2482 ]. |
2483 |
2483 |
2484 semaCollection isNil ifTrue:[ |
2484 semaCollection isNil ifTrue:[ |
2485 semaCollection := #(). |
2485 semaCollection := #(). |
2486 ] ifFalse:[ |
2486 ] ifFalse:[ |
2487 doSignal ifTrue:[ |
2487 doSignal ifTrue:[ |
2488 semaCollection do:[:eachSema| |
2488 semaCollection do:[:eachSema| |
2489 eachSema signalForAll. |
2489 eachSema signalForAll. |
2490 semaCollection := #(). |
2490 semaCollection := #(). |
2491 ]. |
2491 ]. |
2492 ]. |
2492 ]. |
2493 ]. |
2493 ]. |
2494 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2494 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2495 ^ semaCollection |
2495 ^ semaCollection |
2496 ! |
2496 ! |
2497 |
2497 |
2503 |
2503 |
2504 wasBlocked := OperatingSystem blockInterrupts. |
2504 wasBlocked := OperatingSystem blockInterrupts. |
2505 idx := 0. |
2505 idx := 0. |
2506 [idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2506 [idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2507 idx ~~ 0] whileTrue:[ |
2507 idx ~~ 0] whileTrue:[ |
2508 useIOInterrupts ifTrue:[ |
2508 useIOInterrupts ifTrue:[ |
2509 fd := readFdArray at:idx. |
2509 fd := readFdArray at:idx. |
2510 fd notNil ifTrue:[ |
2510 fd notNil ifTrue:[ |
2511 OperatingSystem disableIOInterruptsOn:fd |
2511 OperatingSystem disableIOInterruptsOn:fd |
2512 ]. |
2512 ]. |
2513 ]. |
2513 ]. |
2514 readFdArray at:idx put:nil. |
2514 readFdArray at:idx put:nil. |
2515 readSemaphoreArray at:idx put:nil. |
2515 readSemaphoreArray at:idx put:nil. |
2516 readCheckArray at:idx put:nil. |
2516 readCheckArray at:idx put:nil. |
2517 ]. |
2517 ]. |
2518 idx := 0. |
2518 idx := 0. |
2519 [idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2519 [idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2520 idx ~~ 0] whileTrue:[ |
2520 idx ~~ 0] whileTrue:[ |
2521 useIOInterrupts ifTrue:[ |
2521 useIOInterrupts ifTrue:[ |
2522 fd := writeFdArray at:idx. |
2522 fd := writeFdArray at:idx. |
2523 fd notNil ifTrue:[ |
2523 fd notNil ifTrue:[ |
2524 OperatingSystem disableIOInterruptsOn:fd |
2524 OperatingSystem disableIOInterruptsOn:fd |
2525 ]. |
2525 ]. |
2526 ]. |
2526 ]. |
2527 writeFdArray at:idx put:nil. |
2527 writeFdArray at:idx put:nil. |
2528 writeSemaphoreArray at:idx put:nil. |
2528 writeSemaphoreArray at:idx put:nil. |
2529 writeCheckArray at:idx put:nil. |
2529 writeCheckArray at:idx put:nil. |
2530 ]. |
2530 ]. |
2531 idx := 0. |
2531 idx := 0. |
2532 [idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2532 [idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2533 idx ~~ 0] whileTrue:[ |
2533 idx ~~ 0] whileTrue:[ |
2534 exceptFdArray at:idx put:nil. |
2534 exceptFdArray at:idx put:nil. |
2535 exceptSemaphoreArray at:idx put:nil. |
2535 exceptSemaphoreArray at:idx put:nil. |
2536 ]. |
2536 ]. |
2537 self removeTimeoutForSemaphore:aSemaphore. |
2537 self removeTimeoutForSemaphore:aSemaphore. |
2538 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2538 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2539 |
2539 |
2540 "Modified: 4.8.1997 / 15:19:33 / cg" |
2540 "Modified: 4.8.1997 / 15:19:33 / cg" |
2590 wasBlocked| |
2590 wasBlocked| |
2591 |
2591 |
2592 wasBlocked := OperatingSystem blockInterrupts. |
2592 wasBlocked := OperatingSystem blockInterrupts. |
2593 index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2593 index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2594 index ~~ 0 ifTrue:[ |
2594 index ~~ 0 ifTrue:[ |
2595 timeoutArray at:index put:aMillisecondTime |
2595 timeoutArray at:index put:aMillisecondTime |
2596 ] ifFalse:[ |
2596 ] ifFalse:[ |
2597 index := timeoutArray identityIndexOf:nil startingAt:1. |
2597 index := timeoutArray identityIndexOf:nil startingAt:1. |
2598 index ~~ 0 ifTrue:[ |
2598 index ~~ 0 ifTrue:[ |
2599 timeoutSemaphoreArray at:index put:aSemaphore. |
2599 timeoutSemaphoreArray at:index put:aSemaphore. |
2600 timeoutArray at:index put:aMillisecondTime. |
2600 timeoutArray at:index put:aMillisecondTime. |
2601 timeoutActionArray at:index put:nil. |
2601 timeoutActionArray at:index put:nil. |
2602 timeoutProcessArray at:index put:nil |
2602 timeoutProcessArray at:index put:nil |
2603 ] ifFalse:[ |
2603 ] ifFalse:[ |
2604 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore. |
2604 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore. |
2605 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2605 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2606 timeoutActionArray := timeoutActionArray copyWith:nil. |
2606 timeoutActionArray := timeoutActionArray copyWith:nil. |
2607 timeoutProcessArray := timeoutProcessArray copyWith:nil |
2607 timeoutProcessArray := timeoutProcessArray copyWith:nil |
2608 ]. |
2608 ]. |
2609 ]. |
2609 ]. |
2610 |
2610 |
2611 anyTimeouts := true. |
2611 anyTimeouts := true. |
2612 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2612 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2613 ! |
2613 ! |
2628 |
2628 |
2629 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2629 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2630 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2630 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2631 |
2631 |
2632 aFileDescriptor isNil ifTrue:[ |
2632 aFileDescriptor isNil ifTrue:[ |
2633 idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2633 idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2634 idx == 0 ifTrue:[ |
2634 idx == 0 ifTrue:[ |
2635 "aSemaphore is not registered yet, have to create a new slot" |
2635 "aSemaphore is not registered yet, have to create a new slot" |
2636 exceptFdArray := exceptFdArray copyWith:nil. |
2636 exceptFdArray := exceptFdArray copyWith:nil. |
2637 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2637 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2638 ] ifFalse:[ |
2638 ] ifFalse:[ |
2639 slot := exceptSemaphoreArray at:idx. |
2639 slot := exceptSemaphoreArray at:idx. |
2640 slot isNil ifTrue:[ |
2640 slot isNil ifTrue:[ |
2641 exceptSemaphoreArray at:idx put:aSemaphore. |
2641 exceptSemaphoreArray at:idx put:aSemaphore. |
2642 ] |
2642 ] |
2643 ] |
2643 ] |
2644 ] ifFalse:[ |
2644 ] ifFalse:[ |
2645 idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil. |
2645 idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil. |
2646 idx == 0 ifTrue:[ |
2646 idx == 0 ifTrue:[ |
2647 "aFileDescriptor is not registered yet, have to create a new slot" |
2647 "aFileDescriptor is not registered yet, have to create a new slot" |
2648 exceptFdArray := exceptFdArray copyWith:aFileDescriptor. |
2648 exceptFdArray := exceptFdArray copyWith:aFileDescriptor. |
2649 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2649 exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore. |
2650 ] ifFalse:[ |
2650 ] ifFalse:[ |
2651 slot := exceptFdArray at:idx. |
2651 slot := exceptFdArray at:idx. |
2652 slot isNil ifTrue:[ |
2652 slot isNil ifTrue:[ |
2653 exceptFdArray at:idx put:aFileDescriptor. |
2653 exceptFdArray at:idx put:aFileDescriptor. |
2654 exceptSemaphoreArray at:idx put:aSemaphore. |
2654 exceptSemaphoreArray at:idx put:aSemaphore. |
2655 ]. |
2655 ]. |
2656 ]. |
2656 ]. |
2657 "/ (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2657 "/ (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2658 "/ OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2658 "/ OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2659 "/ ]. |
2659 "/ ]. |
2660 ]. |
2660 ]. |
2661 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2661 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2688 |
2688 |
2689 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2689 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2690 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2690 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2691 |
2691 |
2692 aFileDescriptor isNil ifTrue:[ |
2692 aFileDescriptor isNil ifTrue:[ |
2693 idx := readSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2693 idx := readSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2694 idx == 0 ifTrue:[ |
2694 idx == 0 ifTrue:[ |
2695 "aSemaphore is not registered yet, have to create a new slot" |
2695 "aSemaphore is not registered yet, have to create a new slot" |
2696 readFdArray := readFdArray copyWith:nil. |
2696 readFdArray := readFdArray copyWith:nil. |
2697 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2697 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2698 readCheckArray := readCheckArray copyWith:aBlock. |
2698 readCheckArray := readCheckArray copyWith:aBlock. |
2699 ] ifFalse:[ |
2699 ] ifFalse:[ |
2700 slot := readSemaphoreArray at:idx. |
2700 slot := readSemaphoreArray at:idx. |
2701 slot isNil ifTrue:[ |
2701 slot isNil ifTrue:[ |
2702 readSemaphoreArray at:idx put:aSemaphore. |
2702 readSemaphoreArray at:idx put:aSemaphore. |
2703 readCheckArray at:idx put:aBlock |
2703 readCheckArray at:idx put:aBlock |
2704 ] ifFalse:[ |
2704 ] ifFalse:[ |
2705 "/ someone has already registered aSemaphore. |
2705 "/ someone has already registered aSemaphore. |
2706 "/ Check if it is the block changes... |
2706 "/ Check if it is the block changes... |
2707 (readCheckArray at:idx) notNil ifTrue:[ |
2707 (readCheckArray at:idx) notNil ifTrue:[ |
2708 (readCheckArray at:idx) ~~ aBlock ifTrue:[ |
2708 (readCheckArray at:idx) ~~ aBlock ifTrue:[ |
2709 'Processor [info]: checkblock changed for read-check' infoPrintCR. |
2709 'Processor [info]: checkblock changed for read-check' infoPrintCR. |
2710 readCheckArray at:idx put:aBlock. |
2710 readCheckArray at:idx put:aBlock. |
2711 ]. |
2711 ]. |
2712 ]. |
2712 ]. |
2713 ]. |
2713 ]. |
2714 ] |
2714 ] |
2715 ] ifFalse:[ |
2715 ] ifFalse:[ |
2716 idx := readFdArray identityIndexOf:aFileDescriptor or:nil. |
2716 idx := readFdArray identityIndexOf:aFileDescriptor or:nil. |
2717 idx == 0 ifTrue:[ |
2717 idx == 0 ifTrue:[ |
2718 "aFileDescriptor is not registered yet, have to create a new slot" |
2718 "aFileDescriptor is not registered yet, have to create a new slot" |
2719 readFdArray := readFdArray copyWith:aFileDescriptor. |
2719 readFdArray := readFdArray copyWith:aFileDescriptor. |
2720 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2720 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2721 readCheckArray := readCheckArray copyWith:aBlock. |
2721 readCheckArray := readCheckArray copyWith:aBlock. |
2722 ] ifFalse:[ |
2722 ] ifFalse:[ |
2723 slot := readFdArray at:idx. |
2723 slot := readFdArray at:idx. |
2724 slot isNil ifTrue:[ |
2724 slot isNil ifTrue:[ |
2725 readFdArray at:idx put:aFileDescriptor. |
2725 readFdArray at:idx put:aFileDescriptor. |
2726 readSemaphoreArray at:idx put:aSemaphore. |
2726 readSemaphoreArray at:idx put:aSemaphore. |
2727 readCheckArray at:idx put:aBlock |
2727 readCheckArray at:idx put:aBlock |
2728 ] ifFalse:[ |
2728 ] ifFalse:[ |
2729 "/ someone has already registered aFileDescriptor. |
2729 "/ someone has already registered aFileDescriptor. |
2730 "/ Check if it is the semaphore or block changes... |
2730 "/ Check if it is the semaphore or block changes... |
2731 (readSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[ |
2731 (readSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[ |
2732 'Processor [info]: sema changed for read-check' infoPrintCR. |
2732 'Processor [info]: sema changed for read-check' infoPrintCR. |
2733 readSemaphoreArray at:idx put:aSemaphore. |
2733 readSemaphoreArray at:idx put:aSemaphore. |
2734 ]. |
2734 ]. |
2735 (readCheckArray at:idx) ~~ aBlock ifTrue:[ |
2735 (readCheckArray at:idx) ~~ aBlock ifTrue:[ |
2736 'Processor [info]: checkblock changed for read-check' infoPrintCR. |
2736 'Processor [info]: checkblock changed for read-check' infoPrintCR. |
2737 readCheckArray at:idx put:aBlock. |
2737 readCheckArray at:idx put:aBlock. |
2738 ]. |
2738 ]. |
2739 ]. |
2739 ]. |
2740 ]. |
2740 ]. |
2741 (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2741 (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2742 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2742 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2743 ]. |
2743 ]. |
2744 ]. |
2744 ]. |
2745 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2745 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2746 |
2746 |
2747 "Modified: 4.8.1997 / 15:20:45 / cg" |
2747 "Modified: 4.8.1997 / 15:20:45 / cg" |
2748 ! |
2748 ! |
2789 |
2789 |
2790 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2790 "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock) |
2791 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2791 aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil" |
2792 |
2792 |
2793 aFileDescriptor isNil ifTrue:[ |
2793 aFileDescriptor isNil ifTrue:[ |
2794 idx := writeSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2794 idx := writeSemaphoreArray identityIndexOf:aSemaphore or:nil. |
2795 idx == 0 ifTrue:[ |
2795 idx == 0 ifTrue:[ |
2796 "aSemaphore is not registered yet, have to create a new slot" |
2796 "aSemaphore is not registered yet, have to create a new slot" |
2797 writeFdArray := writeFdArray copyWith:nil. |
2797 writeFdArray := writeFdArray copyWith:nil. |
2798 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2798 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2799 writeCheckArray := writeCheckArray copyWith:aBlock. |
2799 writeCheckArray := writeCheckArray copyWith:aBlock. |
2800 ] ifFalse:[ |
2800 ] ifFalse:[ |
2801 slot := writeSemaphoreArray at:idx. |
2801 slot := writeSemaphoreArray at:idx. |
2802 slot isNil ifTrue:[ |
2802 slot isNil ifTrue:[ |
2803 writeSemaphoreArray at:idx put:aSemaphore. |
2803 writeSemaphoreArray at:idx put:aSemaphore. |
2804 writeCheckArray at:idx put:aBlock |
2804 writeCheckArray at:idx put:aBlock |
2805 ] ifFalse:[ |
2805 ] ifFalse:[ |
2806 "/ someone has already registered aSemaphore. |
2806 "/ someone has already registered aSemaphore. |
2807 "/ Check if it is the block changes... |
2807 "/ Check if it is the block changes... |
2808 (writeCheckArray at:idx) notNil ifTrue:[ |
2808 (writeCheckArray at:idx) notNil ifTrue:[ |
2809 (writeCheckArray at:idx) ~~ aBlock ifTrue:[ |
2809 (writeCheckArray at:idx) ~~ aBlock ifTrue:[ |
2810 'Processor [info]: checkblock changed for write-check' infoPrintCR. |
2810 'Processor [info]: checkblock changed for write-check' infoPrintCR. |
2811 writeCheckArray at:idx put:aBlock. |
2811 writeCheckArray at:idx put:aBlock. |
2812 ]. |
2812 ]. |
2813 ]. |
2813 ]. |
2814 ]. |
2814 ]. |
2815 ] |
2815 ] |
2816 ] ifFalse:[ |
2816 ] ifFalse:[ |
2817 idx := writeFdArray identityIndexOf:aFileDescriptor or:nil. |
2817 idx := writeFdArray identityIndexOf:aFileDescriptor or:nil. |
2818 idx == 0 ifTrue:[ |
2818 idx == 0 ifTrue:[ |
2819 "aFileDescriptor is not registered yet, have to create a new slot" |
2819 "aFileDescriptor is not registered yet, have to create a new slot" |
2820 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
2820 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
2821 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2821 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2822 writeCheckArray := writeCheckArray copyWith:aBlock. |
2822 writeCheckArray := writeCheckArray copyWith:aBlock. |
2823 ] ifFalse:[ |
2823 ] ifFalse:[ |
2824 slot := writeFdArray at:idx. |
2824 slot := writeFdArray at:idx. |
2825 slot isNil ifTrue:[ |
2825 slot isNil ifTrue:[ |
2826 writeFdArray at:idx put:aFileDescriptor. |
2826 writeFdArray at:idx put:aFileDescriptor. |
2827 writeSemaphoreArray at:idx put:aSemaphore. |
2827 writeSemaphoreArray at:idx put:aSemaphore. |
2828 writeCheckArray at:idx put:aBlock |
2828 writeCheckArray at:idx put:aBlock |
2829 ] ifFalse:[ |
2829 ] ifFalse:[ |
2830 "/ someone has already registered aFileDescriptor. |
2830 "/ someone has already registered aFileDescriptor. |
2831 "/ Check if it is the semaphore or block changes... |
2831 "/ Check if it is the semaphore or block changes... |
2832 (writeSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[ |
2832 (writeSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[ |
2833 'Processor [info]: sema changed for write-check' infoPrintCR. |
2833 'Processor [info]: sema changed for write-check' infoPrintCR. |
2834 writeSemaphoreArray at:idx put:aSemaphore. |
2834 writeSemaphoreArray at:idx put:aSemaphore. |
2835 ]. |
2835 ]. |
2836 (writeCheckArray at:idx) ~~ aBlock ifTrue:[ |
2836 (writeCheckArray at:idx) ~~ aBlock ifTrue:[ |
2837 'Processor [info]: checkblock changed for write-check' infoPrintCR. |
2837 'Processor [info]: checkblock changed for write-check' infoPrintCR. |
2838 writeCheckArray at:idx put:aBlock. |
2838 writeCheckArray at:idx put:aBlock. |
2839 ]. |
2839 ]. |
2840 ]. |
2840 ]. |
2841 ]. |
2841 ]. |
2842 (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2842 (useIOInterrupts and:[slot isNil]) ifTrue:[ |
2843 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2843 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2844 ]. |
2844 ]. |
2845 ]. |
2845 ]. |
2846 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2846 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2847 |
2847 |
2848 "Modified: 4.8.1997 / 15:21:49 / cg" |
2848 "Modified: 4.8.1997 / 15:21:49 / cg" |
2849 ! |
2849 ! |
2873 If enabled, arrangements are made for data-availability to trigger an |
2873 If enabled, arrangements are made for data-availability to trigger an |
2874 interrupt. |
2874 interrupt. |
2875 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2875 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2876 (typically 2-7%). |
2876 (typically 2-7%). |
2877 Notice: |
2877 Notice: |
2878 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2878 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2879 and this feature is always disabled; |
2879 and this feature is always disabled; |
2880 Also notice: |
2880 Also notice: |
2881 we found that in some Xlib-implementations, interrupted reads are not |
2881 we found that in some Xlib-implementations, interrupted reads are not |
2882 handled correctly (especially in multi-headed applications), and this |
2882 handled correctly (especially in multi-headed applications), and this |
2883 feature should be disabled to avoid a blocking XPending. |
2883 feature should be disabled to avoid a blocking XPending. |
2884 |
2884 |
2885 If this method is used to disable IO interrupts in multi-headed apps, |
2885 If this method is used to disable IO interrupts in multi-headed apps, |
2886 it should be invoked BEFORE the display event dispatcher processes are started." |
2886 it should be invoked BEFORE the display event dispatcher processes are started." |
2887 |
2887 |
2888 OperatingSystem supportsIOInterrupts ifTrue:[ |
2888 OperatingSystem supportsIOInterrupts ifTrue:[ |
2889 useIOInterrupts := aBoolean |
2889 useIOInterrupts := aBoolean |
2890 ]. |
2890 ]. |
2891 |
2891 |
2892 "Created: / 15.7.1998 / 13:32:29 / cg" |
2892 "Created: / 15.7.1998 / 13:32:29 / cg" |
2893 ! ! |
2893 ! ! |
2894 |
2894 |
3120 |
3120 |
3121 |sema now aTime block blocksAndProcessesToEvaluate |
3121 |sema now aTime block blocksAndProcessesToEvaluate |
3122 firstBlockToEvaluate firstProcess |
3122 firstBlockToEvaluate firstProcess |
3123 n "{ Class: SmallInteger }" |
3123 n "{ Class: SmallInteger }" |
3124 indexOfLastTimeout "{ Class: SmallInteger }" |
3124 indexOfLastTimeout "{ Class: SmallInteger }" |
3125 halfSize "{ Class: SmallInteger }" |
3125 halfSize "{ Class: SmallInteger }" process wasBlocked| |
3126 wasBlocked p| |
3126 |
3127 |
3127 anyTimeouts ifFalse:[ |
3128 anyTimeouts ifFalse:[ ^ self]. |
3128 ^ self |
|
3129 ]. |
3129 anyTimeouts := false. |
3130 anyTimeouts := false. |
3130 indexOfLastTimeout := 0. |
3131 indexOfLastTimeout := 0. |
3131 |
3132 |
3132 "have to collect the blocks first, then evaluate them. |
3133 "have to collect the blocks first, then evaluate them. |
3133 This avoids problems due to newly inserted blocks." |
3134 This avoids problems due to newly inserted blocks." |
3138 "/ To avoid idle memory allocation, we avoid the allocation of the OrderedCollection in this case, |
3139 "/ To avoid idle memory allocation, we avoid the allocation of the OrderedCollection in this case, |
3139 "/ by remembering the first block+process in a variable until another block is found. |
3140 "/ by remembering the first block+process in a variable until another block is found. |
3140 "/ Thus firstBlockToEvaluate+firstProcess effectively cache the first slot of the lazy allocated collection. |
3141 "/ Thus firstBlockToEvaluate+firstProcess effectively cache the first slot of the lazy allocated collection. |
3141 "/ looks ugly, but as this is called very often, reduces idle allocation by a lot. |
3142 "/ looks ugly, but as this is called very often, reduces idle allocation by a lot. |
3142 |
3143 |
|
3144 wasBlocked := OperatingSystem blockInterrupts. |
3143 now := OperatingSystem getMillisecondTime. |
3145 now := OperatingSystem getMillisecondTime. |
3144 n := timeoutArray size. |
3146 n := timeoutArray size. |
3145 1 to:n do:[:index | |
3147 1 to:n do:[:index | |
3146 aTime := timeoutArray at:index. |
3148 aTime := timeoutArray at:index. |
3147 aTime notNil ifTrue:[ |
3149 aTime notNil ifTrue:[ |
3192 |
3198 |
3193 "shrink the arrays, if they are 50% free" |
3199 "shrink the arrays, if they are 50% free" |
3194 n > 20 ifTrue:[ |
3200 n > 20 ifTrue:[ |
3195 halfSize := n // 2. |
3201 halfSize := n // 2. |
3196 (indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[ |
3202 (indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[ |
3197 wasBlocked := OperatingSystem blockInterrupts. |
3203 timeoutArray := timeoutArray copyTo:halfSize. |
3198 (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[ "/ no new timeouts arrived |
3204 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize. |
3199 timeoutArray := timeoutArray copyTo:halfSize. |
3205 timeoutActionArray := timeoutActionArray copyTo:halfSize. |
3200 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize. |
3206 timeoutProcessArray := timeoutProcessArray copyTo:halfSize. |
3201 timeoutActionArray := timeoutActionArray copyTo:halfSize. |
|
3202 timeoutProcessArray := timeoutProcessArray copyTo:halfSize. |
|
3203 ]. |
|
3204 wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ]. |
|
3205 ]. |
3207 ]. |
3206 ]. |
3208 ]. |
3207 |
3209 |
3208 "/ usually (>99%), there is only one single timeout action to call; |
3210 "/ usually (>99%), there is only one single timeout action to call; |
3209 "/ above code avoided the creation of an OrderedCollection |
3211 "/ above code avoided the creation of an OrderedCollection |
3210 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3212 blocksAndProcessesToEvaluate isNil ifTrue:[ |
3211 firstBlockToEvaluate notNil ifTrue:[ |
3213 firstBlockToEvaluate notNil ifTrue:[ |
3212 timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal). |
3214 timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal. |
3213 (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[ |
3215 (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[ |
3214 firstBlockToEvaluate value |
3216 firstBlockToEvaluate value |
3215 ] ifFalse:[ |
3217 ] ifFalse:[ |
3216 firstProcess isDead ifTrue:[ |
3218 firstProcess isDead ifTrue:[ |
3217 "/ a timedBlock for a process which has already terminated |
3219 "/ a timedBlock for a process which has already terminated |
3234 ]. |
3236 ]. |
3235 ] ifFalse:[ |
3237 ] ifFalse:[ |
3236 n := blocksAndProcessesToEvaluate size. |
3238 n := blocksAndProcessesToEvaluate size. |
3237 1 to:n by:2 do:[:index | |
3239 1 to:n by:2 do:[:index | |
3238 block := blocksAndProcessesToEvaluate at:index. |
3240 block := blocksAndProcessesToEvaluate at:index. |
3239 p := blocksAndProcessesToEvaluate at:index+1. |
3241 process := blocksAndProcessesToEvaluate at:index+1. |
3240 (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[ |
3242 (process isNil or:[process == scheduler or:[PureEventDriven]]) ifTrue:[ |
3241 block value. |
3243 block value. |
3242 timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal). |
3244 timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal. |
3243 ] ifFalse:[ |
3245 ] ifFalse:[ |
3244 p isDead ifTrue:[ |
3246 process isDead ifTrue:[ |
3245 "/ a timedBlock for a process which has already terminated |
3247 "/ a timedBlock for a process which has already terminated |
3246 "/ issue a warning and do not execute it. |
3248 "/ issue a warning and do not execute it. |
3247 "/ (executing here may be dangerous, since it would run at scheduler priority here, |
3249 "/ (executing here may be dangerous, since it would run at scheduler priority here, |
3248 "/ and thereby could block the whole smalltalk system. |
3250 "/ and thereby could block the whole smalltalk system. |
3249 "/ For this reason is it IGNORED here.) |
3251 "/ For this reason is it IGNORED here.) |
3251 "/ Could handle it in timeoutProcess, but we don't, |
3253 "/ Could handle it in timeoutProcess, but we don't, |
3252 "/ because otherwise timeouts might be reissued forever... |
3254 "/ because otherwise timeouts might be reissued forever... |
3253 "/ (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[ |
3255 "/ (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[ |
3254 "/ timeoutHandlerProcess interruptWith:block. |
3256 "/ timeoutHandlerProcess interruptWith:block. |
3255 "/ ] ifFalse:[ |
3257 "/ ] ifFalse:[ |
3256 ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , p name , '''') errorPrintCR. |
3258 ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , process name , '''') errorPrintCR. |
3257 "/ ]. |
3259 "/ ]. |
3258 ] ifFalse:[ |
3260 ] ifFalse:[ |
3259 timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal). |
3261 timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal. |
3260 p interruptWith:block |
3262 process interruptWith:block |
3261 ] |
3263 ] |
3262 ] |
3264 ] |
3263 ] |
3265 ] |
3264 ]. |
3266 ]. |
3265 |
3267 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3266 "Modified: / 24-07-2017 / 16:15:36 / stefan" |
3268 |
|
3269 "Modified: / 25-07-2017 / 14:49:46 / stefan" |
3267 "Modified: / 25-07-2017 / 11:27:00 / cg" |
3270 "Modified: / 25-07-2017 / 11:27:00 / cg" |
3268 ! |
3271 ! |
3269 |
3272 |
3270 removeTimedBlock:aBlock |
3273 removeTimedBlock:aBlock |
3271 "remove the argument, aBlock from the list of time-sceduled-blocks." |
3274 "remove the argument, aBlock from the list of time-sceduled-blocks." |
3276 aBlock isNil ifTrue:[^ self]. |
3279 aBlock isNil ifTrue:[^ self]. |
3277 |
3280 |
3278 wasBlocked := OperatingSystem blockInterrupts. |
3281 wasBlocked := OperatingSystem blockInterrupts. |
3279 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
3282 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
3280 (index ~~ 0) ifTrue:[ |
3283 (index ~~ 0) ifTrue:[ |
3281 timeoutArray at:index put:nil. |
3284 timeoutArray at:index put:nil. |
3282 timeoutActionArray at:index put:nil. |
3285 timeoutActionArray at:index put:nil. |
3283 timeoutSemaphoreArray at:index put:nil. |
3286 timeoutSemaphoreArray at:index put:nil. |
3284 timeoutProcessArray at:index put:nil. |
3287 timeoutProcessArray at:index put:nil. |
3285 ]. |
3288 ]. |
3286 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3289 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3287 ! |
3290 ! |
3288 |
3291 |
3289 removeTimeoutForSemaphore:aSemaphore |
3292 removeTimeoutForSemaphore:aSemaphore |
3316 |index "{ Class: SmallInteger }" |
3319 |index "{ Class: SmallInteger }" |
3317 wasBlocked| |
3320 wasBlocked| |
3318 |
3321 |
3319 index := anID. |
3322 index := anID. |
3320 (index > 0) ifTrue:[ |
3323 (index > 0) ifTrue:[ |
3321 wasBlocked := OperatingSystem blockInterrupts. |
3324 wasBlocked := OperatingSystem blockInterrupts. |
3322 |
3325 |
3323 timeoutArray at:index put:nil. |
3326 timeoutArray at:index put:nil. |
3324 timeoutActionArray at:index put:nil. |
3327 timeoutActionArray at:index put:nil. |
3325 timeoutSemaphoreArray at:index put:nil. |
3328 timeoutSemaphoreArray at:index put:nil. |
3326 timeoutProcessArray at:index put:nil. |
3329 timeoutProcessArray at:index put:nil. |
3327 |
3330 |
3328 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3331 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3329 ] |
3332 ] |
3330 |
3333 |
3331 "Created: 23.9.1996 / 14:32:33 / cg" |
3334 "Created: 23.9.1996 / 14:32:33 / cg" |
3332 "Modified: 23.9.1996 / 14:35:09 / cg" |
3335 "Modified: 23.9.1996 / 14:35:09 / cg" |
3333 ! |
3336 ! |
3341 |index "{ Class: SmallInteger }" |
3344 |index "{ Class: SmallInteger }" |
3342 wasBlocked| |
3345 wasBlocked| |
3343 |
3346 |
3344 index := anID. |
3347 index := anID. |
3345 (anID notNil and:[index > 0]) ifTrue:[ |
3348 (anID notNil and:[index > 0]) ifTrue:[ |
3346 wasBlocked := OperatingSystem blockInterrupts. |
3349 wasBlocked := OperatingSystem blockInterrupts. |
3347 |
3350 |
3348 (aBlockOrSemaphore notNil |
3351 (aBlockOrSemaphore notNil |
3349 and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore |
3352 and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore |
3350 and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[ |
3353 and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[ |
3351 'Processor: trying to remove stale timeout id - ignored' errorPrintCR. |
3354 'Processor: trying to remove stale timeout id - ignored' errorPrintCR. |
3352 ] ifFalse:[ |
3355 ] ifFalse:[ |
3353 timeoutArray at:index put:nil. |
3356 timeoutArray at:index put:nil. |
3354 timeoutActionArray at:index put:nil. |
3357 timeoutActionArray at:index put:nil. |
3355 timeoutSemaphoreArray at:index put:nil. |
3358 timeoutSemaphoreArray at:index put:nil. |
3356 timeoutProcessArray at:index put:nil. |
3359 timeoutProcessArray at:index put:nil. |
3357 ]. |
3360 ]. |
3358 |
3361 |
3359 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3362 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
3360 ] |
3363 ] |
3361 ! |
3364 ! |
3362 |
3365 |
3363 timeoutHandlerProcess |
3366 timeoutHandlerProcess |
3364 (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[ |
3367 (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[ |
3365 timeoutHandlerProcess := |
3368 timeoutHandlerProcess := |
3366 [ |
3369 [ |
3367 [ |
3370 [ |
3368 self timeoutHandlerProcessLoop. |
3371 self timeoutHandlerProcessLoop. |
3369 ] ensure:[ |
3372 ] ensure:[ |
3370 timeoutHandlerProcess := nil |
3373 timeoutHandlerProcess := nil |
3371 ]. |
3374 ]. |
3372 ] newProcess. |
3375 ] newProcess. |
3373 |
3376 |
3374 timeoutHandlerProcess |
3377 timeoutHandlerProcess |
3375 priority:TimingPriority; |
3378 priority:TimingPriority; |
3376 name:'timeout handler'; |
3379 name:'timeout handler'; |
3377 beSystemProcess; |
3380 beSystemProcess; |
3378 resume. |
3381 resume. |
3379 ]. |
3382 ]. |
3380 ^ timeoutHandlerProcess. |
3383 ^ timeoutHandlerProcess. |
3381 |
3384 |
3382 "Modified: / 20-07-2006 / 09:52:27 / cg" |
3385 "Modified: / 20-07-2006 / 09:52:27 / cg" |
3383 ! |
3386 ! |
3653 Notice, that at the time of the message, we are still in the context |
3656 Notice, that at the time of the message, we are still in the context |
3654 of whichever process is currently running." |
3657 of whichever process is currently running." |
3655 |
3658 |
3656 gotIOInterrupt := true. |
3659 gotIOInterrupt := true. |
3657 activeProcess ~~ scheduler ifTrue:[ |
3660 activeProcess ~~ scheduler ifTrue:[ |
3658 interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal. |
3661 interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal. |
3659 interruptedProcess := activeProcess. |
3662 interruptedProcess := activeProcess. |
3660 self threadSwitch:scheduler |
3663 self threadSwitch:scheduler |
3661 ] |
3664 ] |
3662 |
3665 |
3663 "Modified: 21.12.1995 / 16:17:40 / stefan" |
3666 "Modified: 21.12.1995 / 16:17:40 / stefan" |
3664 "Modified: 4.8.1997 / 14:23:08 / cg" |
3667 "Modified: 4.8.1997 / 14:23:08 / cg" |
3665 ! |
3668 ! |
3673 an #EBADF error, leading to high-frequency polling and a locked up system. |
3676 an #EBADF error, leading to high-frequency polling and a locked up system. |
3674 (you could still fix things by interrupting on the console and fixing the |
3677 (you could still fix things by interrupting on the console and fixing the |
3675 readFdArray/writeFdArray in the debugger)" |
3678 readFdArray/writeFdArray in the debugger)" |
3676 |
3679 |
3677 readFdArray keysAndValuesDo:[:idx :fd | |
3680 readFdArray keysAndValuesDo:[:idx :fd | |
3678 |result sema| |
3681 |result sema| |
3679 |
3682 |
3680 fd notNil ifTrue:[ |
3683 fd notNil ifTrue:[ |
3681 result := OperatingSystem |
3684 result := OperatingSystem |
3682 selectOnAnyReadable:(Array with:fd) writable:nil exception:nil |
3685 selectOnAnyReadable:(Array with:fd) writable:nil exception:nil |
3683 readableInto:nil writableInto:nil exceptionInto:nil |
3686 readableInto:nil writableInto:nil exceptionInto:nil |
3684 withTimeOut:0. |
3687 withTimeOut:0. |
3685 |
3688 |
3686 result < 0 ifTrue:[ |
3689 result < 0 ifTrue:[ |
3687 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3690 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3688 readFdArray at:idx put:nil. |
3691 readFdArray at:idx put:nil. |
3689 readCheckArray at:idx put:nil. |
3692 readCheckArray at:idx put:nil. |
3690 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
3693 (sema := readSemaphoreArray at:idx) notNil ifTrue:[ |
3691 readSemaphoreArray at:idx put:nil. |
3694 readSemaphoreArray at:idx put:nil. |
3692 self removeTimeoutForSemaphore:sema. |
3695 self removeTimeoutForSemaphore:sema. |
3693 sema signalForAll. |
3696 sema signalForAll. |
3694 ]. |
3697 ]. |
3695 ] |
3698 ] |
3696 ]. |
3699 ]. |
3697 ]. |
3700 ]. |
3698 |
3701 |
3699 writeFdArray keysAndValuesDo:[:idx :fd | |
3702 writeFdArray keysAndValuesDo:[:idx :fd | |
3700 |result sema| |
3703 |result sema| |
3701 |
3704 |
3702 fd notNil ifTrue:[ |
3705 fd notNil ifTrue:[ |
3703 result := OperatingSystem |
3706 result := OperatingSystem |
3704 selectOnAnyReadable:nil writable:(Array with:fd) exception:nil |
3707 selectOnAnyReadable:nil writable:(Array with:fd) exception:nil |
3705 readableInto:nil writableInto:nil exceptionInto:nil |
3708 readableInto:nil writableInto:nil exceptionInto:nil |
3706 withTimeOut:0. |
3709 withTimeOut:0. |
3707 |
3710 |
3708 result < 0 ifTrue:[ |
3711 result < 0 ifTrue:[ |
3709 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3712 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3710 writeFdArray at:idx put:nil. |
3713 writeFdArray at:idx put:nil. |
3711 writeCheckArray at:idx put:nil. |
3714 writeCheckArray at:idx put:nil. |
3712 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
3715 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[ |
3713 writeSemaphoreArray at:idx put:nil. |
3716 writeSemaphoreArray at:idx put:nil. |
3714 self removeTimeoutForSemaphore:sema. |
3717 self removeTimeoutForSemaphore:sema. |
3715 sema signalForAll. |
3718 sema signalForAll. |
3716 ]. |
3719 ]. |
3717 ] |
3720 ] |
3718 ] |
3721 ] |
3719 ]. |
3722 ]. |
3720 |
3723 |
3721 exceptFdArray keysAndValuesDo:[:idx :fd | |
3724 exceptFdArray keysAndValuesDo:[:idx :fd | |
3722 |result sema| |
3725 |result sema| |
3723 |
3726 |
3724 fd notNil ifTrue:[ |
3727 fd notNil ifTrue:[ |
3725 result := OperatingSystem |
3728 result := OperatingSystem |
3726 selectOnAnyReadable:nil writable:nil exception:(Array with:fd) |
3729 selectOnAnyReadable:nil writable:nil exception:(Array with:fd) |
3727 readableInto:nil writableInto:nil exceptionInto:nil |
3730 readableInto:nil writableInto:nil exceptionInto:nil |
3728 withTimeOut:0. |
3731 withTimeOut:0. |
3729 |
3732 |
3730 result < 0 ifTrue:[ |
3733 result < 0 ifTrue:[ |
3731 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3734 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR. |
3732 exceptFdArray at:idx put:nil. |
3735 exceptFdArray at:idx put:nil. |
3733 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
3736 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[ |
3734 exceptSemaphoreArray at:idx put:nil. |
3737 exceptSemaphoreArray at:idx put:nil. |
3735 self removeTimeoutForSemaphore:sema. |
3738 self removeTimeoutForSemaphore:sema. |
3736 sema signalForAll. |
3739 sema signalForAll. |
3737 ]. |
3740 ]. |
3738 ] |
3741 ] |
3739 ] |
3742 ] |
3740 ]. |
3743 ]. |
3741 |
3744 |
3742 |
3745 |
3743 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3746 OperatingSystem isMSWINDOWSlike ifTrue:[ |
3744 "/ |
3747 "/ |
3745 "/ win32 does a WaitForMultipleObjects in select... |
3748 "/ win32 does a WaitForMultipleObjects in select... |
3746 "/ unix waits for SIGCHLD |
3749 "/ unix waits for SIGCHLD |
3747 "/ |
3750 "/ |
3748 osChildExitActions keysDo:[:eachPid | |
3751 osChildExitActions keysDo:[:eachPid | |
3749 |result sema| |
3752 |result sema| |
3750 |
3753 |
3751 eachPid notNil ifTrue:[ |
3754 eachPid notNil ifTrue:[ |
3752 result := OperatingSystem |
3755 result := OperatingSystem |
3753 selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid) |
3756 selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid) |
3754 readableInto:nil writableInto:nil exceptionInto:nil |
3757 readableInto:nil writableInto:nil exceptionInto:nil |
3755 withTimeOut:0. |
3758 withTimeOut:0. |
3756 |
3759 |
3757 result < 0 ifTrue:[ |
3760 result < 0 ifTrue:[ |
3758 'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR. |
3761 'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR. |
3759 osChildExitActions safeRemoveKey:eachPid. |
3762 osChildExitActions safeRemoveKey:eachPid. |
3760 ] |
3763 ] |
3761 ] |
3764 ] |
3762 ]. |
3765 ]. |
3763 ]. |
3766 ]. |
3764 |
3767 |
3765 "Modified: 12.4.1996 / 09:32:58 / stefan" |
3768 "Modified: 12.4.1996 / 09:32:58 / stefan" |
3766 "Modified: 27.1.1997 / 20:09:27 / cg" |
3769 "Modified: 27.1.1997 / 20:09:27 / cg" |
3767 ! |
3770 ! |
3787 If there were many, the list should be kept sorted ... keeping deltas |
3790 If there were many, the list should be kept sorted ... keeping deltas |
3788 to next (as in Unix kernel)" |
3791 to next (as in Unix kernel)" |
3789 |
3792 |
3790 n := timeoutArray size. |
3793 n := timeoutArray size. |
3791 1 to:n do:[:index | |
3794 1 to:n do:[:index | |
3792 aTime := timeoutArray at:index. |
3795 aTime := timeoutArray at:index. |
3793 aTime notNil ifTrue:[ |
3796 aTime notNil ifTrue:[ |
3794 now isNil ifTrue:[ |
3797 now isNil ifTrue:[ |
3795 now := OperatingSystem getMillisecondTime. |
3798 now := OperatingSystem getMillisecondTime. |
3796 ]. |
3799 ]. |
3797 delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now. |
3800 delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now. |
3798 delta <= 0 ifTrue:[ |
3801 delta <= 0 ifTrue:[ |
3799 ^ 0. |
3802 ^ 0. |
3800 ]. |
3803 ]. |
3801 minDelta isNil ifTrue:[ |
3804 minDelta isNil ifTrue:[ |
3802 minDelta := delta |
3805 minDelta := delta |
3803 ] ifFalse:[ |
3806 ] ifFalse:[ |
3804 minDelta := minDelta min:delta |
3807 minDelta := minDelta min:delta |
3805 ] |
3808 ] |
3806 ] |
3809 ] |
3807 ]. |
3810 ]. |
3808 minDelta isNil ifTrue:[ |
3811 minDelta isNil ifTrue:[ |
3809 "this is safe, since always called with interruptsBlocked" |
3812 "this is safe, since always called with interruptsBlocked" |
3810 anyTimeouts := false. |
3813 anyTimeouts := false. |
3811 ]. |
3814 ]. |
3812 |
3815 |
3813 ^ minDelta |
3816 ^ minDelta |
3814 ! |
3817 ! |
3815 |
3818 |