16 readCheckArray writeFdArray writeSemaphoreArray timeoutArray |
16 readCheckArray writeFdArray writeSemaphoreArray timeoutArray |
17 timeoutActionArray timeoutProcessArray timeoutSemaphoreArray |
17 timeoutActionArray timeoutProcessArray timeoutSemaphoreArray |
18 idleActions anyTimeouts dispatching interruptedProcess |
18 idleActions anyTimeouts dispatching interruptedProcess |
19 useIOInterrupts gotIOInterrupt osChildExitActions |
19 useIOInterrupts gotIOInterrupt osChildExitActions |
20 gotChildSignalInterrupt exitWhenNoMoreUserProcesses |
20 gotChildSignalInterrupt exitWhenNoMoreUserProcesses |
21 suspendScheduler timeSliceProcess' |
21 suspendScheduler timeSliceProcess processesToRestart' |
22 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
22 classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven |
23 UserSchedulingPriority UserInterruptPriority TimingPriority |
23 UserSchedulingPriority UserInterruptPriority TimingPriority |
24 HighestPriority SchedulingPriority MaxNumberOfProcesses |
24 HighestPriority SchedulingPriority MaxNumberOfProcesses |
25 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
25 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval |
26 EventPollingInterval' |
26 EventPollingInterval' |
743 A userProcess is defined as a process with a non-zero processGroup. |
743 A userProcess is defined as a process with a non-zero processGroup. |
744 This flag is typically set for standAlone operation, to terminate the (Unix-) |
744 This flag is typically set for standAlone operation, to terminate the (Unix-) |
745 process, when the last thread terminates." |
745 process, when the last thread terminates." |
746 |
746 |
747 exitWhenNoMoreUserProcesses := aBoolean |
747 exitWhenNoMoreUserProcesses := aBoolean |
|
748 ! ! |
|
749 |
|
750 !ProcessorScheduler methodsFor:'initializing'! |
|
751 |
|
752 initialize |
|
753 "initialize the one-and-only ProcessorScheduler" |
|
754 |
|
755 |nPrios "{ Class: SmallInteger }" |
|
756 p l| |
|
757 |
|
758 KnownProcesses isNil ifTrue:[ |
|
759 KnownProcesses := WeakArray new:30. |
|
760 KnownProcesses addDependent:self class. |
|
761 KnownProcessIds := OrderedCollection new. |
|
762 ]. |
|
763 |
|
764 " |
|
765 create a collection with process lists; accessed using the priority as key |
|
766 " |
|
767 nPrios := SchedulingPriority. |
|
768 quiescentProcessLists := Array new:nPrios. |
|
769 "/ 1 to:nPrios do:[:pri | |
|
770 "/ quiescentProcessLists at:pri put:(LinkedList new) |
|
771 "/ ]. |
|
772 |
|
773 readFdArray := Array with:nil. |
|
774 readCheckArray := Array with:nil. |
|
775 readSemaphoreArray := Array with:nil. |
|
776 writeFdArray := Array with:nil. |
|
777 writeSemaphoreArray := Array with:nil. |
|
778 timeoutArray := Array with:nil. |
|
779 timeoutSemaphoreArray := Array with:nil. |
|
780 timeoutActionArray := Array with:nil. |
|
781 timeoutProcessArray := Array with:nil. |
|
782 anyTimeouts := false. |
|
783 dispatching := false. |
|
784 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
|
785 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
|
786 gotIOInterrupt := false. |
|
787 osChildExitActions := Dictionary new. |
|
788 gotChildSignalInterrupt := false. |
|
789 |
|
790 " |
|
791 handcraft the first (dispatcher-) process - this one will never |
|
792 block, but go into a select if there is nothing to do. |
|
793 Also, it has a prio of max+1 - thus, it comes first when looking |
|
794 for a runnable process. |
|
795 " |
|
796 currentPriority := SchedulingPriority. |
|
797 p := Process basicNew. |
|
798 p setId:0 state:#run. |
|
799 p setPriority:currentPriority. |
|
800 p name:'scheduler'. |
|
801 |
|
802 scheduler := activeProcess := p. |
|
803 activeProcessId := 0. |
|
804 |
|
805 quiescentProcessLists at:currentPriority put:(l := LinkedList new). |
|
806 l add:p. |
|
807 |
|
808 " |
|
809 let me handle IO and timer interrupts |
|
810 " |
|
811 ObjectMemory ioInterruptHandler:self. |
|
812 ObjectMemory timerInterruptHandler:self. |
|
813 ObjectMemory childSignalInterruptHandler:self. |
|
814 |
|
815 "Modified: 29.7.1996 / 12:10:59 / cg" |
|
816 "Modified: 7.1.1997 / 16:48:26 / stefan" |
|
817 ! |
|
818 |
|
819 reinitialize |
|
820 "all previous processes (except those marked as restartable) are made dead |
|
821 - each object should reinstall its process(s) upon restart; |
|
822 especially, windowgroups have to. |
|
823 In contrast to ST-80, restartable processes are restarted at the beginning |
|
824 NOT continued where left. This is a consequence of the portable implementation |
|
825 of ST/X, since in order to continue a process, we needed to know the |
|
826 internals of the machines (and C-compilers) stack layout. |
|
827 This was not done, favouring portability for process continuation. |
|
828 In praxis, this is not much of a problem, since in almost every case, |
|
829 the computation state can be saved in some object, and processing be |
|
830 restarted from scratch, reinitializing things from this saved state." |
|
831 |
|
832 " |
|
833 lay all processes to rest, collect restartable ones |
|
834 " |
|
835 processesToRestart := OrderedCollection new. |
|
836 KnownProcesses do:[:p | |
|
837 (p notNil and:[p ~~ 0]) ifTrue:[ |
|
838 "how, exactly should this be done ?" |
|
839 |
|
840 p isRestartable == true ifTrue:[ |
|
841 p nextLink:nil. |
|
842 processesToRestart add:p |
|
843 ] ifFalse:[ |
|
844 p setId:nil state:#dead |
|
845 ] |
|
846 ]. |
|
847 ]. |
|
848 scheduler setId:nil state:#dead. |
|
849 |
|
850 " |
|
851 now, start from scratch |
|
852 " |
|
853 KnownProcesses := nil. |
|
854 self initialize. |
|
855 |
|
856 "Modified: / 7.6.1998 / 02:05:47 / cg" |
|
857 ! |
|
858 |
|
859 restartRestartableProcesses |
|
860 "restart those that can be. |
|
861 This must be done as a second step, to make certain that all |
|
862 of the GUI classes are intitialized first (and, especially the |
|
863 event dispatching mechanism is running)" |
|
864 |
|
865 |procs| |
|
866 |
|
867 procs := processesToRestart. |
|
868 procs notNil ifTrue:[ |
|
869 processesToRestart := nil. |
|
870 |
|
871 procs do:[:p | |
|
872 p imageRestart |
|
873 ] |
|
874 ] |
|
875 |
|
876 "Created: / 7.6.1998 / 02:06:52 / cg" |
|
877 "Modified: / 7.6.1998 / 02:07:59 / cg" |
748 ! ! |
878 ! ! |
749 |
879 |
750 !ProcessorScheduler methodsFor:'os process handling'! |
880 !ProcessorScheduler methodsFor:'os process handling'! |
751 |
881 |
752 childSignalInterrupt |
882 childSignalInterrupt |
1138 index ~~ 0 ifTrue:[ |
1268 index ~~ 0 ifTrue:[ |
1139 KnownProcessIds at:index put:nil. |
1269 KnownProcessIds at:index put:nil. |
1140 KnownProcesses at:index put:nil. |
1270 KnownProcesses at:index put:nil. |
1141 ]. |
1271 ]. |
1142 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1272 wasBlocked ifFalse:[OperatingSystem unblockInterrupts]. |
1143 ! ! |
|
1144 |
|
1145 !ProcessorScheduler methodsFor:'private initializing'! |
|
1146 |
|
1147 initialize |
|
1148 "initialize the one-and-only ProcessorScheduler" |
|
1149 |
|
1150 |nPrios "{ Class: SmallInteger }" |
|
1151 p l| |
|
1152 |
|
1153 KnownProcesses isNil ifTrue:[ |
|
1154 KnownProcesses := WeakArray new:30. |
|
1155 KnownProcesses addDependent:self class. |
|
1156 KnownProcessIds := OrderedCollection new. |
|
1157 ]. |
|
1158 |
|
1159 " |
|
1160 create a collection with process lists; accessed using the priority as key |
|
1161 " |
|
1162 nPrios := SchedulingPriority. |
|
1163 quiescentProcessLists := Array new:nPrios. |
|
1164 "/ 1 to:nPrios do:[:pri | |
|
1165 "/ quiescentProcessLists at:pri put:(LinkedList new) |
|
1166 "/ ]. |
|
1167 |
|
1168 readFdArray := Array with:nil. |
|
1169 readCheckArray := Array with:nil. |
|
1170 readSemaphoreArray := Array with:nil. |
|
1171 writeFdArray := Array with:nil. |
|
1172 writeSemaphoreArray := Array with:nil. |
|
1173 timeoutArray := Array with:nil. |
|
1174 timeoutSemaphoreArray := Array with:nil. |
|
1175 timeoutActionArray := Array with:nil. |
|
1176 timeoutProcessArray := Array with:nil. |
|
1177 anyTimeouts := false. |
|
1178 dispatching := false. |
|
1179 exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ? |
|
1180 useIOInterrupts := OperatingSystem supportsIOInterrupts. |
|
1181 gotIOInterrupt := false. |
|
1182 osChildExitActions := Dictionary new. |
|
1183 gotChildSignalInterrupt := false. |
|
1184 |
|
1185 " |
|
1186 handcraft the first (dispatcher-) process - this one will never |
|
1187 block, but go into a select if there is nothing to do. |
|
1188 Also, it has a prio of max+1 - thus, it comes first when looking |
|
1189 for a runnable process. |
|
1190 " |
|
1191 currentPriority := SchedulingPriority. |
|
1192 p := Process basicNew. |
|
1193 p setId:0 state:#run. |
|
1194 p setPriority:currentPriority. |
|
1195 p name:'scheduler'. |
|
1196 |
|
1197 scheduler := activeProcess := p. |
|
1198 activeProcessId := 0. |
|
1199 |
|
1200 quiescentProcessLists at:currentPriority put:(l := LinkedList new). |
|
1201 l add:p. |
|
1202 |
|
1203 " |
|
1204 let me handle IO and timer interrupts |
|
1205 " |
|
1206 ObjectMemory ioInterruptHandler:self. |
|
1207 ObjectMemory timerInterruptHandler:self. |
|
1208 ObjectMemory childSignalInterruptHandler:self. |
|
1209 |
|
1210 "Modified: 29.7.1996 / 12:10:59 / cg" |
|
1211 "Modified: 7.1.1997 / 16:48:26 / stefan" |
|
1212 ! |
|
1213 |
|
1214 reinitialize |
|
1215 "all previous processes (except those marked as restartable) are made dead |
|
1216 - each object should reinstall its process(s) upon restart; |
|
1217 especially, windowgroups have to. |
|
1218 In contrast to ST-80, restartable processes are restarted at the beginning |
|
1219 NOT continued where left. This is a consequence of the portable implementation |
|
1220 of ST/X, since in order to continue a process, we needed to know the |
|
1221 internals of the machines (and C-compilers) stack layout. |
|
1222 This was not done, favouring portability for process continuation. |
|
1223 In praxis, this is not much of a problem, since in almost every case, |
|
1224 the computation state can be saved in some object, and processing be |
|
1225 restarted from scratch, reinitializing things from this saved state." |
|
1226 |
|
1227 |processesToRestart| |
|
1228 |
|
1229 " |
|
1230 lay all processes to rest, collect restartable ones |
|
1231 " |
|
1232 processesToRestart := OrderedCollection new. |
|
1233 KnownProcesses do:[:p | |
|
1234 (p notNil and:[p ~~ 0]) ifTrue:[ |
|
1235 "how, exactly should this be done ?" |
|
1236 |
|
1237 p isRestartable == true ifTrue:[ |
|
1238 p nextLink:nil. |
|
1239 processesToRestart add:p |
|
1240 ] ifFalse:[ |
|
1241 p setId:nil state:#dead |
|
1242 ] |
|
1243 ]. |
|
1244 ]. |
|
1245 scheduler setId:nil state:#dead. |
|
1246 |
|
1247 " |
|
1248 now, start from scratch |
|
1249 " |
|
1250 KnownProcesses := nil. |
|
1251 self initialize. |
|
1252 |
|
1253 " |
|
1254 ... and restart those that can be. |
|
1255 " |
|
1256 processesToRestart do:[:p | |
|
1257 p imageRestart |
|
1258 ] |
|
1259 |
|
1260 "Modified: 28.10.1996 / 20:45:54 / cg" |
|
1261 ! ! |
1273 ! ! |
1262 |
1274 |
1263 !ProcessorScheduler methodsFor:'process creation'! |
1275 !ProcessorScheduler methodsFor:'process creation'! |
1264 |
1276 |
1265 newProcessFor:aProcess |
1277 newProcessFor:aProcess |