129 TimingPriority := 16. |
129 TimingPriority := 16. |
130 SchedulingPriority := 31. |
130 SchedulingPriority := 31. |
131 HighestPriority := 30. |
131 HighestPriority := 30. |
132 |
132 |
133 Processor isNil ifTrue:[ |
133 Processor isNil ifTrue:[ |
134 "create the one and only processor" |
134 "create the one and only processor" |
135 |
135 |
136 Processor := self basicNew initialize. |
136 Processor := self basicNew initialize. |
137 ]. |
137 ]. |
138 |
138 |
139 " |
139 " |
140 allow configurations without processes |
140 allow configurations without processes |
141 " |
141 " |
142 PureEventDriven := self threadsAvailable not. |
142 PureEventDriven := self threadsAvailable not. |
143 PureEventDriven ifTrue:[ |
143 PureEventDriven ifTrue:[ |
144 'no process support - running event driven' errorPrintNL |
144 'PROCESSOR: no process support - running event driven' errorPrintNL |
145 ]. |
145 ]. |
|
146 |
|
147 "Modified: 7.3.1996 / 19:22:49 / cg" |
146 ! ! |
148 ! ! |
147 |
149 |
148 !ProcessorScheduler class methodsFor:'instance creation'! |
150 !ProcessorScheduler class methodsFor:'instance creation'! |
149 |
151 |
150 new |
152 new |
803 currentPriority := pri. |
805 currentPriority := pri. |
804 %{ |
806 %{ |
805 extern OBJ ___threadSwitch(); |
807 extern OBJ ___threadSwitch(); |
806 |
808 |
807 if (__isSmallInteger(id)) { |
809 if (__isSmallInteger(id)) { |
808 ok = ___threadSwitch(__context, _intVal(id), (singleStep == true) ? 1 : 0); |
810 ok = ___threadSwitch(__context, _intVal(id), (singleStep == true) ? 1 : 0); |
809 } else { |
811 } else { |
810 ok = false; |
812 ok = false; |
811 } |
813 } |
812 %}. |
814 %}. |
813 "time passes spent in some other process ... |
815 "time passes spent in some other process ... |
814 ... here again" |
816 ... here again" |
815 |
817 |
816 p := activeProcess. |
818 p := activeProcess. |
817 activeProcess := oldProcess. |
819 activeProcess := oldProcess. |
818 currentPriority := oldProcess priority. |
820 currentPriority := oldProcess priority. |
819 |
821 |
820 ok ifFalse:[ |
822 ok ifFalse:[ |
821 " |
823 " |
822 switch failed for some reason - |
824 switch failed for some reason - |
823 destroy the bad process |
825 destroy the bad process |
824 " |
826 " |
825 p id ~~ 0 ifTrue:[ |
827 p id ~~ 0 ifTrue:[ |
826 'SCHEDULER: problem with process ' errorPrint. |
828 'PROCESSOR: problem with process ' errorPrint. |
827 p id errorPrint. |
829 p id errorPrint. |
828 p name notNil ifTrue:[ |
830 p name notNil ifTrue:[ |
829 ' (' errorPrint. p name errorPrint. ')' errorPrint. |
831 ' (' errorPrint. p name errorPrint. ')' errorPrint. |
830 ]. |
832 ]. |
831 '; hard-terminate it.' errorPrintNL. |
833 '; hard-terminate it.' errorPrintNL. |
832 p state:#suspended. |
834 p state:#suspended. |
833 self terminateNoSignal:p. |
835 self terminateNoSignal:p. |
834 ] |
836 ] |
835 ]. |
837 ]. |
836 zombie notNil ifTrue:[ |
838 zombie notNil ifTrue:[ |
837 self class threadDestroy:zombie. |
839 self class threadDestroy:zombie. |
838 zombie := nil |
840 zombie := nil |
839 ]. |
841 ]. |
840 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
842 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
841 ! ! |
843 ! ! |
842 |
844 |
843 !ProcessorScheduler methodsFor:'private'! |
845 !ProcessorScheduler methodsFor:'private'! |
1082 |listArray l p prio "{ Class: SmallInteger }" | |
1084 |listArray l p prio "{ Class: SmallInteger }" | |
1083 |
1085 |
1084 prio := HighestPriority. |
1086 prio := HighestPriority. |
1085 listArray := quiescentProcessLists. |
1087 listArray := quiescentProcessLists. |
1086 [prio >= 1] whileTrue:[ |
1088 [prio >= 1] whileTrue:[ |
1087 l := listArray at:prio. |
1089 l := listArray at:prio. |
1088 l notEmpty ifTrue:[ |
1090 l notEmpty ifTrue:[ |
1089 p := l first. |
1091 p := l first. |
1090 " |
1092 " |
1091 if it got corrupted somehow ... |
1093 if it got corrupted somehow ... |
1092 " |
1094 " |
1093 p id isNil ifTrue:[ |
1095 p id isNil ifTrue:[ |
1094 'process with nil id removed' errorPrintNL. |
1096 'PROCESSOR: process with nil id removed' errorPrintNL. |
1095 l removeFirst. |
1097 l removeFirst. |
1096 ^ nil. |
1098 ^ nil. |
1097 ]. |
1099 ]. |
1098 ^ p |
1100 ^ p |
1099 ]. |
1101 ]. |
1100 prio := prio - 1 |
1102 prio := prio - 1 |
1101 ]. |
1103 ]. |
1102 ^ nil |
1104 ^ nil |
|
1105 |
|
1106 "Modified: 7.3.1996 / 19:22:05 / cg" |
1103 ! |
1107 ! |
1104 |
1108 |
1105 isSystemProcess:aProcess |
1109 isSystemProcess:aProcess |
1106 "return true if aProcess is a system process, |
1110 "return true if aProcess is a system process, |
1107 which should not be suspended/terminated etc.." |
1111 which should not be suspended/terminated etc.." |
1389 |
1393 |
1390 " |
1394 " |
1391 debugging consistency check - will be removed later |
1395 debugging consistency check - will be removed later |
1392 " |
1396 " |
1393 activeProcess priority ~~ currentPriority ifTrue:[ |
1397 activeProcess priority ~~ currentPriority ifTrue:[ |
1394 'oops process changed priority' errorPrintNL. |
1398 'PROCESSOR: oops - process changed priority' errorPrintNL. |
1395 currentPriority := activeProcess priority. |
1399 currentPriority := activeProcess priority. |
1396 ]. |
1400 ]. |
1397 |
1401 |
1398 l := quiescentProcessLists at:currentPriority. |
1402 l := quiescentProcessLists at:currentPriority. |
1399 |
1403 |
1400 " |
1404 " |
1401 debugging consistency checks - will be removed later |
1405 debugging consistency checks - will be removed later |
1402 " |
1406 " |
1403 l isEmpty ifTrue:[ |
1407 l isEmpty ifTrue:[ |
1404 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1408 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1405 'oops - empty runnable list' errorPrintNL. |
1409 'PROCESSOR: oops - empty runnable list' errorPrintNL. |
1406 ^ self |
1410 ^ self |
1407 ]. |
1411 ]. |
1408 |
1412 |
1409 " |
1413 " |
1410 check if the running process is not the only one |
1414 check if the running process is not the only one |
1411 " |
1415 " |
1412 l size ~~ 1 ifTrue:[ |
1416 l size ~~ 1 ifTrue:[ |
1413 " |
1417 " |
1414 bring running process to the end |
1418 bring running process to the end |
1415 " |
1419 " |
1416 l removeFirst. |
1420 l removeFirst. |
1417 l addLast:activeProcess. |
1421 l addLast:activeProcess. |
1418 |
1422 |
1419 " |
1423 " |
1420 and switch to first in the list |
1424 and switch to first in the list |
1421 " |
1425 " |
1422 self threadSwitch:(l first). |
1426 self threadSwitch:(l first). |
1423 ]. |
1427 ]. |
1424 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1428 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
|
1429 |
|
1430 "Modified: 7.3.1996 / 19:22:43 / cg" |
1425 ! ! |
1431 ! ! |
1426 |
1432 |
1427 !ProcessorScheduler methodsFor:'semaphore signalling'! |
1433 !ProcessorScheduler methodsFor:'semaphore signalling'! |
1428 |
1434 |
1429 disableSemaphore:aSemaphore |
1435 disableSemaphore:aSemaphore |
1750 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1756 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1751 ! ! |
1757 ! ! |
1752 |
1758 |
1753 !ProcessorScheduler methodsFor:'waiting'! |
1759 !ProcessorScheduler methodsFor:'waiting'! |
1754 |
1760 |
1755 removeCorruptedFds |
|
1756 "this is sent when select returns an error due to some invalid |
|
1757 fileDescriptor. May happens, if someone does a readWait/writeWait on a |
|
1758 connection, which somehow gets corrupted. |
|
1759 Without special care, all following selects would immediately return with |
|
1760 an #EBADF error, leading to high-frequency polling and a locked up system. |
|
1761 (you could still fix things by interrupting on the console and fixing the |
|
1762 readFdArray/writeFdArray in the debugger)" |
|
1763 |
|
1764 readFdArray keysAndValuesDo:[:idx :fd | |
|
1765 |rslt| |
|
1766 |
|
1767 rslt := OperatingSystem |
|
1768 selectOnAnyReadable:(Array with:fd) |
|
1769 writable:nil |
|
1770 exception:nil |
|
1771 withTimeOut:0. |
|
1772 |
|
1773 (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[ |
|
1774 ('PROCESSOR: remove invalid read fileDescriptor: ' , fd printString) errorPrintNL. |
|
1775 readFdArray at:idx put:nil |
|
1776 ] |
|
1777 ]. |
|
1778 |
|
1779 writeFdArray keysAndValuesDo:[:idx :fd | |
|
1780 |rslt| |
|
1781 |
|
1782 rslt := OperatingSystem |
|
1783 selectOnAnyReadable:nil |
|
1784 writable:(Array with:fd) |
|
1785 exception:nil |
|
1786 withTimeOut:0. |
|
1787 |
|
1788 (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[ |
|
1789 ('PROCESSOR: removing invalid write fileDescriptor: ' , fd printString) errorPrintNL. |
|
1790 writeFdArray at:idx put:nil |
|
1791 ] |
|
1792 ]. |
|
1793 ! |
|
1794 |
|
1795 checkForInputWithTimeout:millis |
1761 checkForInputWithTimeout:millis |
1796 "this is called, when there is absolutely nothing to do; |
1762 "this is called, when there is absolutely nothing to do; |
1797 hard wait for either input to arrive or a timeout to occur." |
1763 hard wait for either input to arrive or a timeout to occur." |
1798 |
1764 |
1799 |fd index sema action| |
1765 |fd index sema action| |
1840 self threadSwitch:scheduler |
1806 self threadSwitch:scheduler |
1841 |
1807 |
1842 "Modified: 21.12.1995 / 16:17:40 / stefan" |
1808 "Modified: 21.12.1995 / 16:17:40 / stefan" |
1843 ! |
1809 ! |
1844 |
1810 |
|
1811 removeCorruptedFds |
|
1812 "this is sent when select returns an error due to some invalid |
|
1813 fileDescriptor. May happens, if someone does a readWait/writeWait on a |
|
1814 connection, which somehow gets corrupted. |
|
1815 Without special care, all following selects would immediately return with |
|
1816 an #EBADF error, leading to high-frequency polling and a locked up system. |
|
1817 (you could still fix things by interrupting on the console and fixing the |
|
1818 readFdArray/writeFdArray in the debugger)" |
|
1819 |
|
1820 readFdArray keysAndValuesDo:[:idx :fd | |
|
1821 |rslt| |
|
1822 |
|
1823 rslt := OperatingSystem |
|
1824 selectOnAnyReadable:(Array with:fd) |
|
1825 writable:nil |
|
1826 exception:nil |
|
1827 withTimeOut:0. |
|
1828 |
|
1829 (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[ |
|
1830 ('PROCESSOR: remove invalid read fileDescriptor: ' , fd printString) errorPrintNL. |
|
1831 readFdArray at:idx put:nil |
|
1832 ] |
|
1833 ]. |
|
1834 |
|
1835 writeFdArray keysAndValuesDo:[:idx :fd | |
|
1836 |rslt| |
|
1837 |
|
1838 rslt := OperatingSystem |
|
1839 selectOnAnyReadable:nil |
|
1840 writable:(Array with:fd) |
|
1841 exception:nil |
|
1842 withTimeOut:0. |
|
1843 |
|
1844 (rslt isNil and:[OperatingSystem lastErrorSymbol == #EBADF]) ifTrue:[ |
|
1845 ('PROCESSOR: removing invalid write fileDescriptor: ' , fd printString) errorPrintNL. |
|
1846 writeFdArray at:idx put:nil |
|
1847 ] |
|
1848 ]. |
|
1849 ! |
|
1850 |
1845 schedulerInterrupt |
1851 schedulerInterrupt |
1846 "forced reschedule - switch to scheduler process which will decide |
1852 "forced reschedule - switch to scheduler process which will decide |
1847 what to do now." |
1853 what to do now." |
1848 |
1854 |
1849 interruptedProcess := activeProcess. |
1855 interruptedProcess := activeProcess. |