ProcessorScheduler.st
changeset 10495 c2aa28a1ca72
parent 10494 3f422740eb30
child 10497 3c6d5a8121a3
equal deleted inserted replaced
10494:3f422740eb30 10495:c2aa28a1ca72
     1 "
     1 "
     2  COPYRIGHT (c) 1993 by Claus Gittinger
     2  COPYRIGHT (c) 1993 by Claus Gittinger
     3               All Rights Reserved
     3 	      All Rights Reserved
     4 
     4 
     5  This software is furnished under a license and may be used
     5  This software is furnished under a license and may be used
     6  only in accordance with the terms of that license and with the
     6  only in accordance with the terms of that license and with the
     7  inclusion of the above copyright notice.   This software may not
     7  inclusion of the above copyright notice.   This software may not
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
    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.
   380      (warning: low level entry, no administration done)"
   380      (warning: low level entry, no administration done)"
   381 
   381 
   382 %{  /* NOCONTEXT */
   382 %{  /* NOCONTEXT */
   383 
   383 
   384     if (__isSmallInteger(id)) {
   384     if (__isSmallInteger(id)) {
   385         __threadDestroy(__intVal(id));
   385 	__threadDestroy(__intVal(id));
   386     }
   386     }
   387 %}
   387 %}
   388 !
   388 !
   389 
   389 
   390 threadInterrupt:id
   390 threadInterrupt:id
   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"
   854 
   854 
   855     |nPrios "{ Class: SmallInteger }"
   855     |nPrios "{ Class: SmallInteger }"
   856      p l|
   856      p l|
   857 
   857 
   858     KnownProcesses isNil ifTrue:[
   858     KnownProcesses isNil ifTrue:[
   859         KnownProcesses := WeakArray new:30.
   859 	KnownProcesses := WeakArray new:30.
   860         KnownProcesses addDependent:self class.
   860 	KnownProcesses addDependent:self class.
   861         KnownProcessIds := OrderedCollection new.
   861 	KnownProcessIds := OrderedCollection new.
   862     ].
   862     ].
   863 
   863 
   864     "
   864     "
   865      create a collection with process lists; accessed using the priority as key
   865      create a collection with process lists; accessed using the priority as key
   866     "
   866     "
   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 
  1078     "child changed state - switch to scheduler process which will decide 
  1078     "child changed state - switch to scheduler process which will decide 
  1079      what to do now."
  1079      what to do now."
  1080 
  1080 
  1081     gotChildSignalInterrupt := true.
  1081     gotChildSignalInterrupt := true.
  1082     activeProcess ~~ scheduler ifTrue:[
  1082     activeProcess ~~ scheduler ifTrue:[
  1083         interruptedProcess := activeProcess.
  1083 	interruptedProcess := activeProcess.
  1084         self threadSwitch:scheduler
  1084 	self threadSwitch:scheduler
  1085     ]
  1085     ]
  1086 
  1086 
  1087     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1087     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1088 !
  1088 !
  1089 
  1089 
  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"
  1493     |index wasBlocked|
  1493     |index wasBlocked|
  1494 
  1494 
  1495     wasBlocked := OperatingSystem blockInterrupts.
  1495     wasBlocked := OperatingSystem blockInterrupts.
  1496     index := KnownProcesses identityIndexOf:aProcess.
  1496     index := KnownProcesses identityIndexOf:aProcess.
  1497     index ~~ 0 ifTrue:[
  1497     index ~~ 0 ifTrue:[
  1498         KnownProcessIds at:index put:nil.
  1498 	KnownProcessIds at:index put:nil.
  1499         KnownProcesses at:index put:nil.
  1499 	KnownProcesses at:index put:nil.
  1500     ].
  1500     ].
  1501     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1501     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1502 ! !
  1502 ! !
  1503 
  1503 
  1504 !ProcessorScheduler methodsFor:'process creation'!
  1504 !ProcessorScheduler methodsFor:'process creation'!
  1565     wasBlocked := OperatingSystem blockInterrupts.
  1565     wasBlocked := OperatingSystem blockInterrupts.
  1566 
  1566 
  1567     listArray := quiescentProcessLists.
  1567     listArray := quiescentProcessLists.
  1568 
  1568 
  1569     [prio >= 1] whileTrue:[
  1569     [prio >= 1] whileTrue:[
  1570         l := listArray at:prio.
  1570 	l := listArray at:prio.
  1571         l notNil ifTrue:[
  1571 	l notNil ifTrue:[
  1572             l do:[:aProcess |
  1572 	    l do:[:aProcess |
  1573                 aProcess processGroupId ~~ 0 ifTrue:[
  1573 		aProcess processGroupId ~~ 0 ifTrue:[
  1574                     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1574 		    wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1575                     ^ true.
  1575 		    ^ true.
  1576                 ]
  1576 		]
  1577             ]
  1577 	    ]
  1578         ].
  1578 	].
  1579         prio := prio - 1
  1579 	prio := prio - 1
  1580     ].
  1580     ].
  1581     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1581     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1582     ^ false
  1582     ^ false
  1583 
  1583 
  1584     "
  1584     "
  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 !
  2249 
  2249 
  2250 stopTimeSlicing
  2250 stopTimeSlicing
  2251     "stop preemptive scheduling (timeSlicing)"
  2251     "stop preemptive scheduling (timeSlicing)"
  2252 
  2252 
  2253     timeSliceProcess notNil ifTrue: [
  2253     timeSliceProcess notNil ifTrue: [
  2254         timeSliceProcess terminate.
  2254 	timeSliceProcess terminate.
  2255         timeSliceProcess := nil.
  2255 	timeSliceProcess := nil.
  2256         scheduledProcesses := nil
  2256 	scheduledProcesses := nil
  2257     ]
  2257     ]
  2258 
  2258 
  2259     "
  2259     "
  2260      Processor stopTimeSlicing
  2260      Processor stopTimeSlicing
  2261     "
  2261     "
  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
  2725     wasBlocked := OperatingSystem blockInterrupts.
  2725     wasBlocked := OperatingSystem blockInterrupts.
  2726     now := OperatingSystem getMillisecondTime.
  2726     now := OperatingSystem getMillisecondTime.
  2727     then := OperatingSystem millisecondTimeAdd:now and:delta.
  2727     then := OperatingSystem millisecondTimeAdd:now and:delta.
  2728 
  2728 
  2729     id := self
  2729     id := self
  2730         addTimeoutFunctionCall:anExternalFunction 
  2730 	addTimeoutFunctionCall:anExternalFunction 
  2731         for:aProcess 
  2731 	for:aProcess 
  2732         atMilliseconds:then 
  2732 	atMilliseconds:then 
  2733         with:argument.
  2733 	with:argument.
  2734 
  2734 
  2735     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2735     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2736     ^ id
  2736     ^ id
  2737 
  2737 
  2738     "Created: 23.9.1996 / 14:28:27 / cg"
  2738     "Created: 23.9.1996 / 14:28:27 / cg"
  2751 
  2751 
  2752     |action|
  2752     |action|
  2753 
  2753 
  2754     action := [anExternalFunction callWith:argument].
  2754     action := [anExternalFunction callWith:argument].
  2755     ^ self
  2755     ^ self
  2756         addTimedBlock:action 
  2756 	addTimedBlock:action 
  2757         for:aProcess 
  2757 	for:aProcess 
  2758         atMilliseconds:milliTime.
  2758 	atMilliseconds:milliTime.
  2759 
  2759 
  2760     "Created: 23.9.1996 / 14:29:30 / cg"
  2760     "Created: 23.9.1996 / 14:29:30 / cg"
  2761     "Modified: 23.9.1996 / 14:34:57 / cg"
  2761     "Modified: 23.9.1996 / 14:34:57 / cg"
  2762 !
  2762 !
  2763 
  2763 
  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 !
  3192 schedulerInterrupt
  3192 schedulerInterrupt
  3193     "forced reschedule - switch to scheduler process which will decide
  3193     "forced reschedule - switch to scheduler process which will decide
  3194      what to do now."
  3194      what to do now."
  3195 
  3195 
  3196     activeProcess ~~ scheduler ifTrue:[
  3196     activeProcess ~~ scheduler ifTrue:[
  3197         interruptedProcess := activeProcess.
  3197 	interruptedProcess := activeProcess.
  3198         self threadSwitch:scheduler
  3198 	self threadSwitch:scheduler
  3199     ]
  3199     ]
  3200 !
  3200 !
  3201 
  3201 
  3202 timeToNextTimeout
  3202 timeToNextTimeout
  3203     "return the delta-T (in millis) to next timeout, or nil if
  3203     "return the delta-T (in millis) to next timeout, or nil if
  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             ]
  3350 ! !
  3346 ! !
  3351 
  3347 
  3352 !ProcessorScheduler class methodsFor:'documentation'!
  3348 !ProcessorScheduler class methodsFor:'documentation'!
  3353 
  3349 
  3354 version
  3350 version
  3355     ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.241 2007-04-03 16:39:13 stefan Exp $'
  3351     ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.242 2007-04-03 16:47:43 stefan Exp $'
  3356 ! !
  3352 ! !
  3357 
  3353 
  3358 ProcessorScheduler initialize!
  3354 ProcessorScheduler initialize!