14 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
14 instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess |
15 currentPriority readFdArray readSemaphoreArray readCheckArray |
15 currentPriority readFdArray readSemaphoreArray readCheckArray |
16 writeFdArray writeSemaphoreArray timeoutArray timeoutActionArray |
16 writeFdArray writeSemaphoreArray timeoutArray timeoutActionArray |
17 timeoutProcessArray timeoutSemaphoreArray idleActions anyTimeouts |
17 timeoutProcessArray timeoutSemaphoreArray idleActions anyTimeouts |
18 dispatching interruptedProcess useIOInterrupts gotIOInterrupt |
18 dispatching interruptedProcess useIOInterrupts gotIOInterrupt |
19 osChildExitActions exitWhenNoMoreUserProcesses' |
19 osChildExitActions gotChildSignalInterrupt |
|
20 exitWhenNoMoreUserProcesses' |
20 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
21 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
21 UserSchedulingPriority UserInterruptPriority TimingPriority |
22 UserSchedulingPriority UserInterruptPriority TimingPriority |
22 HighestPriority SchedulingPriority MaxNumberOfProcesses' |
23 HighestPriority SchedulingPriority MaxNumberOfProcesses' |
23 poolDictionaries:'' |
24 poolDictionaries:'' |
24 category:'Kernel-Processes' |
25 category:'Kernel-Processes' |
500 |
501 |
501 " |
502 " |
502 handle all timeout actions |
503 handle all timeout actions |
503 " |
504 " |
504 anyTimeouts ifTrue:[ |
505 anyTimeouts ifTrue:[ |
505 self evaluateTimeouts |
506 self evaluateTimeouts |
506 ]. |
507 ]. |
507 |
508 |
508 "first do a quick check for semaphores using checkActions - this is needed for |
509 "first do a quick check for semaphores using checkActions - this is needed for |
509 devices like the X-connection, where some events might be in the event |
510 devices like the X-connection, where some events might be in the event |
510 queue. Without these checks, a select might block even though there is work to do |
511 queue. Without these checks, a select might block even though there is work to do |
511 " |
512 " |
512 any := false. |
513 any := false. |
513 nActions := readCheckArray size. |
514 nActions := readCheckArray size. |
514 1 to:nActions do:[:index | |
515 1 to:nActions do:[:index | |
515 checkBlock := readCheckArray at:index. |
516 checkBlock := readCheckArray at:index. |
516 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
517 (checkBlock notNil and:[checkBlock value]) ifTrue:[ |
517 sema := readSemaphoreArray at:index. |
518 sema := readSemaphoreArray at:index. |
518 sema notNil ifTrue:[ |
519 sema notNil ifTrue:[ |
519 sema signalOnce. |
520 sema signalOnce. |
520 ]. |
521 ]. |
521 any := true. |
522 any := true. |
522 ] |
523 ] |
523 ]. |
524 ]. |
524 |
525 |
525 "now, someone might be runnable ..." |
526 "now, someone might be runnable ..." |
526 |
527 |
527 p := self highestPriorityRunnableProcess. |
528 p := self highestPriorityRunnableProcess. |
528 p isNil ifTrue:[ |
529 p isNil ifTrue:[ |
529 "/ no one runnable, hard wait for event or timeout |
530 "/ no one runnable, hard wait for event or timeout |
530 |
531 |
531 self waitForEventOrTimeout. |
532 self waitForEventOrTimeout. |
532 ^ self |
533 ^ self |
533 ]. |
534 ]. |
534 |
535 |
535 pri := p priority. |
536 pri := p priority. |
536 |
537 |
537 " |
538 " |
574 or by installing a poll-interrupt after 50ms (if the OS does not). |
575 or by installing a poll-interrupt after 50ms (if the OS does not). |
575 " |
576 " |
576 pri < UserInterruptPriority ifTrue:[ |
577 pri < UserInterruptPriority ifTrue:[ |
577 |
578 |
578 "comment out this if above is uncommented" |
579 "comment out this if above is uncommented" |
579 anyTimeouts ifTrue:[ |
580 anyTimeouts ifTrue:[ |
580 millis := self timeToNextTimeout. |
581 millis := self timeToNextTimeout. |
581 millis == 0 ifTrue:[^ self]. |
582 millis == 0 ifTrue:[^ self]. |
582 ]. |
583 ]. |
583 "---" |
584 "---" |
584 |
585 |
585 useIOInterrupts ifTrue:[ |
586 useIOInterrupts ifTrue:[ |
586 readFdArray do:[:fd | |
587 readFdArray do:[:fd | |
587 fd notNil ifTrue:[ |
588 fd notNil ifTrue:[ |
588 OperatingSystem enableIOInterruptsOn:fd |
589 OperatingSystem enableIOInterruptsOn:fd |
589 ]. |
590 ]. |
590 ]. |
591 ]. |
591 ] ifFalse:[ |
592 ] ifFalse:[ |
592 millis notNil ifTrue:[ |
593 millis notNil ifTrue:[ |
593 millis := millis min:50 |
594 millis := millis min:50 |
594 ] ifFalse:[ |
595 ] ifFalse:[ |
595 millis := 50 |
596 millis := 50 |
596 ] |
597 ] |
597 ] |
598 ] |
598 ]. |
599 ]. |
599 |
600 |
600 millis notNil ifTrue:[ |
601 millis notNil ifTrue:[ |
601 "schedule a clock interrupt after millis milliseconds" |
602 "schedule a clock interrupt after millis milliseconds" |
602 OperatingSystem enableTimer:millis rounded. |
603 OperatingSystem enableTimer:millis rounded. |
603 ]. |
604 ]. |
604 |
605 |
605 " |
606 " |
606 now let the process run - will come back here by reschedule |
607 now let the process run - will come back here by reschedule |
607 from ioInterrupt or timerInterrupt ... (running at max+1) |
608 from ioInterrupt or timerInterrupt ... (running at max+1) |
608 " |
609 " |
609 self threadSwitch:p. |
610 self threadSwitch:p. |
610 |
611 |
611 "... when we arrive here, we are back on stage. |
612 "... when we arrive here, we are back on stage. |
612 Either by an ALARM or IO signal, or by a suspend of another process |
613 Either by an ALARM or IO signal, or by a suspend of another process |
613 " |
614 " |
614 |
615 |
615 millis notNil ifTrue:[ |
616 millis notNil ifTrue:[ |
616 OperatingSystem disableTimer. |
617 OperatingSystem disableTimer. |
|
618 ]. |
|
619 |
|
620 "/ check for OS process termination |
|
621 gotChildSignalInterrupt ifTrue:[ |
|
622 gotChildSignalInterrupt := false. |
|
623 self handleChildSignalInterrupt |
617 ]. |
624 ]. |
618 |
625 |
619 "/ check for new input |
626 "/ check for new input |
620 |
627 |
621 (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[ |
628 (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[ |
622 gotIOInterrupt := false. |
629 gotIOInterrupt := false. |
623 self checkForInputWithTimeout:0. |
630 self checkForInputWithTimeout:0. |
624 ] |
631 ] |
625 |
632 |
626 "Modified: 21.12.1995 / 16:21:54 / stefan" |
633 "Modified: 12.4.1996 / 10:14:18 / stefan" |
627 ! |
634 ! |
628 |
635 |
629 dispatchLoop |
636 dispatchLoop |
630 "central dispatch loop; the scheduler process is always staying in |
637 "central dispatch loop; the scheduler process is always staying in |
631 this method, looping forever." |
638 this method, looping forever." |
675 ! ! |
682 ! ! |
676 |
683 |
677 !ProcessorScheduler methodsFor:'os process handling'! |
684 !ProcessorScheduler methodsFor:'os process handling'! |
678 |
685 |
679 childSignalInterrupt |
686 childSignalInterrupt |
|
687 "child changed state - switch to scheduler process which will decide |
|
688 what to do now." |
|
689 |
|
690 gotChildSignalInterrupt := true. |
|
691 interruptedProcess := activeProcess. |
|
692 self threadSwitch:scheduler |
|
693 |
|
694 "Modified: 12.4.1996 / 10:12:18 / stefan" |
|
695 ! |
|
696 |
|
697 handleChildSignalInterrupt |
680 "child changed state - execute child termination blocks. |
698 "child changed state - execute child termination blocks. |
681 If child is no longer alive, remove action block." |
699 If child is no longer alive, remove action block." |
682 |
700 |
683 |osProcessStatus blocking wasBlocked| |
701 |osProcessStatus blocking wasBlocked| |
684 |
702 |
718 ]. |
736 ]. |
719 ] valueNowOrOnUnwindDo:[ |
737 ] valueNowOrOnUnwindDo:[ |
720 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
738 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
721 ] |
739 ] |
722 |
740 |
723 "Created: 22.12.1995 / 14:16:26 / stefan" |
|
724 "Modified: 5.1.1996 / 16:56:11 / stefan" |
741 "Modified: 5.1.1996 / 16:56:11 / stefan" |
725 "Modified: 28.2.1996 / 21:36:31 / cg" |
742 "Modified: 28.2.1996 / 21:36:31 / cg" |
|
743 "Created: 12.4.1996 / 10:08:21 / stefan" |
726 ! |
744 ! |
727 |
745 |
728 monitorPid:pid action:aBlock |
746 monitorPid:pid action:aBlock |
729 "add a 1-arg-block that is called when the operating system child process |
747 "add a 1-arg-block that is called when the operating system child process |
730 with pid pid changes state. |
748 with pid pid changes state. |
916 |
934 |
917 |nPrios "{ Class: SmallInteger }" |
935 |nPrios "{ Class: SmallInteger }" |
918 p| |
936 p| |
919 |
937 |
920 KnownProcesses isNil ifTrue:[ |
938 KnownProcesses isNil ifTrue:[ |
921 KnownProcesses := WeakArray new:10. |
939 KnownProcesses := WeakArray new:10. |
922 KnownProcesses watcher:self class. |
940 KnownProcesses watcher:self class. |
923 KnownProcessIds := OrderedCollection new. |
941 KnownProcessIds := OrderedCollection new. |
924 ]. |
942 ]. |
925 |
943 |
926 " |
944 " |
927 create a collection with process lists; accessed using the priority as key |
945 create a collection with process lists; accessed using the priority as key |
928 " |
946 " |
929 nPrios := SchedulingPriority. |
947 nPrios := SchedulingPriority. |
930 quiescentProcessLists := Array new:nPrios. |
948 quiescentProcessLists := Array new:nPrios. |
931 1 to:nPrios do:[:pri | |
949 1 to:nPrios do:[:pri | |
932 quiescentProcessLists at:pri put:(LinkedList new) |
950 quiescentProcessLists at:pri put:(LinkedList new) |
933 ]. |
951 ]. |
934 |
952 |
935 readFdArray := Array with:nil. |
953 readFdArray := Array with:nil. |
936 readCheckArray := Array with:nil. |
954 readCheckArray := Array with:nil. |
937 readSemaphoreArray := Array with:nil. |
955 readSemaphoreArray := Array with:nil. |
945 dispatching := false. |
963 dispatching := false. |
946 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
964 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
947 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
965 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
948 gotIOInterrupt := false. |
966 gotIOInterrupt := false. |
949 osChildExitActions := Dictionary new. |
967 osChildExitActions := Dictionary new. |
|
968 gotChildSignalInterrupt := false. |
950 |
969 |
951 " |
970 " |
952 handcraft the first (dispatcher-) process - this one will never |
971 handcraft the first (dispatcher-) process - this one will never |
953 block, but go into a select if there is nothing to do. |
972 block, but go into a select if there is nothing to do. |
954 Also, it has a prio of max+1 - thus, it comes first when looking |
973 Also, it has a prio of max+1 - thus, it comes first when looking |
969 " |
988 " |
970 ObjectMemory ioInterruptHandler:self. |
989 ObjectMemory ioInterruptHandler:self. |
971 ObjectMemory timerInterruptHandler:self. |
990 ObjectMemory timerInterruptHandler:self. |
972 ObjectMemory childSignalInterruptHandler:self. |
991 ObjectMemory childSignalInterruptHandler:self. |
973 |
992 |
974 "Modified: 22.12.1995 / 14:15:29 / stefan" |
993 "Modified: 12.4.1996 / 10:12:56 / stefan" |
975 ! |
994 ! |
976 |
995 |
977 reinitialize |
996 reinitialize |
978 "all previous processes (except those marked as restartable) are made dead |
997 "all previous processes (except those marked as restartable) are made dead |
979 - each object should reinstall its process(s) upon restart; |
998 - each object should reinstall its process(s) upon restart; |
1774 hard wait for either input to arrive or a timeout to occur." |
1793 hard wait for either input to arrive or a timeout to occur." |
1775 |
1794 |
1776 |fd index sema action| |
1795 |fd index sema action| |
1777 |
1796 |
1778 fd := OperatingSystem |
1797 fd := OperatingSystem |
1779 selectOnAnyReadable:readFdArray |
1798 selectOnAnyReadable:readFdArray |
1780 writable:writeFdArray |
1799 writable:writeFdArray |
1781 exception:nil |
1800 exception:nil |
1782 withTimeOut:millis. |
1801 withTimeOut:millis. |
1783 |
1802 |
1784 fd isNil ifTrue:[ |
1803 fd isNil ifTrue:[ |
1785 (OperatingSystem lastErrorSymbol == #EBADF) ifTrue:[ |
1804 (OperatingSystem lastErrorSymbol == #EBADF) ifTrue:[ |
1786 |
1805 |
1787 "/ mhmh - one of the fd's given to me is corrupt. |
1806 "/ mhmh - one of the fd's given to me is corrupt. |
1788 "/ find out which one .... and remove it |
1807 "/ find out which one .... and remove it |
1789 |
1808 |
1790 self removeCorruptedFds |
1809 OperatingSystem clearLastErrorNumber. |
1791 ] |
1810 self removeCorruptedFds |
|
1811 ] |
1792 ] ifFalse:[ |
1812 ] ifFalse:[ |
1793 index := readFdArray indexOf:fd. |
1813 index := readFdArray indexOf:fd. |
1794 index ~~ 0 ifTrue:[ |
1814 index ~~ 0 ifTrue:[ |
1795 sema := readSemaphoreArray at:index. |
1815 sema := readSemaphoreArray at:index. |
1796 sema notNil ifTrue:[ |
1816 sema notNil ifTrue:[ |
1797 sema signalOnce. |
1817 sema signalOnce. |
1798 ^ true |
1818 ^ true |
1799 ] ifFalse:[ |
1819 ] ifFalse:[ |
1800 action := readCheckArray at:index. |
1820 action := readCheckArray at:index. |
1801 action notNil ifTrue:[ |
1821 action notNil ifTrue:[ |
1802 action value. |
1822 action value. |
1803 ^ true |
1823 ^ true |
1804 ] |
1824 ] |
1805 ] |
1825 ] |
1806 ] |
1826 ] |
1807 ]. |
1827 ]. |
1808 ^ false |
1828 ^ false |
|
1829 |
|
1830 "Modified: 12.4.1996 / 09:31:22 / stefan" |
1809 ! |
1831 ! |
1810 |
1832 |
1811 ioInterrupt |
1833 ioInterrupt |
1812 "data arrived while waiting - switch to scheduler process which will decide |
1834 "data arrived while waiting - switch to scheduler process which will decide |
1813 what to do now." |
1835 what to do now." |