10 hereby transferred. |
10 hereby transferred. |
11 " |
11 " |
12 "{ Package: 'stx:libbasic' }" |
12 "{ Package: 'stx:libbasic' }" |
13 |
13 |
14 Object subclass:#ProcessorScheduler |
14 Object subclass:#ProcessorScheduler |
15 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
15 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
16 activeProcessId currentPriority readFdArray readSemaphoreArray |
16 activeProcessId currentPriority readFdArray readSemaphoreArray |
17 readCheckArray writeFdArray writeSemaphoreArray writeCheckArray |
17 readCheckArray writeFdArray writeSemaphoreArray writeCheckArray |
18 timeoutArray timeoutActionArray timeoutProcessArray |
18 timeoutArray timeoutActionArray timeoutProcessArray |
19 timeoutSemaphoreArray idleActions anyTimeouts dispatching |
19 timeoutSemaphoreArray idleActions anyTimeouts dispatching |
20 interruptedProcess useIOInterrupts gotIOInterrupt |
20 interruptedProcess useIOInterrupts gotIOInterrupt |
21 osChildExitActions gotChildSignalInterrupt |
21 osChildExitActions gotChildSignalInterrupt |
22 exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess |
22 exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess |
23 supportDynamicPriorities scheduledProcesses preWaitActions |
23 supportDynamicPriorities scheduledProcesses preWaitActions |
24 timeoutHandlerProcess' |
24 timeoutHandlerProcess' |
25 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
25 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
26 UserSchedulingPriority UserInterruptPriority TimingPriority |
26 UserSchedulingPriority UserInterruptPriority TimingPriority |
27 HighestPriority SchedulingPriority MaxNumberOfProcesses |
27 HighestPriority SchedulingPriority MaxNumberOfProcesses |
28 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
28 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
29 EventPollingInterval' |
29 EventPollingInterval' |
30 poolDictionaries:'' |
30 poolDictionaries:'' |
31 category:'Kernel-Processes' |
31 category:'Kernel-Processes' |
32 ! |
32 ! |
33 |
33 |
34 !ProcessorScheduler class methodsFor:'documentation'! |
34 !ProcessorScheduler class methodsFor:'documentation'! |
35 |
35 |
36 copyright |
36 copyright |
37 " |
37 " |
38 COPYRIGHT (c) 1993 by Claus Gittinger |
38 COPYRIGHT (c) 1993 by Claus Gittinger |
39 All Rights Reserved |
39 All Rights Reserved |
40 |
40 |
41 This software is furnished under a license and may be used |
41 This software is furnished under a license and may be used |
42 only in accordance with the terms of that license and with the |
42 only in accordance with the terms of that license and with the |
43 inclusion of the above copyright notice. This software may not |
43 inclusion of the above copyright notice. This software may not |
44 be provided or otherwise made available to, or used by, any |
44 be provided or otherwise made available to, or used by, any |
207 event. |
207 event. |
208 Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which |
208 Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which |
209 allows for critical processes to run unaffected to completion. |
209 allows for critical processes to run unaffected to completion. |
210 |
210 |
211 WARNING: |
211 WARNING: |
212 timesliced priority scheduling is an experimental feature. There is no warranty, |
212 timesliced priority scheduling is an experimental feature. There is no warranty, |
213 (at the moment), that the system runs reliable in this mode. |
213 (at the moment), that the system runs reliable in this mode. |
214 The problem is, that shared collections may now be easily modified by other |
214 The problem is, that shared collections may now be easily modified by other |
215 processes, running at the same time. |
215 processes, running at the same time. |
216 The class library has being investigated for such possible trouble spots |
216 The class library has being investigated for such possible trouble spots |
217 (we have eliminated many weak spots, and added critical regions at many places, |
217 (we have eliminated many weak spots, and added critical regions at many places, |
218 but cannot guarantee that all of them have been found so far ...) |
218 but cannot guarantee that all of them have been found so far ...) |
219 We found that many existing public domain programs are not prepared for |
219 We found that many existing public domain programs are not prepared for |
220 being interrupted by a same-prio process and therefore may corrupt their |
220 being interrupted by a same-prio process and therefore may corrupt their |
221 data. If in doubt, disable this fefature. |
221 data. If in doubt, disable this fefature. |
222 |
222 |
223 We think, that the timeSlicer is a useful add-on and that the system is fit enough |
223 We think, that the timeSlicer is a useful add-on and that the system is fit enough |
224 for it to be evaluated, therefore, its included. |
224 for it to be evaluated, therefore, its included. |
225 However, use it at your own risk. |
225 However, use it at your own risk. |
226 |
226 |
227 To demonstrate the effect of timeSlicing, do the following: |
227 To demonstrate the effect of timeSlicing, do the following: |
228 |
228 |
229 - disable timeSlicing (in the launchers misc-settings menu) |
229 - disable timeSlicing (in the launchers misc-settings menu) |
230 - open a workSpace |
230 - open a workSpace |
231 - in the workspace, evaluate: |
231 - in the workspace, evaluate: |
232 [true] whileTrue:[1000 factorial] |
232 [true] whileTrue:[1000 factorial] |
233 |
233 |
234 now, (since the workSpace runs at the same prio as other window-processes), |
234 now, (since the workSpace runs at the same prio as other window-processes), |
235 other views do no longer react - all CPU is used up by the workSpace. |
235 other views do no longer react - all CPU is used up by the workSpace. |
236 However, CTRL-C in the workspace is still possible to stop the endless loop, |
236 However, CTRL-C in the workspace is still possible to stop the endless loop, |
237 since that is handled by the (higher prio) event dispatcher process. |
237 since that is handled by the (higher prio) event dispatcher process. |
308 by sending #terminate." |
308 by sending #terminate." |
309 |
309 |
310 |id sz "{ Class: SmallInteger }"| |
310 |id sz "{ Class: SmallInteger }"| |
311 |
311 |
312 something == #ElementExpired ifTrue:[ |
312 something == #ElementExpired ifTrue:[ |
313 sz := KnownProcessIds size. |
313 sz := KnownProcessIds size. |
314 1 to:sz do:[:index | |
314 1 to:sz do:[:index | |
315 "/ (KnownProcesses at:index) isNil ifTrue:[ |
315 "/ (KnownProcesses at:index) isNil ifTrue:[ |
316 (KnownProcesses at:index) == 0 ifTrue:[ |
316 (KnownProcesses at:index) == 0 ifTrue:[ |
317 id := KnownProcessIds at:index. |
317 id := KnownProcessIds at:index. |
318 id notNil ifTrue:[ |
318 id notNil ifTrue:[ |
319 'Processor [warning]: terminating thread ' errorPrint. |
319 'Processor [warning]: terminating thread ' errorPrint. |
320 id errorPrint. |
320 id errorPrint. |
321 ' (no longer refd)' errorPrintCR. |
321 ' (no longer refd)' errorPrintCR. |
322 |
322 |
323 self threadDestroy:id. |
323 self threadDestroy:id. |
324 KnownProcessIds at:index put:nil. |
324 KnownProcessIds at:index put:nil. |
325 ]. |
325 ]. |
326 KnownProcesses at:index put:nil. |
326 KnownProcesses at:index put:nil. |
327 ] |
327 ] |
328 ] |
328 ] |
329 ] |
329 ] |
330 |
330 |
331 "Created: 7.1.1997 / 16:45:42 / stefan" |
331 "Created: 7.1.1997 / 16:45:42 / stefan" |
332 "Modified: 10.1.1997 / 19:10:48 / cg" |
332 "Modified: 10.1.1997 / 19:10:48 / cg" |
333 ! ! |
333 ! ! |
338 "physical creation of a process. |
338 "physical creation of a process. |
339 (warning: low level entry, no administration done). |
339 (warning: low level entry, no administration done). |
340 This may raise an exception, if a VM process could not be created." |
340 This may raise an exception, if a VM process could not be created." |
341 |
341 |
342 MaxNumberOfProcesses notNil ifTrue:[ |
342 MaxNumberOfProcesses notNil ifTrue:[ |
343 KnownProcessIds size >= MaxNumberOfProcesses ifTrue:[ |
343 KnownProcessIds size >= MaxNumberOfProcesses ifTrue:[ |
344 (KnownProcessIds count:[:el | el notNil]) >= MaxNumberOfProcesses ifTrue:[ |
344 (KnownProcessIds count:[:el | el notNil]) >= MaxNumberOfProcesses ifTrue:[ |
345 " |
345 " |
346 the number of processes has reached the (soft) limit. |
346 the number of processes has reached the (soft) limit. |
347 This limit prevents runaway programs from creating too many |
347 This limit prevents runaway programs from creating too many |
348 processes. If you continue in the debugger, the process will be |
348 processes. If you continue in the debugger, the process will be |
349 created as usual. If you dont want this, abort or terminate. |
349 created as usual. If you dont want this, abort or terminate. |
350 " |
350 " |
351 self error:'too many processes'. |
351 self error:'too many processes'. |
352 ] |
352 ] |
353 ] |
353 ] |
354 ]. |
354 ]. |
355 |
355 |
356 %{ |
356 %{ |
357 int tid; |
357 int tid; |
358 extern int __threadCreate(); |
358 extern int __threadCreate(); |
359 |
359 |
360 tid = __threadCreate(aProcess, |
360 tid = __threadCreate(aProcess, |
361 0 /* stackSize: no longer needed */, |
361 0 /* stackSize: no longer needed */, |
362 __isSmallInteger(id) ? __intVal(id) /* assign id */ |
362 __isSmallInteger(id) ? __intVal(id) /* assign id */ |
363 : -1 /* let VM assign one */ ); |
363 : -1 /* let VM assign one */ ); |
364 if (tid) { |
364 if (tid) { |
365 RETURN ( __mkSmallInteger(tid)); |
365 RETURN ( __mkSmallInteger(tid)); |
366 } |
366 } |
367 %} |
367 %} |
368 . |
368 . |
369 " |
369 " |
370 arrive here, if creation of process in VM failed. |
370 arrive here, if creation of process in VM failed. |
472 |idx "{Class: SmallInteger }" |
472 |idx "{Class: SmallInteger }" |
473 wasBlocked| |
473 wasBlocked| |
474 |
474 |
475 wasBlocked := OperatingSystem blockInterrupts. |
475 wasBlocked := OperatingSystem blockInterrupts. |
476 useIOInterrupts ifTrue:[ |
476 useIOInterrupts ifTrue:[ |
477 OperatingSystem disableIOInterruptsOn:aFileDescriptor |
477 OperatingSystem disableIOInterruptsOn:aFileDescriptor |
478 ]. |
478 ]. |
479 |
479 |
480 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
480 idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1. |
481 idx ~~ 0 ifTrue:[ |
481 idx ~~ 0 ifTrue:[ |
482 readFdArray at:idx put:nil. |
482 readFdArray at:idx put:nil. |
483 readCheckArray at:idx put:nil. |
483 readCheckArray at:idx put:nil. |
484 readSemaphoreArray at:idx put:nil |
484 readSemaphoreArray at:idx put:nil |
485 ]. |
485 ]. |
486 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1. |
486 idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1. |
487 idx ~~ 0 ifTrue:[ |
487 idx ~~ 0 ifTrue:[ |
488 writeFdArray at:idx put:nil. |
488 writeFdArray at:idx put:nil. |
489 writeCheckArray at:idx put:nil. |
489 writeCheckArray at:idx put:nil. |
490 writeSemaphoreArray at:idx put:nil |
490 writeSemaphoreArray at:idx put:nil |
491 ]. |
491 ]. |
492 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
492 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
493 |
493 |
494 "Modified: 4.8.1997 / 15:16:00 / cg" |
494 "Modified: 4.8.1997 / 15:16:00 / cg" |
495 ! |
495 ! |
501 |
501 |
502 |idx "{Class: SmallInteger }" |
502 |idx "{Class: SmallInteger }" |
503 wasBlocked| |
503 wasBlocked| |
504 |
504 |
505 aFileDescriptor < 0 ifTrue:[ |
505 aFileDescriptor < 0 ifTrue:[ |
506 'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR. |
506 'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR. |
507 thisContext fullPrintAll. |
507 thisContext fullPrintAll. |
508 ^ self |
508 ^ self |
509 ]. |
509 ]. |
510 |
510 |
511 wasBlocked := OperatingSystem blockInterrupts. |
511 wasBlocked := OperatingSystem blockInterrupts. |
512 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
512 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
513 idx := readFdArray identityIndexOf:nil startingAt:1. |
513 idx := readFdArray identityIndexOf:nil startingAt:1. |
514 idx ~~ 0 ifTrue:[ |
514 idx ~~ 0 ifTrue:[ |
515 readFdArray at:idx put:aFileDescriptor. |
515 readFdArray at:idx put:aFileDescriptor. |
516 readCheckArray at:idx put:aBlock. |
516 readCheckArray at:idx put:aBlock. |
517 readSemaphoreArray at:idx put:nil |
517 readSemaphoreArray at:idx put:nil |
518 ] ifFalse:[ |
518 ] ifFalse:[ |
519 readFdArray := readFdArray copyWith:aFileDescriptor. |
519 readFdArray := readFdArray copyWith:aFileDescriptor. |
520 readCheckArray := readCheckArray copyWith:aBlock. |
520 readCheckArray := readCheckArray copyWith:aBlock. |
521 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
521 readSemaphoreArray := readSemaphoreArray copyWith:nil. |
522 ]. |
522 ]. |
523 useIOInterrupts ifTrue:[ |
523 useIOInterrupts ifTrue:[ |
524 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
524 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
525 ]. |
525 ]. |
526 |
526 |
527 ]. |
527 ]. |
528 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
528 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
529 |
529 |
530 "Modified: 4.8.1997 / 15:17:28 / cg" |
530 "Modified: 4.8.1997 / 15:17:28 / cg" |
879 timeoutProcessArray := Array new:5. |
879 timeoutProcessArray := Array new:5. |
880 |
880 |
881 anyTimeouts := false. |
881 anyTimeouts := false. |
882 dispatching := false. |
882 dispatching := false. |
883 exitWhenNoMoreUserProcesses isNil ifTrue:[ |
883 exitWhenNoMoreUserProcesses isNil ifTrue:[ |
884 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
884 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
885 ]. |
885 ]. |
886 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
886 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
887 gotIOInterrupt := false. |
887 gotIOInterrupt := false. |
888 osChildExitActions := Dictionary new. |
888 osChildExitActions := Dictionary new. |
889 gotChildSignalInterrupt := false. |
889 gotChildSignalInterrupt := false. |
936 " |
936 " |
937 lay all processes to rest, collect restartable ones |
937 lay all processes to rest, collect restartable ones |
938 " |
938 " |
939 processesToRestart := OrderedCollection new. |
939 processesToRestart := OrderedCollection new. |
940 KnownProcesses do:[:p | |
940 KnownProcesses do:[:p | |
941 (p notNil and:[p ~~ 0]) ifTrue:[ |
941 (p notNil and:[p ~~ 0]) ifTrue:[ |
942 "how, exactly should this be done ?" |
942 "how, exactly should this be done ?" |
943 |
943 |
944 p isRestartable == true ifTrue:[ |
944 p isRestartable == true ifTrue:[ |
945 p nextLink:nil. |
945 p nextLink:nil. |
946 processesToRestart add:p |
946 processesToRestart add:p |
947 ] ifFalse:[ |
947 ] ifFalse:[ |
948 p setId:nil state:#dead |
948 p setId:nil state:#dead |
949 ] |
949 ] |
950 ]. |
950 ]. |
951 ]. |
951 ]. |
952 scheduler setId:nil state:#dead. |
952 scheduler setId:nil state:#dead. |
953 |
953 |
954 " |
954 " |
955 now, start from scratch |
955 now, start from scratch |
956 " |
956 " |
957 KnownProcesses := nil. |
957 KnownProcesses := nil. |
958 self initialize. |
958 self initialize. |
959 |
959 |
960 processesToRestart do:[:p | |
960 processesToRestart do:[:p | |
961 p imageRestart |
961 p imageRestart |
962 ] |
962 ] |
963 |
963 |
964 "Modified: / 7.6.1998 / 02:23:56 / cg" |
964 "Modified: / 7.6.1998 / 02:23:56 / cg" |
965 ! ! |
965 ! ! |
966 |
966 |
1456 |
1456 |
1457 wasBlocked := OperatingSystem blockInterrupts. |
1457 wasBlocked := OperatingSystem blockInterrupts. |
1458 index := 1. |
1458 index := 1. |
1459 sz := KnownProcessIds size. |
1459 sz := KnownProcessIds size. |
1460 [index <= sz] whileTrue:[ |
1460 [index <= sz] whileTrue:[ |
1461 (KnownProcesses at:index) isNil ifTrue:[ |
1461 (KnownProcesses at:index) isNil ifTrue:[ |
1462 oldId := KnownProcessIds at:index. |
1462 oldId := KnownProcessIds at:index. |
1463 oldId notNil ifTrue:[ |
1463 oldId notNil ifTrue:[ |
1464 self class threadDestroy:oldId. |
1464 self class threadDestroy:oldId. |
1465 ]. |
1465 ]. |
1466 KnownProcesses at:index put:aProcess. |
1466 KnownProcesses at:index put:aProcess. |
1467 KnownProcessIds at:index put:aProcess id. |
1467 KnownProcessIds at:index put:aProcess id. |
1468 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1468 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1469 ^ self |
1469 ^ self |
1470 ]. |
1470 ]. |
1471 index := index + 1 |
1471 index := index + 1 |
1472 ]. |
1472 ]. |
1473 |
1473 |
1474 KnownProcessIds grow:index. |
1474 KnownProcessIds grow:index. |
1475 KnownProcessIds at:index put:aProcess id. |
1475 KnownProcessIds at:index put:aProcess id. |
1476 |
1476 |
1477 oldSize := KnownProcesses size. |
1477 oldSize := KnownProcesses size. |
1478 (index > oldSize) ifTrue:[ |
1478 (index > oldSize) ifTrue:[ |
1479 newShadow := WeakArray new:(oldSize * 2). |
1479 newShadow := WeakArray new:(oldSize * 2). |
1480 newShadow addDependent:self class. |
1480 newShadow addDependent:self class. |
1481 newShadow replaceFrom:1 with:KnownProcesses. |
1481 newShadow replaceFrom:1 with:KnownProcesses. |
1482 KnownProcesses := newShadow |
1482 KnownProcesses := newShadow |
1483 ]. |
1483 ]. |
1484 KnownProcesses at:index put:aProcess. |
1484 KnownProcesses at:index put:aProcess. |
1485 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1485 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1486 |
1486 |
1487 "Modified: 7.1.1997 / 16:48:39 / stefan" |
1487 "Modified: 7.1.1997 / 16:48:39 / stefan" |
1597 prio := HighestPriority. |
1597 prio := HighestPriority. |
1598 wasBlocked := OperatingSystem blockInterrupts. |
1598 wasBlocked := OperatingSystem blockInterrupts. |
1599 |
1599 |
1600 listArray := quiescentProcessLists. |
1600 listArray := quiescentProcessLists. |
1601 [prio >= 1] whileTrue:[ |
1601 [prio >= 1] whileTrue:[ |
1602 l := listArray at:prio. |
1602 l := listArray at:prio. |
1603 l notNil ifTrue:[ |
1603 l notNil ifTrue:[ |
1604 l isEmpty ifFalse:[ |
1604 l isEmpty ifFalse:[ |
1605 p := l first. |
1605 p := l first. |
1606 " |
1606 " |
1607 if it got corrupted somehow ... |
1607 if it got corrupted somehow ... |
1608 " |
1608 " |
1609 p id isNil ifTrue:[ |
1609 p id isNil ifTrue:[ |
1610 'Processor [warning]: process with nil id removed' errorPrintCR. |
1610 'Processor [warning]: process with nil id removed' errorPrintCR. |
1611 l removeFirst. |
1611 l removeFirst. |
1612 p := nil. |
1612 p := nil. |
1613 ]. |
1613 ]. |
1614 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1614 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1615 ^ p |
1615 ^ p |
1616 ] |
1616 ] |
1617 ]. |
1617 ]. |
1618 prio := prio - 1 |
1618 prio := prio - 1 |
1619 ]. |
1619 ]. |
1620 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1620 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1621 ^ nil |
1621 ^ nil |
1622 |
1622 |
1623 "Modified: 12.2.1997 / 12:41:49 / cg" |
1623 "Modified: 12.2.1997 / 12:41:49 / cg" |
1756 "ignore, if process is already dead" |
1756 "ignore, if process is already dead" |
1757 (aProcess isNil or:[aProcess id isNil]) ifTrue:[^ self]. |
1757 (aProcess isNil or:[aProcess id isNil]) ifTrue:[^ self]. |
1758 |
1758 |
1759 |
1759 |
1760 aProcess == activeProcess ifTrue:[ |
1760 aProcess == activeProcess ifTrue:[ |
1761 "special handling for waiting schedulers" |
1761 "special handling for waiting schedulers" |
1762 aProcess == scheduler ifTrue:[ |
1762 aProcess == scheduler ifTrue:[ |
1763 suspendScheduler := false. |
1763 suspendScheduler := false. |
1764 ]. |
1764 ]. |
1765 ^ self |
1765 ^ self |
1766 ]. |
1766 ]. |
1767 |
1767 |
1768 wasBlocked := OperatingSystem blockInterrupts. |
1768 wasBlocked := OperatingSystem blockInterrupts. |
1769 |
1769 |
1770 pri := aProcess priority. |
1770 pri := aProcess priority. |
1771 |
1771 |
1772 l := quiescentProcessLists at:pri. |
1772 l := quiescentProcessLists at:pri. |
1773 "if already running, ignore" |
1773 "if already running, ignore" |
1774 l notNil ifTrue:[ |
1774 l notNil ifTrue:[ |
1775 (l identityIndexOf:aProcess) ~~ 0 ifTrue:[ |
1775 (l identityIndexOf:aProcess) ~~ 0 ifTrue:[ |
1776 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1776 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1777 ^ self |
1777 ^ self |
1778 ] |
1778 ] |
1779 ] ifFalse:[ |
1779 ] ifFalse:[ |
1780 l := LinkedList new. |
1780 l := LinkedList new. |
1781 quiescentProcessLists at:pri put:l. |
1781 quiescentProcessLists at:pri put:l. |
1782 ]. |
1782 ]. |
1783 l addLast:aProcess. |
1783 l addLast:aProcess. |
1784 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1784 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1785 |
1785 |
1786 aProcess state:#run |
1786 aProcess state:#run |
2058 |
2058 |
2059 " |
2059 " |
2060 debugging consistency check - will be removed later |
2060 debugging consistency check - will be removed later |
2061 " |
2061 " |
2062 activeProcess priority ~~ currentPriority ifTrue:[ |
2062 activeProcess priority ~~ currentPriority ifTrue:[ |
2063 'Processor [warning]: process changed its priority' errorPrintCR. |
2063 'Processor [warning]: process changed its priority' errorPrintCR. |
2064 currentPriority := activeProcess priority. |
2064 currentPriority := activeProcess priority. |
2065 ]. |
2065 ]. |
2066 |
2066 |
2067 l := quiescentProcessLists at:currentPriority. |
2067 l := quiescentProcessLists at:currentPriority. |
2068 sz := l size. |
2068 sz := l size. |
2069 |
2069 |
2070 " |
2070 " |
2071 debugging consistency checks - will be removed later |
2071 debugging consistency checks - will be removed later |
2072 " |
2072 " |
2073 sz == 0 ifTrue:[ |
2073 sz == 0 ifTrue:[ |
2074 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2074 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2075 'Processor [warning]: empty runnable list' errorPrintCR. |
2075 'Processor [warning]: empty runnable list' errorPrintCR. |
2076 ^ self |
2076 ^ self |
2077 ]. |
2077 ]. |
2078 |
2078 |
2079 " |
2079 " |
2080 check if the running process is not the only one |
2080 check if the running process is not the only one |
2081 " |
2081 " |
2082 sz ~~ 1 ifTrue:[ |
2082 sz ~~ 1 ifTrue:[ |
2083 " |
2083 " |
2084 bring running process to the end |
2084 bring running process to the end |
2085 " |
2085 " |
2086 l removeFirst. |
2086 l removeFirst. |
2087 l addLast:activeProcess. |
2087 l addLast:activeProcess. |
2088 |
2088 |
2089 " |
2089 " |
2090 and switch to first in the list |
2090 and switch to first in the list |
2091 " |
2091 " |
2092 self threadSwitch:(l first). |
2092 self threadSwitch:(l first). |
2093 ]. |
2093 ]. |
2094 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2094 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2095 |
2095 |
2096 "Modified: 10.1.1997 / 18:04:35 / cg" |
2096 "Modified: 10.1.1997 / 18:04:35 / cg" |
2097 ! ! |
2097 ! ! |
2102 "recompute dynamic priorities." |
2102 "recompute dynamic priorities." |
2103 |
2103 |
2104 |processesDecreased processesToIncrease| |
2104 |processesDecreased processesToIncrease| |
2105 |
2105 |
2106 scheduledProcesses notNil ifTrue:[ |
2106 scheduledProcesses notNil ifTrue:[ |
2107 "/ this is written a bit cryptic - to avoid creation |
2107 "/ this is written a bit cryptic - to avoid creation |
2108 "/ of garbage objects (Id'sets) if possible. |
2108 "/ of garbage objects (Id'sets) if possible. |
2109 "/ since this runs 50 times a second and most of the |
2109 "/ since this runs 50 times a second and most of the |
2110 "/ time, no rescheduling is req'd |
2110 "/ time, no rescheduling is req'd |
2111 |
2111 |
2112 scheduledProcesses do:[:aProcess | |
2112 scheduledProcesses do:[:aProcess | |
2113 |range prio| |
2113 |range prio| |
2114 |
2114 |
2115 "/ decrease priority of processes that did run |
2115 "/ decrease priority of processes that did run |
2116 (range := aProcess priorityRange) notNil ifTrue:[ |
2116 (range := aProcess priorityRange) notNil ifTrue:[ |
2117 aProcess priority > range start ifTrue:[ |
2117 aProcess priority > range start ifTrue:[ |
2118 processesDecreased isNil ifTrue:[ |
2118 processesDecreased isNil ifTrue:[ |
2119 processesDecreased := IdentitySet new. |
2119 processesDecreased := IdentitySet new. |
2120 ]. |
2120 ]. |
2121 processesDecreased add:aProcess. |
2121 processesDecreased add:aProcess. |
2122 ] |
2122 ] |
2123 ] |
2123 ] |
2124 ]. |
2124 ]. |
2125 |
2125 |
2126 processesDecreased notNil ifTrue:[ |
2126 processesDecreased notNil ifTrue:[ |
2127 processesDecreased do:[:aProcess | |
2127 processesDecreased do:[:aProcess | |
2128 |newPri| |
2128 |newPri| |
2129 |
2129 |
2130 "/ newPri := aProcess priority - 1. |
2130 "/ newPri := aProcess priority - 1. |
2131 newPri := aProcess priorityRange start. |
2131 newPri := aProcess priorityRange start. |
2132 self changePriority:newPri for:aProcess. |
2132 self changePriority:newPri for:aProcess. |
2133 ]. |
2133 ]. |
2134 ]. |
2134 ]. |
2135 |
2135 |
2136 "/ and increase all prios of those that did not run, but are runnable |
2136 "/ and increase all prios of those that did not run, but are runnable |
2137 |
2137 |
2138 TimeSlicingPriorityLimit to:1 by:-1 do:[:i | |
2138 TimeSlicingPriorityLimit to:1 by:-1 do:[:i | |
2139 |list| |
2139 |list| |
2140 |
2140 |
2141 (list := quiescentProcessLists at:i) size > 0 ifTrue:[ |
2141 (list := quiescentProcessLists at:i) size > 0 ifTrue:[ |
2142 list do:[:aProcess | |
2142 list do:[:aProcess | |
2143 |range prio| |
2143 |range prio| |
2144 |
2144 |
2145 (range := aProcess priorityRange) notNil ifTrue:[ |
2145 (range := aProcess priorityRange) notNil ifTrue:[ |
2146 (processesDecreased isNil |
2146 (processesDecreased isNil |
2147 or:[(processesDecreased includes:aProcess) not]) ifTrue:[ |
2147 or:[(processesDecreased includes:aProcess) not]) ifTrue:[ |
2148 aProcess priority < range stop ifTrue:[ |
2148 aProcess priority < range stop ifTrue:[ |
2149 processesToIncrease isNil ifTrue:[ |
2149 processesToIncrease isNil ifTrue:[ |
2150 processesToIncrease := IdentitySet new. |
2150 processesToIncrease := IdentitySet new. |
2151 ]. |
2151 ]. |
2152 processesToIncrease add:aProcess |
2152 processesToIncrease add:aProcess |
2153 ] |
2153 ] |
2154 ] |
2154 ] |
2155 ] |
2155 ] |
2156 ] |
2156 ] |
2157 ] |
2157 ] |
2158 ]. |
2158 ]. |
2159 processesToIncrease notNil ifTrue:[ |
2159 processesToIncrease notNil ifTrue:[ |
2160 processesToIncrease do:[:aProcess | |
2160 processesToIncrease do:[:aProcess | |
2161 self changePriority:(aProcess priority + 1) for:aProcess. |
2161 self changePriority:(aProcess priority + 1) for:aProcess. |
2162 ]. |
2162 ]. |
2163 ]. |
2163 ]. |
2164 ]. |
2164 ]. |
2165 |
2165 |
2166 "Modified: / 21.9.1998 / 09:07:54 / cg" |
2166 "Modified: / 21.9.1998 / 09:07:54 / cg" |
2167 ! |
2167 ! |
2168 |
2168 |
2186 wasBlocked := OperatingSystem blockInterrupts. |
2186 wasBlocked := OperatingSystem blockInterrupts. |
2187 |
2187 |
2188 i := TimeSlicingPriorityLimit. |
2188 i := TimeSlicingPriorityLimit. |
2189 [(i > 0) and:[(list := quiescentProcessLists at:i) size <= 1]] whileTrue: [i := i - 1]. |
2189 [(i > 0) and:[(list := quiescentProcessLists at:i) size <= 1]] whileTrue: [i := i - 1]. |
2190 i ~~ 0 ifTrue: [ |
2190 i ~~ 0 ifTrue: [ |
2191 "/ shuffle that list |
2191 "/ shuffle that list |
2192 list addLast:(list removeFirst). |
2192 list addLast:(list removeFirst). |
2193 ]. |
2193 ]. |
2194 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2194 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2195 |
2195 |
2196 "Modified: / 4.8.1998 / 00:13:32 / cg" |
2196 "Modified: / 4.8.1998 / 00:13:32 / cg" |
2197 ! |
2197 ! |
2295 wasBlocked fd| |
2295 wasBlocked fd| |
2296 |
2296 |
2297 wasBlocked := OperatingSystem blockInterrupts. |
2297 wasBlocked := OperatingSystem blockInterrupts. |
2298 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2298 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2299 [idx ~~ 0] whileTrue:[ |
2299 [idx ~~ 0] whileTrue:[ |
2300 useIOInterrupts ifTrue:[ |
2300 useIOInterrupts ifTrue:[ |
2301 fd := readFdArray at:idx. |
2301 fd := readFdArray at:idx. |
2302 fd notNil ifTrue:[ |
2302 fd notNil ifTrue:[ |
2303 OperatingSystem disableIOInterruptsOn:fd |
2303 OperatingSystem disableIOInterruptsOn:fd |
2304 ]. |
2304 ]. |
2305 ]. |
2305 ]. |
2306 readFdArray at:idx put:nil. |
2306 readFdArray at:idx put:nil. |
2307 readSemaphoreArray at:idx put:nil. |
2307 readSemaphoreArray at:idx put:nil. |
2308 readCheckArray at:idx put:nil. |
2308 readCheckArray at:idx put:nil. |
2309 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2309 idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2310 ]. |
2310 ]. |
2311 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2311 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2312 [idx ~~ 0] whileTrue:[ |
2312 [idx ~~ 0] whileTrue:[ |
2313 useIOInterrupts ifTrue:[ |
2313 useIOInterrupts ifTrue:[ |
2314 fd := writeFdArray at:idx. |
2314 fd := writeFdArray at:idx. |
2315 fd notNil ifTrue:[ |
2315 fd notNil ifTrue:[ |
2316 OperatingSystem disableIOInterruptsOn:fd |
2316 OperatingSystem disableIOInterruptsOn:fd |
2317 ]. |
2317 ]. |
2318 ]. |
2318 ]. |
2319 writeFdArray at:idx put:nil. |
2319 writeFdArray at:idx put:nil. |
2320 writeSemaphoreArray at:idx put:nil. |
2320 writeSemaphoreArray at:idx put:nil. |
2321 writeCheckArray at:idx put:nil. |
2321 writeCheckArray at:idx put:nil. |
2322 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2322 idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2323 ]. |
2323 ]. |
2324 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2324 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2325 [idx ~~ 0] whileTrue:[ |
2325 [idx ~~ 0] whileTrue:[ |
2326 timeoutArray at:idx put:nil. |
2326 timeoutArray at:idx put:nil. |
2327 timeoutSemaphoreArray at:idx put:nil. |
2327 timeoutSemaphoreArray at:idx put:nil. |
2328 timeoutActionArray at:idx put:nil. |
2328 timeoutActionArray at:idx put:nil. |
2329 timeoutProcessArray at:idx put:nil. |
2329 timeoutProcessArray at:idx put:nil. |
2330 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2330 idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1. |
2331 ]. |
2331 ]. |
2332 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2332 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2333 |
2333 |
2334 "Modified: 4.8.1997 / 15:19:33 / cg" |
2334 "Modified: 4.8.1997 / 15:19:33 / cg" |
2335 ! |
2335 ! |
2378 wasBlocked| |
2378 wasBlocked| |
2379 |
2379 |
2380 wasBlocked := OperatingSystem blockInterrupts. |
2380 wasBlocked := OperatingSystem blockInterrupts. |
2381 index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2381 index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1. |
2382 index ~~ 0 ifTrue:[ |
2382 index ~~ 0 ifTrue:[ |
2383 timeoutArray at:index put:aMillisecondTime |
2383 timeoutArray at:index put:aMillisecondTime |
2384 ] ifFalse:[ |
2384 ] ifFalse:[ |
2385 index := timeoutArray identityIndexOf:nil startingAt:1. |
2385 index := timeoutArray identityIndexOf:nil startingAt:1. |
2386 index ~~ 0 ifTrue:[ |
2386 index ~~ 0 ifTrue:[ |
2387 timeoutSemaphoreArray at:index put:aSemaphore. |
2387 timeoutSemaphoreArray at:index put:aSemaphore. |
2388 timeoutArray at:index put:aMillisecondTime. |
2388 timeoutArray at:index put:aMillisecondTime. |
2389 timeoutActionArray at:index put:nil. |
2389 timeoutActionArray at:index put:nil. |
2390 timeoutProcessArray at:index put:nil |
2390 timeoutProcessArray at:index put:nil |
2391 ] ifFalse:[ |
2391 ] ifFalse:[ |
2392 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore. |
2392 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore. |
2393 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2393 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2394 timeoutActionArray := timeoutActionArray copyWith:nil. |
2394 timeoutActionArray := timeoutActionArray copyWith:nil. |
2395 timeoutProcessArray := timeoutProcessArray copyWith:nil |
2395 timeoutProcessArray := timeoutProcessArray copyWith:nil |
2396 ]. |
2396 ]. |
2397 ]. |
2397 ]. |
2398 |
2398 |
2399 anyTimeouts := true. |
2399 anyTimeouts := true. |
2400 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2400 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2401 ! |
2401 ! |
2420 wasBlocked| |
2420 wasBlocked| |
2421 |
2421 |
2422 wasBlocked := OperatingSystem blockInterrupts. |
2422 wasBlocked := OperatingSystem blockInterrupts. |
2423 |
2423 |
2424 aFileDescriptor isNil ifTrue:[ |
2424 aFileDescriptor isNil ifTrue:[ |
2425 (readCheckArray identityIndexOf:aBlock startingAt:1) == 0 ifTrue:[ |
2425 (readCheckArray identityIndexOf:aBlock startingAt:1) == 0 ifTrue:[ |
2426 idx := readFdArray identityIndexOf:nil startingAt:1. |
2426 idx := readFdArray identityIndexOf:nil startingAt:1. |
2427 idx ~~ 0 ifTrue:[ |
2427 idx ~~ 0 ifTrue:[ |
2428 readFdArray at:idx put:aFileDescriptor. |
2428 readFdArray at:idx put:aFileDescriptor. |
2429 readSemaphoreArray at:idx put:aSemaphore. |
2429 readSemaphoreArray at:idx put:aSemaphore. |
2430 readCheckArray at:idx put:aBlock |
2430 readCheckArray at:idx put:aBlock |
2431 ] ifFalse:[ |
2431 ] ifFalse:[ |
2432 readFdArray := readFdArray copyWith:nil. |
2432 readFdArray := readFdArray copyWith:nil. |
2433 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2433 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2434 readCheckArray := readCheckArray copyWith:aBlock. |
2434 readCheckArray := readCheckArray copyWith:aBlock. |
2435 ] |
2435 ] |
2436 ] |
2436 ] |
2437 ] ifFalse:[ |
2437 ] ifFalse:[ |
2438 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
2438 (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
2439 idx := readFdArray identityIndexOf:nil startingAt:1. |
2439 idx := readFdArray identityIndexOf:nil startingAt:1. |
2440 idx ~~ 0 ifTrue:[ |
2440 idx ~~ 0 ifTrue:[ |
2441 readFdArray at:idx put:aFileDescriptor. |
2441 readFdArray at:idx put:aFileDescriptor. |
2442 readSemaphoreArray at:idx put:aSemaphore. |
2442 readSemaphoreArray at:idx put:aSemaphore. |
2443 readCheckArray at:idx put:aBlock |
2443 readCheckArray at:idx put:aBlock |
2444 ] ifFalse:[ |
2444 ] ifFalse:[ |
2445 readFdArray := readFdArray copyWith:aFileDescriptor. |
2445 readFdArray := readFdArray copyWith:aFileDescriptor. |
2446 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2446 readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore. |
2447 readCheckArray := readCheckArray copyWith:aBlock. |
2447 readCheckArray := readCheckArray copyWith:aBlock. |
2448 ]. |
2448 ]. |
2449 useIOInterrupts ifTrue:[ |
2449 useIOInterrupts ifTrue:[ |
2450 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2450 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2451 ]. |
2451 ]. |
2452 ] |
2452 ] |
2453 ]. |
2453 ]. |
2454 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2454 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2455 |
2455 |
2456 "Modified: 4.8.1997 / 15:20:45 / cg" |
2456 "Modified: 4.8.1997 / 15:20:45 / cg" |
2457 ! |
2457 ! |
2460 "arrange for a semaphore to be triggered when input on aStream arrives. |
2460 "arrange for a semaphore to be triggered when input on aStream arrives. |
2461 This will do a select, if the OS supports selecting on that filedescriptor, |
2461 This will do a select, if the OS supports selecting on that filedescriptor, |
2462 otherwise, it will be polled every few milliseconds (MSDOS)." |
2462 otherwise, it will be polled every few milliseconds (MSDOS)." |
2463 |
2463 |
2464 aStream canBeSelected ifTrue:[ |
2464 aStream canBeSelected ifTrue:[ |
2465 "/ can this stream be selected on ? |
2465 "/ can this stream be selected on ? |
2466 self signal:aSemaphore onInput:aStream fileDescriptor orCheck:nil |
2466 self signal:aSemaphore onInput:aStream fileDescriptor orCheck:nil |
2467 ] ifFalse:[ |
2467 ] ifFalse:[ |
2468 "/ nope - must poll ... |
2468 "/ nope - must poll ... |
2469 self signal:aSemaphore onInput:nil orCheck:[aStream canReadWithoutBlocking] |
2469 self signal:aSemaphore onInput:nil orCheck:[aStream canReadWithoutBlocking] |
2470 ] |
2470 ] |
2471 |
2471 |
2472 "Modified: / 14.12.1999 / 23:58:50 / cg" |
2472 "Modified: / 14.12.1999 / 23:58:50 / cg" |
2473 ! |
2473 ! |
2474 |
2474 |
2493 wasBlocked| |
2493 wasBlocked| |
2494 |
2494 |
2495 wasBlocked := OperatingSystem blockInterrupts. |
2495 wasBlocked := OperatingSystem blockInterrupts. |
2496 |
2496 |
2497 aFileDescriptor isNil ifTrue:[ |
2497 aFileDescriptor isNil ifTrue:[ |
2498 (writeCheckArray identityIndexOf:aBlock startingAt:1) == 0 ifTrue:[ |
2498 (writeCheckArray identityIndexOf:aBlock startingAt:1) == 0 ifTrue:[ |
2499 idx := writeFdArray identityIndexOf:nil startingAt:1. |
2499 idx := writeFdArray identityIndexOf:nil startingAt:1. |
2500 idx ~~ 0 ifTrue:[ |
2500 idx ~~ 0 ifTrue:[ |
2501 writeFdArray at:idx put:aFileDescriptor. |
2501 writeFdArray at:idx put:aFileDescriptor. |
2502 writeSemaphoreArray at:idx put:aSemaphore. |
2502 writeSemaphoreArray at:idx put:aSemaphore. |
2503 writeCheckArray at:idx put:aBlock |
2503 writeCheckArray at:idx put:aBlock |
2504 ] ifFalse:[ |
2504 ] ifFalse:[ |
2505 writeFdArray := writeFdArray copyWith:nil. |
2505 writeFdArray := writeFdArray copyWith:nil. |
2506 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2506 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2507 writeCheckArray := writeCheckArray copyWith:aBlock. |
2507 writeCheckArray := writeCheckArray copyWith:aBlock. |
2508 ] |
2508 ] |
2509 ] |
2509 ] |
2510 ] ifFalse:[ |
2510 ] ifFalse:[ |
2511 (writeFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
2511 (writeFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[ |
2512 idx := writeFdArray identityIndexOf:nil startingAt:1. |
2512 idx := writeFdArray identityIndexOf:nil startingAt:1. |
2513 idx ~~ 0 ifTrue:[ |
2513 idx ~~ 0 ifTrue:[ |
2514 writeFdArray at:idx put:aFileDescriptor. |
2514 writeFdArray at:idx put:aFileDescriptor. |
2515 writeSemaphoreArray at:idx put:aSemaphore. |
2515 writeSemaphoreArray at:idx put:aSemaphore. |
2516 writeCheckArray at:idx put:aBlock |
2516 writeCheckArray at:idx put:aBlock |
2517 ] ifFalse:[ |
2517 ] ifFalse:[ |
2518 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
2518 writeFdArray := writeFdArray copyWith:aFileDescriptor. |
2519 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2519 writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore. |
2520 writeCheckArray := writeCheckArray copyWith:aBlock. |
2520 writeCheckArray := writeCheckArray copyWith:aBlock. |
2521 ]. |
2521 ]. |
2522 useIOInterrupts ifTrue:[ |
2522 useIOInterrupts ifTrue:[ |
2523 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2523 OperatingSystem enableIOInterruptsOn:aFileDescriptor |
2524 ]. |
2524 ]. |
2525 ] |
2525 ] |
2526 ]. |
2526 ]. |
2527 |
2527 |
2528 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2528 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2529 |
2529 |
2530 "Modified: 4.8.1997 / 15:21:49 / cg" |
2530 "Modified: 4.8.1997 / 15:21:49 / cg" |
2534 "arrange for a semaphore to be triggered when output on aStream is possible. |
2534 "arrange for a semaphore to be triggered when output on aStream is possible. |
2535 This will do a select, if the OS supports selecting on that filedescriptor, |
2535 This will do a select, if the OS supports selecting on that filedescriptor, |
2536 otherwise, it will be polled every few milliseconds (MSDOS)." |
2536 otherwise, it will be polled every few milliseconds (MSDOS)." |
2537 |
2537 |
2538 aStream canBeSelected ifTrue:[ |
2538 aStream canBeSelected ifTrue:[ |
2539 "/ can this stream be selected on ? |
2539 "/ can this stream be selected on ? |
2540 self signal:aSemaphore onOutput:aStream fileDescriptor orCheck:nil |
2540 self signal:aSemaphore onOutput:aStream fileDescriptor orCheck:nil |
2541 ] ifFalse:[ |
2541 ] ifFalse:[ |
2542 "/ nope - must poll ... |
2542 "/ nope - must poll ... |
2543 self signal:aSemaphore onOutput:nil orCheck:[aStream canWriteWithoutBlocking] |
2543 self signal:aSemaphore onOutput:nil orCheck:[aStream canWriteWithoutBlocking] |
2544 ] |
2544 ] |
2545 |
2545 |
2546 "Modified: / 14.12.1999 / 23:59:19 / cg" |
2546 "Modified: / 14.12.1999 / 23:59:19 / cg" |
2547 ! ! |
2547 ! ! |
2548 |
2548 |
2555 If enabled, arrangements are made for data-availability to trigger an |
2555 If enabled, arrangements are made for data-availability to trigger an |
2556 interrupt. |
2556 interrupt. |
2557 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2557 Using IO interrupts reduces the idle CPU usage of ST/X by some percent |
2558 (typically 2-7%). |
2558 (typically 2-7%). |
2559 Notice: |
2559 Notice: |
2560 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2560 some systems do not support IO-interrupts (or have a broken stdio-lib), |
2561 and this feature is always disabled; |
2561 and this feature is always disabled; |
2562 Also notice: |
2562 Also notice: |
2563 we found that in some Xlib-implementations, interrupted reads are not |
2563 we found that in some Xlib-implementations, interrupted reads are not |
2564 handled correctly (especially in multi-headed applications), and this |
2564 handled correctly (especially in multi-headed applications), and this |
2565 feature should be disabled to avoid a blocking XPending. |
2565 feature should be disabled to avoid a blocking XPending. |
2566 |
2566 |
2567 If this method is used to disable IO interrupts in multi-headed apps, |
2567 If this method is used to disable IO interrupts in multi-headed apps, |
2568 it should be invoked BEFORE the display event dispatcher processes are started." |
2568 it should be invoked BEFORE the display event dispatcher processes are started." |
2569 |
2569 |
2570 OperatingSystem supportsIOInterrupts ifTrue:[ |
2570 OperatingSystem supportsIOInterrupts ifTrue:[ |
2571 useIOInterrupts := aBoolean |
2571 useIOInterrupts := aBoolean |
2572 ]. |
2572 ]. |
2573 |
2573 |
2574 "Created: / 15.7.1998 / 13:32:29 / cg" |
2574 "Created: / 15.7.1998 / 13:32:29 / cg" |
2575 ! ! |
2575 ! ! |
2576 |
2576 |
2684 wasBlocked| |
2684 wasBlocked| |
2685 |
2685 |
2686 wasBlocked := OperatingSystem blockInterrupts. |
2686 wasBlocked := OperatingSystem blockInterrupts. |
2687 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
2687 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
2688 index ~~ 0 ifTrue:[ |
2688 index ~~ 0 ifTrue:[ |
2689 timeoutArray at:index put:aMillisecondTime |
2689 timeoutArray at:index put:aMillisecondTime |
2690 ] ifFalse:[ |
2690 ] ifFalse:[ |
2691 index := timeoutArray indexOf:nil. |
2691 index := timeoutArray indexOf:nil. |
2692 index ~~ 0 ifTrue:[ |
2692 index ~~ 0 ifTrue:[ |
2693 timeoutArray at:index put:aMillisecondTime. |
2693 timeoutArray at:index put:aMillisecondTime. |
2694 timeoutActionArray at:index put:aBlock. |
2694 timeoutActionArray at:index put:aBlock. |
2695 timeoutSemaphoreArray at:index put:nil. |
2695 timeoutSemaphoreArray at:index put:nil. |
2696 timeoutProcessArray at:index put:aProcess |
2696 timeoutProcessArray at:index put:aProcess |
2697 ] ifFalse:[ |
2697 ] ifFalse:[ |
2698 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2698 timeoutArray := timeoutArray copyWith:aMillisecondTime. |
2699 timeoutActionArray := timeoutActionArray copyWith:aBlock. |
2699 timeoutActionArray := timeoutActionArray copyWith:aBlock. |
2700 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:nil. |
2700 timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:nil. |
2701 timeoutProcessArray := timeoutProcessArray copyWith:aProcess. |
2701 timeoutProcessArray := timeoutProcessArray copyWith:aProcess. |
2702 index := timeoutArray size. |
2702 index := timeoutArray size. |
2703 ]. |
2703 ]. |
2704 ]. |
2704 ]. |
2705 |
2705 |
2706 anyTimeouts := true. |
2706 anyTimeouts := true. |
2707 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2707 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2708 ^ index |
2708 ^ index |
2844 aBlock isNil ifTrue:[^ self]. |
2844 aBlock isNil ifTrue:[^ self]. |
2845 |
2845 |
2846 wasBlocked := OperatingSystem blockInterrupts. |
2846 wasBlocked := OperatingSystem blockInterrupts. |
2847 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
2847 index := timeoutActionArray identityIndexOf:aBlock startingAt:1. |
2848 (index ~~ 0) ifTrue:[ |
2848 (index ~~ 0) ifTrue:[ |
2849 timeoutArray at:index put:nil. |
2849 timeoutArray at:index put:nil. |
2850 timeoutActionArray at:index put:nil. |
2850 timeoutActionArray at:index put:nil. |
2851 timeoutSemaphoreArray at:index put:nil. |
2851 timeoutSemaphoreArray at:index put:nil. |
2852 timeoutProcessArray at:index put:nil. |
2852 timeoutProcessArray at:index put:nil. |
2853 ]. |
2853 ]. |
2854 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2854 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2855 ! |
2855 ! |
2856 |
2856 |
2857 removeTimeoutWithID:anID |
2857 removeTimeoutWithID:anID |
2861 |index "{ Class: SmallInteger }" |
2861 |index "{ Class: SmallInteger }" |
2862 wasBlocked| |
2862 wasBlocked| |
2863 |
2863 |
2864 index := anID. |
2864 index := anID. |
2865 (index > 0) ifTrue:[ |
2865 (index > 0) ifTrue:[ |
2866 wasBlocked := OperatingSystem blockInterrupts. |
2866 wasBlocked := OperatingSystem blockInterrupts. |
2867 |
2867 |
2868 timeoutArray at:index put:nil. |
2868 timeoutArray at:index put:nil. |
2869 timeoutActionArray at:index put:nil. |
2869 timeoutActionArray at:index put:nil. |
2870 timeoutSemaphoreArray at:index put:nil. |
2870 timeoutSemaphoreArray at:index put:nil. |
2871 timeoutProcessArray at:index put:nil. |
2871 timeoutProcessArray at:index put:nil. |
2872 |
2872 |
2873 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2873 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
2874 ] |
2874 ] |
2875 |
2875 |
2876 "Created: 23.9.1996 / 14:32:33 / cg" |
2876 "Created: 23.9.1996 / 14:32:33 / cg" |
2877 "Modified: 23.9.1996 / 14:35:09 / cg" |
2877 "Modified: 23.9.1996 / 14:35:09 / cg" |
2878 ! |
2878 ! |
3119 Notice, that at the time of the message, we are still in the context |
3119 Notice, that at the time of the message, we are still in the context |
3120 of whichever process is currently running." |
3120 of whichever process is currently running." |
3121 |
3121 |
3122 gotIOInterrupt := true. |
3122 gotIOInterrupt := true. |
3123 activeProcess ~~ scheduler ifTrue:[ |
3123 activeProcess ~~ scheduler ifTrue:[ |
3124 interruptedProcess := activeProcess. |
3124 interruptedProcess := activeProcess. |
3125 self threadSwitch:scheduler |
3125 self threadSwitch:scheduler |
3126 ] |
3126 ] |
3127 |
3127 |
3128 "Modified: 21.12.1995 / 16:17:40 / stefan" |
3128 "Modified: 21.12.1995 / 16:17:40 / stefan" |
3129 "Modified: 4.8.1997 / 14:23:08 / cg" |
3129 "Modified: 4.8.1997 / 14:23:08 / cg" |
3130 ! |
3130 ! |
3209 If there were many, the list should be kept sorted ... keeping deltas |
3209 If there were many, the list should be kept sorted ... keeping deltas |
3210 to next (as in Unix kernel)" |
3210 to next (as in Unix kernel)" |
3211 |
3211 |
3212 n := timeoutArray size. |
3212 n := timeoutArray size. |
3213 1 to:n do:[:index | |
3213 1 to:n do:[:index | |
3214 aTime := timeoutArray at:index. |
3214 aTime := timeoutArray at:index. |
3215 aTime notNil ifTrue:[ |
3215 aTime notNil ifTrue:[ |
3216 now isNil ifTrue:[ |
3216 now isNil ifTrue:[ |
3217 now := OperatingSystem getMillisecondTime. |
3217 now := OperatingSystem getMillisecondTime. |
3218 ]. |
3218 ]. |
3219 (OperatingSystem millisecondTime:aTime isAfter:now) ifFalse:[^ 0]. |
3219 (OperatingSystem millisecondTime:aTime isAfter:now) ifFalse:[^ 0]. |
3220 delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now. |
3220 delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now. |
3221 minDelta isNil ifTrue:[ |
3221 minDelta isNil ifTrue:[ |
3222 minDelta := delta |
3222 minDelta := delta |
3223 ] ifFalse:[ |
3223 ] ifFalse:[ |
3224 minDelta := minDelta min:delta |
3224 minDelta := minDelta min:delta |
3225 ] |
3225 ] |
3226 ] |
3226 ] |
3227 ]. |
3227 ]. |
3228 |
3228 |
3229 ^ minDelta |
3229 ^ minDelta |
3230 ! |
3230 ! |
3231 |
3231 |
3237 This method is called by the VM' interrupt handling mechanism. |
3237 This method is called by the VM' interrupt handling mechanism. |
3238 Notice, that at the time of the message, we are still in the context |
3238 Notice, that at the time of the message, we are still in the context |
3239 of whichever process is currently running." |
3239 of whichever process is currently running." |
3240 |
3240 |
3241 activeProcess ~~ scheduler ifTrue:[ |
3241 activeProcess ~~ scheduler ifTrue:[ |
3242 interruptedProcess := activeProcess. |
3242 interruptedProcess := activeProcess. |
3243 self threadSwitch:scheduler |
3243 self threadSwitch:scheduler |
3244 ] |
3244 ] |
3245 |
3245 |
3246 "Modified: 18.10.1996 / 20:35:54 / cg" |
3246 "Modified: 18.10.1996 / 20:35:54 / cg" |
3247 ! |
3247 ! |
3248 |
3248 |
3294 "/ stop dispatching if there is none |
3294 "/ stop dispatching if there is none |
3295 "/ (and millis is nil, which means that no timeout blocks are present) |
3295 "/ (and millis is nil, which means that no timeout blocks are present) |
3296 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3296 "/ and no readSemaphores are present (which means that noone is waiting for input) |
3297 "/ and no writeSemaphores are present |
3297 "/ and no writeSemaphores are present |
3298 |
3298 |
3299 anySema := false. |
3299 anySema := (readSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3300 "/ don't care about input data - if there is no user process, nobod relevant is doing the IO anyway!! |
3300 anySema ifFalse:[ |
3301 "/ |
3301 anySema := (writeSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
3302 |
3302 ]. |
3303 "/ anySema := (readSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
|
3304 "/ anySema ifFalse:[ |
|
3305 "/ anySema := (writeSemaphoreArray findFirst:[:sema | sema notNil]) ~~ 0. |
|
3306 "/ ]. |
|
3307 anySema ifFalse:[ |
3303 anySema ifFalse:[ |
3308 self anyUserProcessAtAll ifFalse:[ |
3304 self anyUserProcessAtAll ifFalse:[ |
3309 dispatching := false. |
3305 dispatching := false. |
3310 ^ self |
3306 ^ self |
3311 ] |
3307 ] |