ProcessorScheduler.st
changeset 22095 d7d5b3f3cc88
parent 22094 93705f0c6a54
child 22146 0a52bd3e639a
equal deleted inserted replaced
22094:93705f0c6a54 22095:d7d5b3f3cc88
     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
    12 "{ Package: 'stx:libbasic' }"
    12 "{ Package: 'stx:libbasic' }"
    13 
    13 
    14 "{ NameSpace: Smalltalk }"
    14 "{ NameSpace: Smalltalk }"
    15 
    15 
    16 Object subclass:#ProcessorScheduler
    16 Object subclass:#ProcessorScheduler
    17 	instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess
    17         instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess
    18 		activeProcessId currentPriority readFdArray readSemaphoreArray
    18                 activeProcessId currentPriority readFdArray readSemaphoreArray
    19 		readCheckArray writeFdArray writeSemaphoreArray writeCheckArray
    19                 readCheckArray writeFdArray writeSemaphoreArray writeCheckArray
    20 		timeoutArray timeoutActionArray timeoutProcessArray
    20                 timeoutArray timeoutActionArray timeoutProcessArray
    21 		timeoutSemaphoreArray idleActions anyTimeouts dispatching
    21                 timeoutSemaphoreArray idleActions anyTimeouts dispatching
    22 		interruptedProcess useIOInterrupts gotIOInterrupt
    22                 interruptedProcess useIOInterrupts gotIOInterrupt
    23 		osChildExitActions gotChildSignalInterrupt
    23                 osChildExitActions gotChildSignalInterrupt
    24 		exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess
    24                 exitWhenNoMoreUserProcesses suspendScheduler timeSliceProcess
    25 		supportDynamicPriorities timeSliceNeededSemaphore
    25                 supportDynamicPriorities timeSliceNeededSemaphore
    26 		scheduledProcesses preWaitActions timeoutHandlerProcess
    26                 scheduledProcesses preWaitActions timeoutHandlerProcess
    27 		readableResultFdArray writableResultFdArray exceptFdArray
    27                 readableResultFdArray writableResultFdArray exceptFdArray
    28 		exceptResultFdArray exceptSemaphoreArray interruptCounter
    28                 exceptResultFdArray exceptSemaphoreArray interruptCounter
    29 		timedActionCounter'
    29                 timedActionCounter'
    30 	classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    30         classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    31 		UserSchedulingPriority UserInterruptPriority TimingPriority
    31                 UserSchedulingPriority UserInterruptPriority TimingPriority
    32 		HighestPriority SchedulingPriority MaxNumberOfProcesses
    32                 HighestPriority SchedulingPriority MaxNumberOfProcesses
    33 		InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval
    33                 InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval
    34 		EventPollingInterval MaxProcessId'
    34                 EventPollingInterval MaxProcessId'
    35 	poolDictionaries:''
    35         poolDictionaries:''
    36 	category:'Kernel-Processes'
    36         category:'Kernel-Processes'
    37 !
    37 !
    38 
    38 
    39 !ProcessorScheduler class methodsFor:'documentation'!
    39 !ProcessorScheduler class methodsFor:'documentation'!
    40 
    40 
    41 copyright
    41 copyright
    42 "
    42 "
    43  COPYRIGHT (c) 1993 by Claus Gittinger
    43  COPYRIGHT (c) 1993 by Claus Gittinger
    44 	      All Rights Reserved
    44               All Rights Reserved
    45 
    45 
    46  This software is furnished under a license and may be used
    46  This software is furnished under a license and may be used
    47  only in accordance with the terms of that license and with the
    47  only in accordance with the terms of that license and with the
    48  inclusion of the above copyright notice.   This software may not
    48  inclusion of the above copyright notice.   This software may not
    49  be provided or otherwise made available to, or used by, any
    49  be provided or otherwise made available to, or used by, any
   222     event.
   222     event.
   223     Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which
   223     Timeslicing will not be done for processes running above TimeSlicingPriorityLimit, which
   224     allows for critical processes to run unaffected to completion.
   224     allows for critical processes to run unaffected to completion.
   225 
   225 
   226     WARNING:
   226     WARNING:
   227 	timesliced priority scheduling is an experimental feature. There is no warranty,
   227         timesliced priority scheduling is an experimental feature. There is no warranty,
   228 	(at the moment), that the system runs reliable in this mode.
   228         (at the moment), that the system runs reliable in this mode.
   229 	The problem is, that shared collections may now be easily modified by other
   229         The problem is, that shared collections may now be easily modified by other
   230 	processes, running at the same time.
   230         processes, running at the same time.
   231 	The class library has being investigated for such possible trouble spots
   231         The class library has being investigated for such possible trouble spots
   232 	(we have eliminated many weak spots, and added critical regions at many places,
   232         (we have eliminated many weak spots, and added critical regions at many places,
   233 	 but cannot guarantee that all of them have been found so far ...)
   233          but cannot guarantee that all of them have been found so far ...)
   234 	We found that many existing public domain programs are not prepared for
   234         We found that many existing public domain programs are not prepared for
   235 	being interrupted by a same-prio process and therefore may corrupt their
   235         being interrupted by a same-prio process and therefore may corrupt their
   236 	data. If in doubt, disable this fefature.
   236         data. If in doubt, disable this fefature.
   237 
   237 
   238     We think, that the timeSlicer is a useful add-on and that the system is fit enough
   238     We think, that the timeSlicer is a useful add-on and that the system is fit enough
   239     for it to be evaluated, therefore, its included.
   239     for it to be evaluated, therefore, its included.
   240     However, use it at your own risk.
   240     However, use it at your own risk.
   241 
   241 
   242     To demonstrate the effect of timeSlicing, do the following:
   242     To demonstrate the effect of timeSlicing, do the following:
   243 
   243 
   244 	- disable timeSlicing (in the launchers misc-settings menu)
   244         - disable timeSlicing (in the launchers misc-settings menu)
   245 	- open a workSpace
   245         - open a workSpace
   246 	- in the workspace, evaluate:
   246         - in the workspace, evaluate:
   247 		[true] whileTrue:[1000 factorial]
   247                 [true] whileTrue:[1000 factorial]
   248 
   248 
   249     now, (since the workSpace runs at the same prio as other window-processes),
   249     now, (since the workSpace runs at the same prio as other window-processes),
   250     other views do no longer react - all CPU is used up by the workSpace.
   250     other views do no longer react - all CPU is used up by the workSpace.
   251     However, CTRL-C in the workspace is still possible to stop the endless loop,
   251     However, CTRL-C in the workspace is still possible to stop the endless loop,
   252     since that is handled by the (higher prio) event dispatcher process.
   252     since that is handled by the (higher prio) event dispatcher process.
   272     TimeSlicingPriorityLimit := 26.
   272     TimeSlicingPriorityLimit := 26.
   273     HighestPriority := 30.
   273     HighestPriority := 30.
   274     SchedulingPriority := 31.
   274     SchedulingPriority := 31.
   275 
   275 
   276     InvalidProcessSignal isNil ifTrue:[
   276     InvalidProcessSignal isNil ifTrue:[
   277 	InvalidProcessSignal := Error newSignalMayProceed:true.
   277         InvalidProcessSignal := Error newSignalMayProceed:true.
   278 	InvalidProcessSignal nameClass:self message:#invalidProcessSignal.
   278         InvalidProcessSignal nameClass:self message:#invalidProcessSignal.
   279 	InvalidProcessSignal notifierString:'invalid process'.
   279         InvalidProcessSignal notifierString:'invalid process'.
   280     ].
   280     ].
   281 
   281 
   282     Processor isNil ifTrue:[
   282     Processor isNil ifTrue:[
   283 	"create the one and only processor"
   283         "create the one and only processor"
   284 
   284 
   285 	Smalltalk at:#Processor put:(self basicNew initialize).
   285         Smalltalk at:#Processor put:(self basicNew initialize).
   286     ].
   286     ].
   287 
   287 
   288     "
   288     "
   289      allow configurations without processes
   289      allow configurations without processes
   290      (but such configurations are no longer distributed)
   290      (but such configurations are no longer distributed)
   291     "
   291     "
   292     PureEventDriven := self threadsAvailable not.
   292     PureEventDriven := self threadsAvailable not.
   293     PureEventDriven ifTrue:[
   293     PureEventDriven ifTrue:[
   294 	'Processor [error]: no process support - running event driven' errorPrintCR
   294         'Processor [error]: no process support - running event driven' errorPrintCR
   295     ].
   295     ].
   296     self initializeVMMaxProcessId
   296     self initializeVMMaxProcessId
   297 
   297 
   298     "Modified: / 23-09-1996 / 14:24:50 / stefan"
   298     "Modified: / 23-09-1996 / 14:24:50 / stefan"
   299     "Modified: / 10-01-1997 / 18:03:03 / cg"
   299     "Modified: / 10-01-1997 / 18:03:03 / cg"
   344      by sending #terminate."
   344      by sending #terminate."
   345 
   345 
   346     |id sz "{ Class: SmallInteger }"|
   346     |id sz "{ Class: SmallInteger }"|
   347 
   347 
   348     something == #ElementExpired ifTrue:[
   348     something == #ElementExpired ifTrue:[
   349 	sz := KnownProcessIds size.
   349         sz := KnownProcessIds size.
   350 	1 to:sz do:[:index |
   350         1 to:sz do:[:index |
   351 	    "/ (KnownProcesses at:index) isNil ifTrue:[
   351             "/ (KnownProcesses at:index) isNil ifTrue:[
   352 	    (KnownProcesses at:index) class == SmallInteger ifTrue:[
   352             (KnownProcesses at:index) class == SmallInteger ifTrue:[
   353 		id := KnownProcessIds at:index.
   353                 id := KnownProcessIds at:index.
   354 		id notNil ifTrue:[
   354                 id notNil ifTrue:[
   355 		    'Processor [warning]: terminating thread ' errorPrint.
   355                     'Processor [warning]: terminating thread ' errorPrint.
   356 		    id errorPrint.
   356                     id errorPrint.
   357 		    ' (no longer refd)' errorPrintCR.
   357                     ' (no longer refd)' errorPrintCR.
   358 
   358 
   359 		    self threadDestroy:id.
   359                     self threadDestroy:id.
   360 		    KnownProcessIds at:index put:nil.
   360                     KnownProcessIds at:index put:nil.
   361 		].
   361                 ].
   362 		KnownProcesses at:index put:nil.
   362                 KnownProcesses at:index put:nil.
   363 	    ]
   363             ]
   364 	]
   364         ]
   365     ]
   365     ]
   366 
   366 
   367     "Created: 7.1.1997 / 16:45:42 / stefan"
   367     "Created: 7.1.1997 / 16:45:42 / stefan"
   368     "Modified: 10.1.1997 / 19:10:48 / cg"
   368     "Modified: 10.1.1997 / 19:10:48 / cg"
   369 ! !
   369 ! !
   416      (warning: low level entry, no administration done)"
   416      (warning: low level entry, no administration done)"
   417 
   417 
   418 %{  /* NOCONTEXT */
   418 %{  /* NOCONTEXT */
   419 
   419 
   420     if (__isSmallInteger(id)) {
   420     if (__isSmallInteger(id)) {
   421 	__threadDestroy(__intVal(id));
   421         __threadDestroy(__intVal(id));
   422     }
   422     }
   423 %}
   423 %}
   424 !
   424 !
   425 
   425 
   426 threadInterrupt:id
   426 threadInterrupt:id
   430      interrupt (currently, it looks for interruptBlocks to evaluate)."
   430      interrupt (currently, it looks for interruptBlocks to evaluate)."
   431 
   431 
   432 %{  /* NOCONTEXT */
   432 %{  /* NOCONTEXT */
   433 
   433 
   434     if (__isSmallInteger(id)) {
   434     if (__isSmallInteger(id)) {
   435 	__threadInterrupt(__intVal(id));
   435         __threadInterrupt(__intVal(id));
   436     }
   436     }
   437 %}
   437 %}
   438 !
   438 !
   439 
   439 
   440 threadsAvailable
   440 threadsAvailable
   472 
   472 
   473 knownProcessesDo:aBlock
   473 knownProcessesDo:aBlock
   474     "evaluate aBlock for each (living) processes in the system"
   474     "evaluate aBlock for each (living) processes in the system"
   475 
   475 
   476     KnownProcesses do:[:p |
   476     KnownProcesses do:[:p |
   477 	(p notNil and:[p class ~~ SmallInteger]) ifTrue:[aBlock value:p]
   477         (p notNil and:[p class ~~ SmallInteger]) ifTrue:[aBlock value:p]
   478     ]
   478     ]
   479 
   479 
   480     "Created: / 26-10-2012 / 13:02:33 / cg"
   480     "Created: / 26-10-2012 / 13:02:33 / cg"
   481 !
   481 !
   482 
   482 
   526 
   526 
   527     |idx "{Class: SmallInteger }"
   527     |idx "{Class: SmallInteger }"
   528      wasBlocked|
   528      wasBlocked|
   529 
   529 
   530     aFileDescriptor < 0 ifTrue:[
   530     aFileDescriptor < 0 ifTrue:[
   531 	'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR.
   531         'Processor [warning]: ignored invalid fd for IO action.' errorPrintCR.
   532 	thisContext fullPrintAll.
   532         thisContext fullPrintAll.
   533 	^ self
   533         ^ self
   534     ].
   534     ].
   535 
   535 
   536     wasBlocked := OperatingSystem blockInterrupts.
   536     wasBlocked := OperatingSystem blockInterrupts.
   537     (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[
   537     (readFdArray identityIndexOf:aFileDescriptor startingAt:1) == 0 ifTrue:[
   538 	idx := readFdArray identityIndexOf:nil startingAt:1.
   538         idx := readFdArray identityIndexOf:nil startingAt:1.
   539 	idx ~~ 0 ifTrue:[
   539         idx ~~ 0 ifTrue:[
   540 	    readFdArray at:idx put:aFileDescriptor.
   540             readFdArray at:idx put:aFileDescriptor.
   541 	    readCheckArray at:idx put:aBlock.
   541             readCheckArray at:idx put:aBlock.
   542 	    readSemaphoreArray at:idx put:nil
   542             readSemaphoreArray at:idx put:nil
   543 	] ifFalse:[
   543         ] ifFalse:[
   544 	    readFdArray := readFdArray copyWith:aFileDescriptor.
   544             readFdArray := readFdArray copyWith:aFileDescriptor.
   545 	    readCheckArray := readCheckArray copyWith:aBlock.
   545             readCheckArray := readCheckArray copyWith:aBlock.
   546 	    readSemaphoreArray := readSemaphoreArray copyWith:nil.
   546             readSemaphoreArray := readSemaphoreArray copyWith:nil.
   547 	].
   547         ].
   548 	useIOInterrupts ifTrue:[
   548         useIOInterrupts ifTrue:[
   549 	    OperatingSystem enableIOInterruptsOn:aFileDescriptor
   549             OperatingSystem enableIOInterruptsOn:aFileDescriptor
   550 	].
   550         ].
   551 
   551 
   552     ].
   552     ].
   553     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   553     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   554 
   554 
   555     "Modified: 4.8.1997 / 15:17:28 / cg"
   555     "Modified: 4.8.1997 / 15:17:28 / cg"
   650 
   650 
   651     |wasBlocked|
   651     |wasBlocked|
   652 
   652 
   653     wasBlocked := OperatingSystem blockInterrupts.
   653     wasBlocked := OperatingSystem blockInterrupts.
   654     idleActions isNil ifTrue:[
   654     idleActions isNil ifTrue:[
   655 	idleActions := OrderedCollection new
   655         idleActions := OrderedCollection new
   656     ].
   656     ].
   657     idleActions add:aBlock.
   657     idleActions add:aBlock.
   658     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   658     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   659 !
   659 !
   660 
   660 
   928 
   928 
   929     |nPrios "{ Class: SmallInteger }"
   929     |nPrios "{ Class: SmallInteger }"
   930      p l|
   930      p l|
   931 
   931 
   932     KnownProcesses isNil ifTrue:[
   932     KnownProcesses isNil ifTrue:[
   933 	KnownProcesses := WeakArray new:30.
   933         KnownProcesses := WeakArray new:30.
   934 	KnownProcesses addDependent:self class.
   934         KnownProcesses addDependent:self class.
   935 	KnownProcessIds := OrderedCollection new:30.
   935         KnownProcessIds := OrderedCollection new:30.
   936     ].
   936     ].
   937 
   937 
   938     "
   938     "
   939      create a collection with process lists; accessed using the priority as key
   939      create a collection with process lists; accessed using the priority as key
   940     "
   940     "
   963     gotChildSignalInterrupt := false.
   963     gotChildSignalInterrupt := false.
   964     interruptCounter := timedActionCounter := 0.
   964     interruptCounter := timedActionCounter := 0.
   965 
   965 
   966     supportDynamicPriorities := false.
   966     supportDynamicPriorities := false.
   967     exitWhenNoMoreUserProcesses isNil ifTrue:[
   967     exitWhenNoMoreUserProcesses isNil ifTrue:[
   968 	exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ?
   968         exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ?
   969     ].
   969     ].
   970 
   970 
   971     "
   971     "
   972      handcraft the first (dispatcher-) process - this one will never
   972      handcraft the first (dispatcher-) process - this one will never
   973      block, but go into a select if there is nothing to do.
   973      block, but go into a select if there is nothing to do.
   975      for a runnable process.
   975      for a runnable process.
   976     "
   976     "
   977     currentPriority := SchedulingPriority.
   977     currentPriority := SchedulingPriority.
   978     p := Process basicNew.
   978     p := Process basicNew.
   979     p
   979     p
   980 	setId:0 state:#run;
   980         setId:0 state:#run;
   981 	setPriority:currentPriority;
   981         setPriority:currentPriority;
   982 	name:'scheduler';
   982         name:'scheduler';
   983 	beSystemProcess.
   983         beSystemProcess.
   984 
   984 
   985     scheduler := activeProcess := p.
   985     scheduler := activeProcess := p.
   986     activeProcessId := 0.
   986     activeProcessId := 0.
   987 
   987 
   988     quiescentProcessLists at:currentPriority put:(l := LinkedList new).
   988     quiescentProcessLists at:currentPriority put:(l := LinkedList new).
   991     "
   991     "
   992      let me handle IO and timer interrupts
   992      let me handle IO and timer interrupts
   993     "
   993     "
   994     useIOInterrupts ifTrue:[ObjectMemory ioInterruptHandler:self].
   994     useIOInterrupts ifTrue:[ObjectMemory ioInterruptHandler:self].
   995     ObjectMemory
   995     ObjectMemory
   996 	timerInterruptHandler:self;
   996         timerInterruptHandler:self;
   997 	childSignalInterruptHandler:self.
   997         childSignalInterruptHandler:self.
   998 
   998 
   999     "Modified: / 7.1.1997 / 16:48:26 / stefan"
   999     "Modified: / 7.1.1997 / 16:48:26 / stefan"
  1000     "Modified: / 4.2.1999 / 13:08:39 / cg"
  1000     "Modified: / 4.2.1999 / 13:08:39 / cg"
  1001 !
  1001 !
  1002 
  1002 
  1018     "
  1018     "
  1019      lay all processes to rest, collect restartable ones
  1019      lay all processes to rest, collect restartable ones
  1020     "
  1020     "
  1021     processesToRestart := OrderedCollection new.
  1021     processesToRestart := OrderedCollection new.
  1022     KnownProcesses do:[:p |
  1022     KnownProcesses do:[:p |
  1023 	(p notNil and:[p class ~~ SmallInteger]) ifTrue:[
  1023         (p notNil and:[p class ~~ SmallInteger]) ifTrue:[
  1024 	    "how, exactly should this be done ?"
  1024             "how, exactly should this be done ?"
  1025 
  1025 
  1026 	    p isRestartable == true ifTrue:[
  1026             p isRestartable == true ifTrue:[
  1027 		p nextLink:nil.
  1027                 p nextLink:nil.
  1028 		processesToRestart add:p
  1028                 processesToRestart add:p
  1029 	    ] ifFalse:[
  1029             ] ifFalse:[
  1030 		p setId:nil state:#dead
  1030                 p setId:nil state:#dead
  1031 	    ]
  1031             ]
  1032 	].
  1032         ].
  1033     ].
  1033     ].
  1034     scheduler setId:nil state:#dead.
  1034     scheduler setId:nil state:#dead.
  1035 
  1035 
  1036     "
  1036     "
  1037      now, start from scratch
  1037      now, start from scratch
  1038     "
  1038     "
  1039     KnownProcesses := nil.
  1039     KnownProcesses := nil.
  1040     self initialize.
  1040     self initialize.
  1041 
  1041 
  1042     processesToRestart do:[:p |
  1042     processesToRestart do:[:p |
  1043 	p imageRestart
  1043         p imageRestart
  1044     ]
  1044     ]
  1045 
  1045 
  1046     "Modified: / 7.6.1998 / 02:23:56 / cg"
  1046     "Modified: / 7.6.1998 / 02:23:56 / cg"
  1047 ! !
  1047 ! !
  1048 
  1048 
  1056     <context: #return>
  1056     <context: #return>
  1057 
  1057 
  1058     |index pri aProcess l|
  1058     |index pri aProcess l|
  1059 
  1059 
  1060     OperatingSystem interruptsBlocked ifFalse:[
  1060     OperatingSystem interruptsBlocked ifFalse:[
  1061 	MiniDebugger
  1061         MiniDebugger
  1062 	    enterWithMessage:'vmResumeInterrupt with no interruptsBlocked'
  1062             enterWithMessage:'vmResumeInterrupt with no interruptsBlocked'
  1063 	    mayProceed:true.
  1063             mayProceed:true.
  1064     ].
  1064     ].
  1065 
  1065 
  1066     index := KnownProcessIds identityIndexOf:id.
  1066     index := KnownProcessIds identityIndexOf:id.
  1067     index ~~ 0 ifTrue:[
  1067     index ~~ 0 ifTrue:[
  1068 	aProcess := KnownProcesses at:index.
  1068         aProcess := KnownProcesses at:index.
  1069 	pri := aProcess priority.
  1069         pri := aProcess priority.
  1070 	l := quiescentProcessLists at:pri.
  1070         l := quiescentProcessLists at:pri.
  1071 	l notNil ifTrue:[
  1071         l notNil ifTrue:[
  1072 	    (l includesIdentical:aProcess) ifTrue:[
  1072             (l includesIdentical:aProcess) ifTrue:[
  1073 		"/ aProcess is on a run queue.
  1073                 "/ aProcess is on a run queue.
  1074 		"/ CG: this situation may happen, if the wrapCall
  1074                 "/ CG: this situation may happen, if the wrapCall
  1075 		"/ finishes before the process was layed to sleep
  1075                 "/ finishes before the process was layed to sleep
  1076 		"/ (i.e. schedulerIRQ arrives before the threadSwitch was finished).
  1076                 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished).
  1077 		"/ In that case, simply resume it and everything is OK.
  1077                 "/ In that case, simply resume it and everything is OK.
  1078 		"/ If the process is state running, ignore.
  1078                 "/ If the process is state running, ignore.
  1079 
  1079 
  1080 		|state|
  1080                 |state|
  1081 
  1081 
  1082 		state := aProcess state.
  1082                 state := aProcess state.
  1083 		(state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[
  1083                 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[
  1084 		    aProcess state:#run.
  1084                     aProcess state:#run.
  1085 		].
  1085                 ].
  1086 		'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint.
  1086                 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint.
  1087 		aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR.
  1087                 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR.
  1088 		^ self
  1088                 ^ self
  1089 	    ]
  1089             ]
  1090 	] ifFalse:[
  1090         ] ifFalse:[
  1091 	    l := LinkedList new.
  1091             l := LinkedList new.
  1092 	    quiescentProcessLists at:pri put:l.
  1092             quiescentProcessLists at:pri put:l.
  1093 	].
  1093         ].
  1094 	l addLast:aProcess.
  1094         l addLast:aProcess.
  1095 	aProcess state:#run.
  1095         aProcess state:#run.
  1096     ] ifFalse:[
  1096     ] ifFalse:[
  1097 	'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint.
  1097         'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint.
  1098 	id infoPrintCR.
  1098         id infoPrintCR.
  1099     ]
  1099     ]
  1100 
  1100 
  1101     "Modified: / 28.9.1998 / 11:36:53 / cg"
  1101     "Modified: / 28.9.1998 / 11:36:53 / cg"
  1102 !
  1102 !
  1103 
  1103 
  1159      what to do now."
  1159      what to do now."
  1160 
  1160 
  1161     gotChildSignalInterrupt := true.
  1161     gotChildSignalInterrupt := true.
  1162     interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  1162     interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  1163     activeProcess ~~ scheduler ifTrue:[
  1163     activeProcess ~~ scheduler ifTrue:[
  1164 	interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  1164         interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  1165 	interruptedProcess := activeProcess.
  1165         interruptedProcess := activeProcess.
  1166 	self threadSwitch:scheduler
  1166         self threadSwitch:scheduler
  1167     ]
  1167     ]
  1168 
  1168 
  1169     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1169     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1170 !
  1170 !
  1171 
  1171 
  1178     blocking := OperatingSystem isChildProcessWaitBlocking.
  1178     blocking := OperatingSystem isChildProcessWaitBlocking.
  1179 
  1179 
  1180     "/ no interrupt processing, to avoid races with monitorPid
  1180     "/ no interrupt processing, to avoid races with monitorPid
  1181     wasBlocked := OperatingSystem blockInterrupts.
  1181     wasBlocked := OperatingSystem blockInterrupts.
  1182     [
  1182     [
  1183 	[
  1183         [
  1184 	    osProcessStatus := OperatingSystem childProcessWait:blocking pid:nil.
  1184             osProcessStatus := OperatingSystem childProcessWait:blocking pid:nil.
  1185 	    osProcessStatus notNil ifTrue:[
  1185             osProcessStatus notNil ifTrue:[
  1186 		|pid action|
  1186                 |pid action|
  1187 
  1187 
  1188 		pid := osProcessStatus pid.
  1188                 pid := osProcessStatus pid.
  1189 		osProcessStatus stillAlive ifTrue:[
  1189                 osProcessStatus stillAlive ifTrue:[
  1190 		    action := osChildExitActions at:pid ifAbsent:nil.
  1190                     action := osChildExitActions at:pid ifAbsent:nil.
  1191 		] ifFalse:[
  1191                 ] ifFalse:[
  1192 		    action := osChildExitActions removeKey:pid ifAbsent:nil.
  1192                     action := osChildExitActions removeKey:pid ifAbsent:nil.
  1193 		].
  1193                 ].
  1194 		action notNil ifTrue:[
  1194                 action notNil ifTrue:[
  1195 		    action value:osProcessStatus
  1195                     action value:osProcessStatus
  1196 		].
  1196                 ].
  1197 	    ].
  1197             ].
  1198 
  1198 
  1199 	    "/ if pollChildProcesses does block, poll only one status change.
  1199             "/ if pollChildProcesses does block, poll only one status change.
  1200 	    "/ we will get another SIGCHLD for other status changes.
  1200             "/ we will get another SIGCHLD for other status changes.
  1201 
  1201 
  1202 	    osProcessStatus notNil and:[blocking not]
  1202             osProcessStatus notNil and:[blocking not]
  1203 	] whileTrue.
  1203         ] whileTrue.
  1204 
  1204 
  1205 	"/ if there are no more waiters, disable SIGCHILD handler.
  1205         "/ if there are no more waiters, disable SIGCHILD handler.
  1206 	"/ this helps us with synchronous waiters (e.g. pclose),
  1206         "/ this helps us with synchronous waiters (e.g. pclose),
  1207 	"/ But they should block SIGCHLD anyway.
  1207         "/ But they should block SIGCHLD anyway.
  1208 
  1208 
  1209 	osChildExitActions isEmpty ifTrue:[
  1209         osChildExitActions isEmpty ifTrue:[
  1210 	    OperatingSystem disableChildSignalInterrupts.
  1210             OperatingSystem disableChildSignalInterrupts.
  1211 	].
  1211         ].
  1212     ] ensure:[
  1212     ] ensure:[
  1213 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1213         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1214     ]
  1214     ]
  1215 
  1215 
  1216     "Modified: 5.1.1996 / 16:56:11 / stefan"
  1216     "Modified: 5.1.1996 / 16:56:11 / stefan"
  1217     "Modified: 28.2.1996 / 21:36:31 / cg"
  1217     "Modified: 28.2.1996 / 21:36:31 / cg"
  1218     "Created: 12.4.1996 / 10:08:21 / stefan"
  1218     "Created: 12.4.1996 / 10:08:21 / stefan"
  1270 scheduleForInterrupt:aProcess
  1270 scheduleForInterrupt:aProcess
  1271     "make aProcess evaluate its pushed interrupt block(s)"
  1271     "make aProcess evaluate its pushed interrupt block(s)"
  1272 
  1272 
  1273     self scheduleInterruptActionsOf:aProcess.
  1273     self scheduleInterruptActionsOf:aProcess.
  1274     aProcess state ~~ #stopped ifTrue:[
  1274     aProcess state ~~ #stopped ifTrue:[
  1275 	"
  1275         "
  1276 	 make the process runnable
  1276          make the process runnable
  1277 	"
  1277         "
  1278 	self resume:aProcess
  1278         self resume:aProcess
  1279     ]
  1279     ]
  1280 
  1280 
  1281     "Modified: / 24.8.1998 / 18:31:32 / cg"
  1281     "Modified: / 24.8.1998 / 18:31:32 / cg"
  1282 !
  1282 !
  1283 
  1283 
  1488 
  1488 
  1489     wasBlocked := OperatingSystem blockInterrupts.
  1489     wasBlocked := OperatingSystem blockInterrupts.
  1490     index := 1.
  1490     index := 1.
  1491     sz := KnownProcessIds size.
  1491     sz := KnownProcessIds size.
  1492     [index <= sz] whileTrue:[
  1492     [index <= sz] whileTrue:[
  1493 	(KnownProcesses at:index) isNil ifTrue:[
  1493         (KnownProcesses at:index) isNil ifTrue:[
  1494 	    oldId := KnownProcessIds at:index.
  1494             oldId := KnownProcessIds at:index.
  1495 	    oldId notNil ifTrue:[
  1495             oldId notNil ifTrue:[
  1496 		self class threadDestroy:oldId.
  1496                 self class threadDestroy:oldId.
  1497 	    ].
  1497             ].
  1498 	    KnownProcesses at:index put:aProcess.
  1498             KnownProcesses at:index put:aProcess.
  1499 	    KnownProcessIds at:index put:aProcess id.
  1499             KnownProcessIds at:index put:aProcess id.
  1500 	    wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1500             wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1501 	    ^ self
  1501             ^ self
  1502 	].
  1502         ].
  1503 	index := index + 1
  1503         index := index + 1
  1504     ].
  1504     ].
  1505 
  1505 
  1506     KnownProcessIds grow:index.
  1506     KnownProcessIds grow:index.
  1507     KnownProcessIds at:index put:aProcess id.
  1507     KnownProcessIds at:index put:aProcess id.
  1508 
  1508 
  1509     oldSize := KnownProcesses size.
  1509     oldSize := KnownProcesses size.
  1510     (index > oldSize) ifTrue:[
  1510     (index > oldSize) ifTrue:[
  1511 	newShadow := WeakArray new:(oldSize * 2).
  1511         newShadow := WeakArray new:(oldSize * 2).
  1512 	newShadow addDependent:self class.
  1512         newShadow addDependent:self class.
  1513 	newShadow replaceFrom:1 with:KnownProcesses.
  1513         newShadow replaceFrom:1 with:KnownProcesses.
  1514 	KnownProcesses := newShadow
  1514         KnownProcesses := newShadow
  1515     ].
  1515     ].
  1516     KnownProcesses at:index put:aProcess.
  1516     KnownProcesses at:index put:aProcess.
  1517     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1517     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1518 
  1518 
  1519     "Modified: 7.1.1997 / 16:48:39 / stefan"
  1519     "Modified: 7.1.1997 / 16:48:39 / stefan"
  1525     |index wasBlocked|
  1525     |index wasBlocked|
  1526 
  1526 
  1527     wasBlocked := OperatingSystem blockInterrupts.
  1527     wasBlocked := OperatingSystem blockInterrupts.
  1528     index := KnownProcesses identityIndexOf:aProcess.
  1528     index := KnownProcesses identityIndexOf:aProcess.
  1529     index ~~ 0 ifTrue:[
  1529     index ~~ 0 ifTrue:[
  1530 	KnownProcessIds at:index put:nil.
  1530         KnownProcessIds at:index put:nil.
  1531 	KnownProcesses at:index put:nil.
  1531         KnownProcesses at:index put:nil.
  1532     ].
  1532     ].
  1533     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1533     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1534 ! !
  1534 ! !
  1535 
  1535 
  1536 !ProcessorScheduler methodsFor:'process creation'!
  1536 !ProcessorScheduler methodsFor:'process creation'!
  1551 
  1551 
  1552 newProcessFor:aProcess withId:idWant
  1552 newProcessFor:aProcess withId:idWant
  1553     "private entry for Process restart - do not use in your program"
  1553     "private entry for Process restart - do not use in your program"
  1554 
  1554 
  1555     idWant isNil ifTrue:[
  1555     idWant isNil ifTrue:[
  1556 	self newProcessFor:aProcess.
  1556         self newProcessFor:aProcess.
  1557 	^ true.
  1557         ^ true.
  1558     ].
  1558     ].
  1559 
  1559 
  1560     (self class threadCreate:aProcess withId:idWant) ~~ idWant ifTrue:[
  1560     (self class threadCreate:aProcess withId:idWant) ~~ idWant ifTrue:[
  1561 	^ false
  1561         ^ false
  1562     ].
  1562     ].
  1563 
  1563 
  1564     aProcess state:#light.   "meaning: has no stack yet"
  1564     aProcess state:#light.   "meaning: has no stack yet"
  1565     self remember:aProcess.
  1565     self remember:aProcess.
  1566     ^ true
  1566     ^ true
  1676     prio := HighestPriority.
  1676     prio := HighestPriority.
  1677     wasBlocked := OperatingSystem blockInterrupts.
  1677     wasBlocked := OperatingSystem blockInterrupts.
  1678 
  1678 
  1679     listArray := quiescentProcessLists.
  1679     listArray := quiescentProcessLists.
  1680     [prio >= 1] whileTrue:[
  1680     [prio >= 1] whileTrue:[
  1681 	l := listArray at:prio.
  1681         l := listArray at:prio.
  1682 	l notNil ifTrue:[
  1682         l notNil ifTrue:[
  1683 	    l notEmpty ifTrue:[
  1683             l notEmpty ifTrue:[
  1684 		p := l firstLink.
  1684                 p := l firstLink.
  1685 		"
  1685                 "
  1686 		 if it got corrupted somehow ...
  1686                  if it got corrupted somehow ...
  1687 		"
  1687                 "
  1688 		p isDead ifTrue:[
  1688                 p isDead ifTrue:[
  1689 		    'Processor [warning]: dead process removed' errorPrintCR.
  1689                     'Processor [warning]: dead process removed' errorPrintCR.
  1690 		    l removeFirst.
  1690                     l removeFirst.
  1691 		    p := nil.
  1691                     p := nil.
  1692 		].
  1692                 ].
  1693 		wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1693                 wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1694 		^ p
  1694                 ^ p
  1695 	    ]
  1695             ]
  1696 	].
  1696         ].
  1697 	prio := prio - 1
  1697         prio := prio - 1
  1698     ].
  1698     ].
  1699     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1699     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1700     ^ nil
  1700     ^ nil
  1701 
  1701 
  1702     "Modified: 12.2.1997 / 12:41:49 / cg"
  1702     "Modified: 12.2.1997 / 12:41:49 / cg"
  1742 
  1742 
  1743     wasBlocked := OperatingSystem blockInterrupts.
  1743     wasBlocked := OperatingSystem blockInterrupts.
  1744 
  1744 
  1745     slot := KnownProcessIds indexOf:anInteger.
  1745     slot := KnownProcessIds indexOf:anInteger.
  1746     slot ~~ 0 ifTrue:[
  1746     slot ~~ 0 ifTrue:[
  1747 	process := KnownProcesses at:slot ifAbsent:[].
  1747         process := KnownProcesses at:slot ifAbsent:[].
  1748     ].
  1748     ].
  1749 
  1749 
  1750     wasBlocked ifFalse:[
  1750     wasBlocked ifFalse:[
  1751 	OperatingSystem unblockInterrupts.
  1751         OperatingSystem unblockInterrupts.
  1752     ].
  1752     ].
  1753 
  1753 
  1754     "Take care, the process may already have been collected"
  1754     "Take care, the process may already have been collected"
  1755     process == 0 ifTrue:[
  1755     process == 0 ifTrue:[
  1756 	^ nil.
  1756         ^ nil.
  1757     ].
  1757     ].
  1758     ^ process.
  1758     ^ process.
  1759 
  1759 
  1760     "
  1760     "
  1761 	Processor processWithId:4
  1761         Processor processWithId:4
  1762 	Processor processWithId:4711
  1762         Processor processWithId:4711
  1763     "
  1763     "
  1764 !
  1764 !
  1765 
  1765 
  1766 processesWithGroupId:anInteger
  1766 processesWithGroupId:anInteger
  1767     "answer a collection of processes with processGroupId, anInteger"
  1767     "answer a collection of processes with processGroupId, anInteger"
  1867     "/ the interrupt block should think it was called right
  1867     "/ the interrupt block should think it was called right
  1868     "/ from the originally interrupted context
  1868     "/ from the originally interrupted context
  1869 
  1869 
  1870     s := thisContext sender.
  1870     s := thisContext sender.
  1871     s selector == #threadSwitchFrom:to:id:singleStep: ifTrue:[
  1871     s selector == #threadSwitchFrom:to:id:singleStep: ifTrue:[
  1872 	s := s sender.
  1872         s := s sender.
  1873 	s selector == #threadSwitch: ifTrue:[
  1873         s selector == #threadSwitch: ifTrue:[
  1874 	    s := s sender.
  1874             s := s sender.
  1875 	    s selector == #timerInterrupt ifTrue:[
  1875             s selector == #timerInterrupt ifTrue:[
  1876 		s := s sender
  1876                 s := s sender
  1877 	    ]
  1877             ]
  1878 	]
  1878         ]
  1879     ].
  1879     ].
  1880 
  1880 
  1881     "/ the returned value here has a subtle effect:
  1881     "/ the returned value here has a subtle effect:
  1882     "/ if false, the interrupt is assumed to be not taken,
  1882     "/ if false, the interrupt is assumed to be not taken,
  1883     "/ and will be redelivered.
  1883     "/ and will be redelivered.
  2179     |l sz wasBlocked|
  2179     |l sz wasBlocked|
  2180 
  2180 
  2181     wasBlocked := OperatingSystem blockInterrupts.
  2181     wasBlocked := OperatingSystem blockInterrupts.
  2182 
  2182 
  2183     activeProcess == scheduler ifTrue:[
  2183     activeProcess == scheduler ifTrue:[
  2184 	'Processor [warning]: scheduler tries to yield' errorPrintCR.
  2184         'Processor [warning]: scheduler tries to yield' errorPrintCR.
  2185 	^ self
  2185         ^ self
  2186     ].
  2186     ].
  2187 
  2187 
  2188     "
  2188     "
  2189      debugging consistency check - will be removed later
  2189      debugging consistency check - will be removed later
  2190     "
  2190     "
  2191     activeProcess priority ~~ currentPriority ifTrue:[
  2191     activeProcess priority ~~ currentPriority ifTrue:[
  2192 	'Processor [warning]: process changed its priority' errorPrintCR.
  2192         'Processor [warning]: process changed its priority' errorPrintCR.
  2193 	currentPriority := activeProcess priority.
  2193         currentPriority := activeProcess priority.
  2194     ].
  2194     ].
  2195 
  2195 
  2196     l := quiescentProcessLists at:currentPriority.
  2196     l := quiescentProcessLists at:currentPriority.
  2197     sz := l size.
  2197     sz := l size.
  2198 
  2198 
  2199     "
  2199     "
  2200      debugging consistency checks - will be removed later
  2200      debugging consistency checks - will be removed later
  2201     "
  2201     "
  2202     sz == 0 ifTrue:[
  2202     sz == 0 ifTrue:[
  2203 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2203         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2204 	'Processor [warning]: empty runnable list' errorPrintCR.
  2204         'Processor [warning]: empty runnable list' errorPrintCR.
  2205 	^ self
  2205         ^ self
  2206     ].
  2206     ].
  2207 
  2207 
  2208     "
  2208     "
  2209      check if the running process is not the only one
  2209      check if the running process is not the only one
  2210     "
  2210     "
  2211     sz ~~ 1 ifTrue:[
  2211     sz ~~ 1 ifTrue:[
  2212 	"
  2212         "
  2213 	 bring running process to the end
  2213          bring running process to the end
  2214 	"
  2214         "
  2215 	l removeFirst.
  2215         l removeFirst.
  2216 	l addLast:activeProcess.
  2216         l addLast:activeProcess.
  2217 
  2217 
  2218 	"
  2218         "
  2219 	 and switch to first in the list
  2219          and switch to first in the list
  2220 	"
  2220         "
  2221 	self threadSwitch:(l firstLink).
  2221         self threadSwitch:(l firstLink).
  2222     ].
  2222     ].
  2223     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2223     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2224 
  2224 
  2225     "Modified: / 02-08-2010 / 13:36:25 / cg"
  2225     "Modified: / 02-08-2010 / 13:36:25 / cg"
  2226 ! !
  2226 ! !
  2231     "recompute dynamic priorities."
  2231     "recompute dynamic priorities."
  2232 
  2232 
  2233     |processesToDecrease processesToIncrease|
  2233     |processesToDecrease processesToIncrease|
  2234 
  2234 
  2235     scheduledProcesses notNil ifTrue:[
  2235     scheduledProcesses notNil ifTrue:[
  2236 	"/ this is written a bit cryptic - to avoid creation
  2236         "/ this is written a bit cryptic - to avoid creation
  2237 	"/ of garbage objects (Id'sets) if possible.
  2237         "/ of garbage objects (Id'sets) if possible.
  2238 	"/ since this runs 50 times a second and most of the
  2238         "/ since this runs 50 times a second and most of the
  2239 	"/ time, no rescheduling is req'd
  2239         "/ time, no rescheduling is req'd
  2240 
  2240 
  2241 	scheduledProcesses do:[:aProcess |
  2241         scheduledProcesses do:[:aProcess |
  2242 	    |range|
  2242             |range|
  2243 
  2243 
  2244 	    "/ decrease priority of processes that did run
  2244             "/ decrease priority of processes that did run
  2245 	    (range := aProcess priorityRange) notNil ifTrue:[
  2245             (range := aProcess priorityRange) notNil ifTrue:[
  2246 		aProcess priority > range start ifTrue:[
  2246                 aProcess priority > range start ifTrue:[
  2247 		    processesToDecrease isNil ifTrue:[
  2247                     processesToDecrease isNil ifTrue:[
  2248 			processesToDecrease := IdentitySet new.
  2248                         processesToDecrease := IdentitySet new.
  2249 		    ].
  2249                     ].
  2250 		    processesToDecrease add:aProcess.
  2250                     processesToDecrease add:aProcess.
  2251 		]
  2251                 ]
  2252 	    ]
  2252             ]
  2253 	].
  2253         ].
  2254 
  2254 
  2255 	processesToDecrease notNil ifTrue:[
  2255         processesToDecrease notNil ifTrue:[
  2256 	    processesToDecrease do:[:aProcess |
  2256             processesToDecrease do:[:aProcess |
  2257 		|newPri|
  2257                 |newPri|
  2258 
  2258 
  2259 		"/ newPri := aProcess priority - 1.
  2259                 "/ newPri := aProcess priority - 1.
  2260 		newPri := aProcess priorityRange start.
  2260                 newPri := aProcess priorityRange start.
  2261 		self changePriority:newPri for:aProcess.
  2261                 self changePriority:newPri for:aProcess.
  2262 	    ].
  2262             ].
  2263 	].
  2263         ].
  2264 
  2264 
  2265 	"/ and increase all prios of those that did not run, but are runnable
  2265         "/ and increase all prios of those that did not run, but are runnable
  2266 
  2266 
  2267 	TimeSlicingPriorityLimit to:1 by:-1 do:[:i |
  2267         TimeSlicingPriorityLimit to:1 by:-1 do:[:i |
  2268 	    |list|
  2268             |list|
  2269 
  2269 
  2270 	    (list := quiescentProcessLists at:i) size > 0 ifTrue:[
  2270             (list := quiescentProcessLists at:i) size > 0 ifTrue:[
  2271 		list linksDo:[:aProcess |
  2271                 list linksDo:[:aProcess |
  2272 		    |range prio|
  2272                     |range prio|
  2273 
  2273 
  2274 		    (range := aProcess priorityRange) notNil ifTrue:[
  2274                     (range := aProcess priorityRange) notNil ifTrue:[
  2275 			(processesToDecrease isNil
  2275                         (processesToDecrease isNil
  2276 			or:[(processesToDecrease includes:aProcess) not]) ifTrue:[
  2276                         or:[(processesToDecrease includes:aProcess) not]) ifTrue:[
  2277 			    aProcess priority < range stop ifTrue:[
  2277                             aProcess priority < range stop ifTrue:[
  2278 				processesToIncrease isNil ifTrue:[
  2278                                 processesToIncrease isNil ifTrue:[
  2279 				    processesToIncrease := OrderedCollection new.
  2279                                     processesToIncrease := OrderedCollection new.
  2280 				].
  2280                                 ].
  2281 				processesToIncrease add:aProcess
  2281                                 processesToIncrease add:aProcess
  2282 			    ]
  2282                             ]
  2283 			]
  2283                         ]
  2284 		    ]
  2284                     ]
  2285 		]
  2285                 ]
  2286 	    ]
  2286             ]
  2287 	].
  2287         ].
  2288 	processesToIncrease notNil ifTrue:[
  2288         processesToIncrease notNil ifTrue:[
  2289 	    processesToIncrease do:[:aProcess |
  2289             processesToIncrease do:[:aProcess |
  2290 		self changePriority:(aProcess priority + 1) for:aProcess.
  2290                 self changePriority:(aProcess priority + 1) for:aProcess.
  2291 	    ].
  2291             ].
  2292 	].
  2292         ].
  2293     ].
  2293     ].
  2294 
  2294 
  2295     "Modified: / 30-07-2013 / 19:33:14 / cg"
  2295     "Modified: / 30-07-2013 / 19:33:14 / cg"
  2296 !
  2296 !
  2297 
  2297 
  2338     timeSliceProcess notNil ifTrue: [^ self].
  2338     timeSliceProcess notNil ifTrue: [^ self].
  2339 
  2339 
  2340     timeSliceNeededSemaphore := Semaphore new name:'timeSlice needed'.
  2340     timeSliceNeededSemaphore := Semaphore new name:'timeSlice needed'.
  2341 
  2341 
  2342     timeSliceProcess := [
  2342     timeSliceProcess := [
  2343 	[
  2343         [
  2344 	    self timeSlicingLoop.
  2344             self timeSlicingLoop.
  2345 	] ifCurtailed:[
  2345         ] ifCurtailed:[
  2346 	    timeSliceProcess := nil.
  2346             timeSliceProcess := nil.
  2347 	    'Processor [info]: timeslicer finished' infoPrintCR.
  2347             'Processor [info]: timeslicer finished' infoPrintCR.
  2348 	]
  2348         ]
  2349     ] newProcess.
  2349     ] newProcess.
  2350     timeSliceProcess
  2350     timeSliceProcess
  2351 	priority:HighestPriority;
  2351         priority:HighestPriority;
  2352 	name:'time slicer';
  2352         name:'time slicer';
  2353 	restartable:true;
  2353         restartable:true;
  2354 	beSystemProcess;
  2354         beSystemProcess;
  2355 	resume.
  2355         resume.
  2356 
  2356 
  2357     "
  2357     "
  2358      Processor stopTimeSlicing.
  2358      Processor stopTimeSlicing.
  2359      Processor startTimeSlicing.
  2359      Processor startTimeSlicing.
  2360     "
  2360     "
  2365 
  2365 
  2366 stopTimeSlicing
  2366 stopTimeSlicing
  2367     "stop preemptive scheduling (timeSlicing)"
  2367     "stop preemptive scheduling (timeSlicing)"
  2368 
  2368 
  2369     timeSliceProcess notNil ifTrue: [
  2369     timeSliceProcess notNil ifTrue: [
  2370 	timeSliceProcess terminate.
  2370         timeSliceProcess terminate.
  2371 	timeSliceProcess := nil.
  2371         timeSliceProcess := nil.
  2372 	scheduledProcesses := nil.
  2372         scheduledProcesses := nil.
  2373 	timeSliceNeededSemaphore := nil.
  2373         timeSliceNeededSemaphore := nil.
  2374     ]
  2374     ]
  2375 
  2375 
  2376     "
  2376     "
  2377      Processor stopTimeSlicing
  2377      Processor stopTimeSlicing
  2378     "
  2378     "
  2443     |idx "{ Class: SmallInteger }"
  2443     |idx "{ Class: SmallInteger }"
  2444      wasBlocked sema semaCollection|
  2444      wasBlocked sema semaCollection|
  2445 
  2445 
  2446     wasBlocked := OperatingSystem blockInterrupts.
  2446     wasBlocked := OperatingSystem blockInterrupts.
  2447     useIOInterrupts ifTrue:[
  2447     useIOInterrupts ifTrue:[
  2448 	OperatingSystem disableIOInterruptsOn:aFileDescriptor.
  2448         OperatingSystem disableIOInterruptsOn:aFileDescriptor.
  2449     ].
  2449     ].
  2450 
  2450 
  2451     idx := readFdArray indexOf:aFileDescriptor startingAt:1.
  2451     idx := readFdArray indexOf:aFileDescriptor startingAt:1.
  2452     [idx ~~ 0] whileTrue:[
  2452     [idx ~~ 0] whileTrue:[
  2453 	readFdArray at:idx put:nil.
  2453         readFdArray at:idx put:nil.
  2454 	readCheckArray at:idx put:nil.
  2454         readCheckArray at:idx put:nil.
  2455 	(sema := readSemaphoreArray at:idx) notNil ifTrue:[
  2455         (sema := readSemaphoreArray at:idx) notNil ifTrue:[
  2456 	    readSemaphoreArray at:idx put:nil.
  2456             readSemaphoreArray at:idx put:nil.
  2457 	    semaCollection isNil ifTrue:[semaCollection := Set new].
  2457             semaCollection isNil ifTrue:[semaCollection := Set new].
  2458 	    semaCollection add:sema.
  2458             semaCollection add:sema.
  2459 	].
  2459         ].
  2460 	idx := readFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2460         idx := readFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2461     ].
  2461     ].
  2462     idx := writeFdArray indexOf:aFileDescriptor startingAt:1.
  2462     idx := writeFdArray indexOf:aFileDescriptor startingAt:1.
  2463     [idx ~~ 0] whileTrue:[
  2463     [idx ~~ 0] whileTrue:[
  2464 	writeFdArray at:idx put:nil.
  2464         writeFdArray at:idx put:nil.
  2465 	writeCheckArray at:idx put:nil.
  2465         writeCheckArray at:idx put:nil.
  2466 	(sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  2466         (sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  2467 	    writeSemaphoreArray at:idx put:nil.
  2467             writeSemaphoreArray at:idx put:nil.
  2468 	    semaCollection isNil ifTrue:[semaCollection := Set new].
  2468             semaCollection isNil ifTrue:[semaCollection := Set new].
  2469 	    semaCollection add:sema.
  2469             semaCollection add:sema.
  2470 	].
  2470         ].
  2471 	idx := writeFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2471         idx := writeFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2472     ].
  2472     ].
  2473     idx := exceptFdArray indexOf:aFileDescriptor startingAt:1.
  2473     idx := exceptFdArray indexOf:aFileDescriptor startingAt:1.
  2474     [idx ~~ 0] whileTrue:[
  2474     [idx ~~ 0] whileTrue:[
  2475 	exceptFdArray at:idx put:nil.
  2475         exceptFdArray at:idx put:nil.
  2476 	(sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  2476         (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  2477 	    exceptSemaphoreArray at:idx put:nil.
  2477             exceptSemaphoreArray at:idx put:nil.
  2478 	    semaCollection isNil ifTrue:[semaCollection := Set new].
  2478             semaCollection isNil ifTrue:[semaCollection := Set new].
  2479 	    semaCollection add:sema.
  2479             semaCollection add:sema.
  2480 	].
  2480         ].
  2481 	idx := exceptFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2481         idx := exceptFdArray indexOf:aFileDescriptor startingAt:idx+1.
  2482     ].
  2482     ].
  2483 
  2483 
  2484     semaCollection isNil ifTrue:[
  2484     semaCollection isNil ifTrue:[
  2485 	semaCollection := #().
  2485         semaCollection := #().
  2486     ] ifFalse:[
  2486     ] ifFalse:[
  2487 	doSignal ifTrue:[
  2487         doSignal ifTrue:[
  2488 	    semaCollection do:[:eachSema|
  2488             semaCollection do:[:eachSema|
  2489 		eachSema signalForAll.
  2489                 eachSema signalForAll.
  2490 		semaCollection := #().
  2490                 semaCollection := #().
  2491 	    ].
  2491             ].
  2492 	].
  2492         ].
  2493     ].
  2493     ].
  2494     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2494     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2495     ^ semaCollection
  2495     ^ semaCollection
  2496 !
  2496 !
  2497 
  2497 
  2503 
  2503 
  2504     wasBlocked := OperatingSystem blockInterrupts.
  2504     wasBlocked := OperatingSystem blockInterrupts.
  2505     idx := 0.
  2505     idx := 0.
  2506     [idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2506     [idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2507      idx ~~ 0] whileTrue:[
  2507      idx ~~ 0] whileTrue:[
  2508 	useIOInterrupts ifTrue:[
  2508         useIOInterrupts ifTrue:[
  2509 	    fd := readFdArray at:idx.
  2509             fd := readFdArray at:idx.
  2510 	    fd notNil ifTrue:[
  2510             fd notNil ifTrue:[
  2511 		OperatingSystem disableIOInterruptsOn:fd
  2511                 OperatingSystem disableIOInterruptsOn:fd
  2512 	    ].
  2512             ].
  2513 	].
  2513         ].
  2514 	readFdArray at:idx put:nil.
  2514         readFdArray at:idx put:nil.
  2515 	readSemaphoreArray at:idx put:nil.
  2515         readSemaphoreArray at:idx put:nil.
  2516 	readCheckArray at:idx put:nil.
  2516         readCheckArray at:idx put:nil.
  2517     ].
  2517     ].
  2518     idx := 0.
  2518     idx := 0.
  2519     [idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2519     [idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2520      idx ~~ 0] whileTrue:[
  2520      idx ~~ 0] whileTrue:[
  2521 	useIOInterrupts ifTrue:[
  2521         useIOInterrupts ifTrue:[
  2522 	    fd := writeFdArray at:idx.
  2522             fd := writeFdArray at:idx.
  2523 	    fd notNil ifTrue:[
  2523             fd notNil ifTrue:[
  2524 		OperatingSystem disableIOInterruptsOn:fd
  2524                 OperatingSystem disableIOInterruptsOn:fd
  2525 	    ].
  2525             ].
  2526 	].
  2526         ].
  2527 	writeFdArray at:idx put:nil.
  2527         writeFdArray at:idx put:nil.
  2528 	writeSemaphoreArray at:idx put:nil.
  2528         writeSemaphoreArray at:idx put:nil.
  2529 	writeCheckArray at:idx put:nil.
  2529         writeCheckArray at:idx put:nil.
  2530     ].
  2530     ].
  2531     idx := 0.
  2531     idx := 0.
  2532     [idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2532     [idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2533      idx ~~ 0] whileTrue:[
  2533      idx ~~ 0] whileTrue:[
  2534 	exceptFdArray at:idx put:nil.
  2534         exceptFdArray at:idx put:nil.
  2535 	exceptSemaphoreArray at:idx put:nil.
  2535         exceptSemaphoreArray at:idx put:nil.
  2536     ].
  2536     ].
  2537     self removeTimeoutForSemaphore:aSemaphore.
  2537     self removeTimeoutForSemaphore:aSemaphore.
  2538     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2538     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2539 
  2539 
  2540     "Modified: 4.8.1997 / 15:19:33 / cg"
  2540     "Modified: 4.8.1997 / 15:19:33 / cg"
  2590      wasBlocked|
  2590      wasBlocked|
  2591 
  2591 
  2592     wasBlocked := OperatingSystem blockInterrupts.
  2592     wasBlocked := OperatingSystem blockInterrupts.
  2593     index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2593     index := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2594     index ~~ 0 ifTrue:[
  2594     index ~~ 0 ifTrue:[
  2595 	timeoutArray at:index put:aMillisecondTime
  2595         timeoutArray at:index put:aMillisecondTime
  2596     ] ifFalse:[
  2596     ] ifFalse:[
  2597 	index := timeoutArray identityIndexOf:nil startingAt:1.
  2597         index := timeoutArray identityIndexOf:nil startingAt:1.
  2598 	index ~~ 0 ifTrue:[
  2598         index ~~ 0 ifTrue:[
  2599 	    timeoutSemaphoreArray at:index put:aSemaphore.
  2599             timeoutSemaphoreArray at:index put:aSemaphore.
  2600 	    timeoutArray at:index put:aMillisecondTime.
  2600             timeoutArray at:index put:aMillisecondTime.
  2601 	    timeoutActionArray at:index put:nil.
  2601             timeoutActionArray at:index put:nil.
  2602 	    timeoutProcessArray at:index put:nil
  2602             timeoutProcessArray at:index put:nil
  2603 	] ifFalse:[
  2603         ] ifFalse:[
  2604 	    timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore.
  2604             timeoutSemaphoreArray := timeoutSemaphoreArray copyWith:aSemaphore.
  2605 	    timeoutArray := timeoutArray copyWith:aMillisecondTime.
  2605             timeoutArray := timeoutArray copyWith:aMillisecondTime.
  2606 	    timeoutActionArray := timeoutActionArray copyWith:nil.
  2606             timeoutActionArray := timeoutActionArray copyWith:nil.
  2607 	    timeoutProcessArray := timeoutProcessArray copyWith:nil
  2607             timeoutProcessArray := timeoutProcessArray copyWith:nil
  2608 	].
  2608         ].
  2609     ].
  2609     ].
  2610 
  2610 
  2611     anyTimeouts := true.
  2611     anyTimeouts := true.
  2612     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2612     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2613 !
  2613 !
  2628 
  2628 
  2629     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2629     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2630      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2630      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2631 
  2631 
  2632     aFileDescriptor isNil ifTrue:[
  2632     aFileDescriptor isNil ifTrue:[
  2633 	idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2633         idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2634 	idx == 0 ifTrue:[
  2634         idx == 0 ifTrue:[
  2635 	    "aSemaphore is not registered yet, have to create a new slot"
  2635             "aSemaphore is not registered yet, have to create a new slot"
  2636 	    exceptFdArray := exceptFdArray copyWith:nil.
  2636             exceptFdArray := exceptFdArray copyWith:nil.
  2637 	    exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2637             exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2638 	] ifFalse:[
  2638         ] ifFalse:[
  2639 	    slot := exceptSemaphoreArray at:idx.
  2639             slot := exceptSemaphoreArray at:idx.
  2640 	    slot isNil ifTrue:[
  2640             slot isNil ifTrue:[
  2641 		exceptSemaphoreArray at:idx put:aSemaphore.
  2641                 exceptSemaphoreArray at:idx put:aSemaphore.
  2642 	    ]
  2642             ]
  2643 	]
  2643         ]
  2644     ] ifFalse:[
  2644     ] ifFalse:[
  2645 	idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil.
  2645         idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil.
  2646 	idx == 0 ifTrue:[
  2646         idx == 0 ifTrue:[
  2647 	    "aFileDescriptor is not registered yet, have to create a new slot"
  2647             "aFileDescriptor is not registered yet, have to create a new slot"
  2648 	    exceptFdArray := exceptFdArray copyWith:aFileDescriptor.
  2648             exceptFdArray := exceptFdArray copyWith:aFileDescriptor.
  2649 	    exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2649             exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2650 	] ifFalse:[
  2650         ] ifFalse:[
  2651 	    slot := exceptFdArray at:idx.
  2651             slot := exceptFdArray at:idx.
  2652 	    slot isNil ifTrue:[
  2652             slot isNil ifTrue:[
  2653 		exceptFdArray at:idx put:aFileDescriptor.
  2653                 exceptFdArray at:idx put:aFileDescriptor.
  2654 		exceptSemaphoreArray at:idx put:aSemaphore.
  2654                 exceptSemaphoreArray at:idx put:aSemaphore.
  2655 	    ].
  2655             ].
  2656 	].
  2656         ].
  2657 "/        (useIOInterrupts and:[slot isNil]) ifTrue:[
  2657 "/        (useIOInterrupts and:[slot isNil]) ifTrue:[
  2658 "/            OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2658 "/            OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2659 "/        ].
  2659 "/        ].
  2660     ].
  2660     ].
  2661     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2661     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2688 
  2688 
  2689     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2689     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2690      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2690      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2691 
  2691 
  2692     aFileDescriptor isNil ifTrue:[
  2692     aFileDescriptor isNil ifTrue:[
  2693 	idx := readSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2693         idx := readSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2694 	idx == 0 ifTrue:[
  2694         idx == 0 ifTrue:[
  2695 	    "aSemaphore is not registered yet, have to create a new slot"
  2695             "aSemaphore is not registered yet, have to create a new slot"
  2696 	    readFdArray := readFdArray copyWith:nil.
  2696             readFdArray := readFdArray copyWith:nil.
  2697 	    readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore.
  2697             readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore.
  2698 	    readCheckArray := readCheckArray copyWith:aBlock.
  2698             readCheckArray := readCheckArray copyWith:aBlock.
  2699 	] ifFalse:[
  2699         ] ifFalse:[
  2700 	    slot := readSemaphoreArray at:idx.
  2700             slot := readSemaphoreArray at:idx.
  2701 	    slot isNil ifTrue:[
  2701             slot isNil ifTrue:[
  2702 		readSemaphoreArray at:idx put:aSemaphore.
  2702                 readSemaphoreArray at:idx put:aSemaphore.
  2703 		readCheckArray at:idx put:aBlock
  2703                 readCheckArray at:idx put:aBlock
  2704 	    ] ifFalse:[
  2704             ] ifFalse:[
  2705 		"/ someone has already registered aSemaphore.
  2705                 "/ someone has already registered aSemaphore.
  2706 		"/ Check if it is the block changes...
  2706                 "/ Check if it is the block changes...
  2707 		(readCheckArray at:idx) notNil ifTrue:[
  2707                 (readCheckArray at:idx) notNil ifTrue:[
  2708 		    (readCheckArray at:idx) ~~ aBlock ifTrue:[
  2708                     (readCheckArray at:idx) ~~ aBlock ifTrue:[
  2709 			'Processor [info]: checkblock changed for read-check' infoPrintCR.
  2709                         'Processor [info]: checkblock changed for read-check' infoPrintCR.
  2710 			readCheckArray at:idx put:aBlock.
  2710                         readCheckArray at:idx put:aBlock.
  2711 		    ].
  2711                     ].
  2712 		].
  2712                 ].
  2713 	    ].
  2713             ].
  2714 	]
  2714         ]
  2715     ] ifFalse:[
  2715     ] ifFalse:[
  2716 	idx := readFdArray identityIndexOf:aFileDescriptor or:nil.
  2716         idx := readFdArray identityIndexOf:aFileDescriptor or:nil.
  2717 	idx == 0 ifTrue:[
  2717         idx == 0 ifTrue:[
  2718 	    "aFileDescriptor is not registered yet, have to create a new slot"
  2718             "aFileDescriptor is not registered yet, have to create a new slot"
  2719 	    readFdArray := readFdArray copyWith:aFileDescriptor.
  2719             readFdArray := readFdArray copyWith:aFileDescriptor.
  2720 	    readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore.
  2720             readSemaphoreArray := readSemaphoreArray copyWith:aSemaphore.
  2721 	    readCheckArray := readCheckArray copyWith:aBlock.
  2721             readCheckArray := readCheckArray copyWith:aBlock.
  2722 	] ifFalse:[
  2722         ] ifFalse:[
  2723 	    slot := readFdArray at:idx.
  2723             slot := readFdArray at:idx.
  2724 	    slot isNil ifTrue:[
  2724             slot isNil ifTrue:[
  2725 		readFdArray at:idx put:aFileDescriptor.
  2725                 readFdArray at:idx put:aFileDescriptor.
  2726 		readSemaphoreArray at:idx put:aSemaphore.
  2726                 readSemaphoreArray at:idx put:aSemaphore.
  2727 		readCheckArray at:idx put:aBlock
  2727                 readCheckArray at:idx put:aBlock
  2728 	    ] ifFalse:[
  2728             ] ifFalse:[
  2729 		"/ someone has already registered aFileDescriptor.
  2729                 "/ someone has already registered aFileDescriptor.
  2730 		"/ Check if it is the semaphore or block changes...
  2730                 "/ Check if it is the semaphore or block changes...
  2731 		(readSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[
  2731                 (readSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[
  2732 		    'Processor [info]: sema changed for read-check' infoPrintCR.
  2732                     'Processor [info]: sema changed for read-check' infoPrintCR.
  2733 		    readSemaphoreArray at:idx put:aSemaphore.
  2733                     readSemaphoreArray at:idx put:aSemaphore.
  2734 		].
  2734                 ].
  2735 		(readCheckArray at:idx) ~~ aBlock ifTrue:[
  2735                 (readCheckArray at:idx) ~~ aBlock ifTrue:[
  2736 		    'Processor [info]: checkblock changed for read-check' infoPrintCR.
  2736                     'Processor [info]: checkblock changed for read-check' infoPrintCR.
  2737 		    readCheckArray at:idx put:aBlock.
  2737                     readCheckArray at:idx put:aBlock.
  2738 		].
  2738                 ].
  2739 	    ].
  2739             ].
  2740 	].
  2740         ].
  2741 	(useIOInterrupts and:[slot isNil]) ifTrue:[
  2741         (useIOInterrupts and:[slot isNil]) ifTrue:[
  2742 	    OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2742             OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2743 	].
  2743         ].
  2744     ].
  2744     ].
  2745     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2745     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2746 
  2746 
  2747     "Modified: 4.8.1997 / 15:20:45 / cg"
  2747     "Modified: 4.8.1997 / 15:20:45 / cg"
  2748 !
  2748 !
  2789 
  2789 
  2790     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2790     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2791      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2791      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2792 
  2792 
  2793     aFileDescriptor isNil ifTrue:[
  2793     aFileDescriptor isNil ifTrue:[
  2794 	idx := writeSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2794         idx := writeSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2795 	idx == 0 ifTrue:[
  2795         idx == 0 ifTrue:[
  2796 	    "aSemaphore is not registered yet, have to create a new slot"
  2796             "aSemaphore is not registered yet, have to create a new slot"
  2797 	    writeFdArray := writeFdArray copyWith:nil.
  2797             writeFdArray := writeFdArray copyWith:nil.
  2798 	    writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore.
  2798             writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore.
  2799 	    writeCheckArray := writeCheckArray copyWith:aBlock.
  2799             writeCheckArray := writeCheckArray copyWith:aBlock.
  2800 	] ifFalse:[
  2800         ] ifFalse:[
  2801 	    slot := writeSemaphoreArray at:idx.
  2801             slot := writeSemaphoreArray at:idx.
  2802 	    slot isNil ifTrue:[
  2802             slot isNil ifTrue:[
  2803 		writeSemaphoreArray at:idx put:aSemaphore.
  2803                 writeSemaphoreArray at:idx put:aSemaphore.
  2804 		writeCheckArray at:idx put:aBlock
  2804                 writeCheckArray at:idx put:aBlock
  2805 	    ] ifFalse:[
  2805             ] ifFalse:[
  2806 		"/ someone has already registered aSemaphore.
  2806                 "/ someone has already registered aSemaphore.
  2807 		"/ Check if it is the block changes...
  2807                 "/ Check if it is the block changes...
  2808 		(writeCheckArray at:idx) notNil ifTrue:[
  2808                 (writeCheckArray at:idx) notNil ifTrue:[
  2809 		    (writeCheckArray at:idx) ~~ aBlock ifTrue:[
  2809                     (writeCheckArray at:idx) ~~ aBlock ifTrue:[
  2810 			'Processor [info]: checkblock changed for write-check' infoPrintCR.
  2810                         'Processor [info]: checkblock changed for write-check' infoPrintCR.
  2811 			writeCheckArray at:idx put:aBlock.
  2811                         writeCheckArray at:idx put:aBlock.
  2812 		    ].
  2812                     ].
  2813 		].
  2813                 ].
  2814 	    ].
  2814             ].
  2815 	]
  2815         ]
  2816     ] ifFalse:[
  2816     ] ifFalse:[
  2817 	idx := writeFdArray identityIndexOf:aFileDescriptor or:nil.
  2817         idx := writeFdArray identityIndexOf:aFileDescriptor or:nil.
  2818 	idx == 0 ifTrue:[
  2818         idx == 0 ifTrue:[
  2819 	    "aFileDescriptor is not registered yet, have to create a new slot"
  2819             "aFileDescriptor is not registered yet, have to create a new slot"
  2820 	    writeFdArray := writeFdArray copyWith:aFileDescriptor.
  2820             writeFdArray := writeFdArray copyWith:aFileDescriptor.
  2821 	    writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore.
  2821             writeSemaphoreArray := writeSemaphoreArray copyWith:aSemaphore.
  2822 	    writeCheckArray := writeCheckArray copyWith:aBlock.
  2822             writeCheckArray := writeCheckArray copyWith:aBlock.
  2823 	] ifFalse:[
  2823         ] ifFalse:[
  2824 	    slot := writeFdArray at:idx.
  2824             slot := writeFdArray at:idx.
  2825 	    slot isNil ifTrue:[
  2825             slot isNil ifTrue:[
  2826 		writeFdArray at:idx put:aFileDescriptor.
  2826                 writeFdArray at:idx put:aFileDescriptor.
  2827 		writeSemaphoreArray at:idx put:aSemaphore.
  2827                 writeSemaphoreArray at:idx put:aSemaphore.
  2828 		writeCheckArray at:idx put:aBlock
  2828                 writeCheckArray at:idx put:aBlock
  2829 	    ] ifFalse:[
  2829             ] ifFalse:[
  2830 		"/ someone has already registered aFileDescriptor.
  2830                 "/ someone has already registered aFileDescriptor.
  2831 		"/ Check if it is the semaphore or block changes...
  2831                 "/ Check if it is the semaphore or block changes...
  2832 		(writeSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[
  2832                 (writeSemaphoreArray at:idx) ~~ aSemaphore ifTrue:[
  2833 		    'Processor [info]: sema changed for write-check' infoPrintCR.
  2833                     'Processor [info]: sema changed for write-check' infoPrintCR.
  2834 		    writeSemaphoreArray at:idx put:aSemaphore.
  2834                     writeSemaphoreArray at:idx put:aSemaphore.
  2835 		].
  2835                 ].
  2836 		(writeCheckArray at:idx) ~~ aBlock ifTrue:[
  2836                 (writeCheckArray at:idx) ~~ aBlock ifTrue:[
  2837 		    'Processor [info]: checkblock changed for write-check' infoPrintCR.
  2837                     'Processor [info]: checkblock changed for write-check' infoPrintCR.
  2838 		    writeCheckArray at:idx put:aBlock.
  2838                     writeCheckArray at:idx put:aBlock.
  2839 		].
  2839                 ].
  2840 	    ].
  2840             ].
  2841 	].
  2841         ].
  2842 	(useIOInterrupts and:[slot isNil]) ifTrue:[
  2842         (useIOInterrupts and:[slot isNil]) ifTrue:[
  2843 	    OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2843             OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2844 	].
  2844         ].
  2845     ].
  2845     ].
  2846     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2846     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2847 
  2847 
  2848     "Modified: 4.8.1997 / 15:21:49 / cg"
  2848     "Modified: 4.8.1997 / 15:21:49 / cg"
  2849 !
  2849 !
  2873      If enabled, arrangements are made for data-availability to trigger an
  2873      If enabled, arrangements are made for data-availability to trigger an
  2874      interrupt.
  2874      interrupt.
  2875      Using IO interrupts reduces the idle CPU usage of ST/X by some percent
  2875      Using IO interrupts reduces the idle CPU usage of ST/X by some percent
  2876      (typically 2-7%).
  2876      (typically 2-7%).
  2877      Notice:
  2877      Notice:
  2878 	some systems do not support IO-interrupts (or have a broken stdio-lib),
  2878         some systems do not support IO-interrupts (or have a broken stdio-lib),
  2879 	and this feature is always disabled;
  2879         and this feature is always disabled;
  2880      Also notice:
  2880      Also notice:
  2881 	we found that in some Xlib-implementations, interrupted reads are not
  2881         we found that in some Xlib-implementations, interrupted reads are not
  2882 	handled correctly (especially in multi-headed applications), and this
  2882         handled correctly (especially in multi-headed applications), and this
  2883 	feature should be disabled to avoid a blocking XPending.
  2883         feature should be disabled to avoid a blocking XPending.
  2884 
  2884 
  2885      If this method is used to disable IO interrupts in multi-headed apps,
  2885      If this method is used to disable IO interrupts in multi-headed apps,
  2886      it should be invoked BEFORE the display event dispatcher processes are started."
  2886      it should be invoked BEFORE the display event dispatcher processes are started."
  2887 
  2887 
  2888     OperatingSystem supportsIOInterrupts ifTrue:[
  2888     OperatingSystem supportsIOInterrupts ifTrue:[
  2889 	useIOInterrupts := aBoolean
  2889         useIOInterrupts := aBoolean
  2890     ].
  2890     ].
  2891 
  2891 
  2892     "Created: / 15.7.1998 / 13:32:29 / cg"
  2892     "Created: / 15.7.1998 / 13:32:29 / cg"
  2893 ! !
  2893 ! !
  2894 
  2894 
  3120 
  3120 
  3121     |sema now aTime block blocksAndProcessesToEvaluate
  3121     |sema now aTime block blocksAndProcessesToEvaluate
  3122      firstBlockToEvaluate firstProcess
  3122      firstBlockToEvaluate firstProcess
  3123      n "{ Class: SmallInteger }"
  3123      n "{ Class: SmallInteger }"
  3124      indexOfLastTimeout "{ Class: SmallInteger }"
  3124      indexOfLastTimeout "{ Class: SmallInteger }"
  3125      halfSize "{ Class: SmallInteger }"
  3125      halfSize "{ Class: SmallInteger }" process wasBlocked|
  3126      wasBlocked p|
  3126 
  3127 
  3127     anyTimeouts ifFalse:[ 
  3128     anyTimeouts ifFalse:[ ^ self].
  3128         ^ self
       
  3129     ].
  3129     anyTimeouts := false.
  3130     anyTimeouts := false.
  3130     indexOfLastTimeout := 0.
  3131     indexOfLastTimeout := 0.
  3131 
  3132 
  3132     "have to collect the blocks first, then evaluate them.
  3133     "have to collect the blocks first, then evaluate them.
  3133      This avoids problems due to newly inserted blocks."
  3134      This avoids problems due to newly inserted blocks."
  3138     "/ To avoid idle memory allocation, we avoid the allocation of the OrderedCollection in this case,
  3139     "/ To avoid idle memory allocation, we avoid the allocation of the OrderedCollection in this case,
  3139     "/ by remembering the first block+process in a variable until another block is found.
  3140     "/ by remembering the first block+process in a variable until another block is found.
  3140     "/ Thus firstBlockToEvaluate+firstProcess effectively cache the first slot of the lazy allocated collection.
  3141     "/ Thus firstBlockToEvaluate+firstProcess effectively cache the first slot of the lazy allocated collection.
  3141     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3142     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3142 
  3143 
       
  3144     wasBlocked := OperatingSystem blockInterrupts.
  3143     now := OperatingSystem getMillisecondTime.
  3145     now := OperatingSystem getMillisecondTime.
  3144     n := timeoutArray size.
  3146     n := timeoutArray size.
  3145     1 to:n do:[:index |
  3147     1 to:n do:[:index |
  3146         aTime := timeoutArray at:index.
  3148         aTime := timeoutArray at:index.
  3147         aTime notNil ifTrue:[
  3149         aTime notNil ifTrue:[
  3149                 "this one should be triggered"
  3151                 "this one should be triggered"
  3150 
  3152 
  3151                 sema := timeoutSemaphoreArray at:index.
  3153                 sema := timeoutSemaphoreArray at:index.
  3152                 sema notNil ifTrue:[
  3154                 sema notNil ifTrue:[
  3153                     timeoutSemaphoreArray at:index put:nil.
  3155                     timeoutSemaphoreArray at:index put:nil.
  3154                     timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3156                     timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal.
  3155                     sema signalOnceWithoutReschedule.
  3157                     sema signalOnceWithoutReschedule.
  3156                 ] ifFalse:[
  3158                 ] ifFalse:[
  3157                     "to support pure-events"
  3159                     "to support pure-events"
  3158                     block := timeoutActionArray at:index.
  3160                     block := timeoutActionArray at:index.
  3159                     block notNil ifTrue:[
  3161                     block notNil ifTrue:[
  3170                             firstProcess := timeoutProcessArray at:index.
  3172                             firstProcess := timeoutProcessArray at:index.
  3171                         ] ifFalse:[
  3173                         ] ifFalse:[
  3172                             blocksAndProcessesToEvaluate isNil ifTrue:[
  3174                             blocksAndProcessesToEvaluate isNil ifTrue:[
  3173                                 blocksAndProcessesToEvaluate := OrderedCollection
  3175                                 blocksAndProcessesToEvaluate := OrderedCollection
  3174                                                                     with:firstBlockToEvaluate
  3176                                                                     with:firstBlockToEvaluate
  3175                                                                     with:firstProcess.
  3177                                                                     with:firstProcess
       
  3178                                                                     with:block
       
  3179                                                                     with:(timeoutProcessArray at:index).
       
  3180                             ] ifFalse:[
       
  3181                                 blocksAndProcessesToEvaluate 
       
  3182                                     add:block;
       
  3183                                     add:(timeoutProcessArray at:index).
  3176                             ].
  3184                             ].
  3177                             blocksAndProcessesToEvaluate add:block.
       
  3178                             blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index).
       
  3179                         ].
  3185                         ].
  3180                         timeoutActionArray at:index put:nil.
  3186                         timeoutActionArray at:index put:nil.
  3181                         timeoutProcessArray at:index put:nil.
  3187                         timeoutProcessArray at:index put:nil.
  3182                     ]
  3188                     ]
  3183                 ].
  3189                 ].
  3192 
  3198 
  3193     "shrink the arrays, if they are 50% free"
  3199     "shrink the arrays, if they are 50% free"
  3194     n > 20 ifTrue:[
  3200     n > 20 ifTrue:[
  3195         halfSize := n // 2.
  3201         halfSize := n // 2.
  3196         (indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[
  3202         (indexOfLastTimeout ~~ 0 and:[indexOfLastTimeout < halfSize]) ifTrue:[
  3197             wasBlocked := OperatingSystem blockInterrupts.
  3203             timeoutArray := timeoutArray copyTo:halfSize.
  3198             (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[   "/ no new timeouts arrived
  3204             timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3199                 timeoutArray := timeoutArray copyTo:halfSize.
  3205             timeoutActionArray := timeoutActionArray copyTo:halfSize.
  3200                 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3206             timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
  3201                 timeoutActionArray := timeoutActionArray copyTo:halfSize.
       
  3202                 timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
       
  3203             ].
       
  3204             wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
       
  3205         ].
  3207         ].
  3206     ].
  3208     ].
  3207 
  3209 
  3208     "/ usually (>99%), there is only one single timeout action to call;
  3210     "/ usually (>99%), there is only one single timeout action to call;
  3209     "/ above code avoided the creation of an OrderedCollection
  3211     "/ above code avoided the creation of an OrderedCollection
  3210     blocksAndProcessesToEvaluate isNil ifTrue:[
  3212     blocksAndProcessesToEvaluate isNil ifTrue:[
  3211         firstBlockToEvaluate notNil ifTrue:[
  3213         firstBlockToEvaluate notNil ifTrue:[
  3212             timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3214             timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal.
  3213             (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3215             (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3214                 firstBlockToEvaluate value
  3216                 firstBlockToEvaluate value
  3215             ] ifFalse:[
  3217             ] ifFalse:[
  3216                 firstProcess isDead ifTrue:[
  3218                 firstProcess isDead ifTrue:[
  3217                     "/ a timedBlock for a process which has already terminated
  3219                     "/ a timedBlock for a process which has already terminated
  3234         ].
  3236         ].
  3235     ] ifFalse:[
  3237     ] ifFalse:[
  3236         n := blocksAndProcessesToEvaluate size.
  3238         n := blocksAndProcessesToEvaluate size.
  3237         1 to:n by:2 do:[:index |
  3239         1 to:n by:2 do:[:index |
  3238             block := blocksAndProcessesToEvaluate at:index.
  3240             block := blocksAndProcessesToEvaluate at:index.
  3239             p := blocksAndProcessesToEvaluate at:index+1.
  3241             process := blocksAndProcessesToEvaluate at:index+1.
  3240             (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[
  3242             (process isNil or:[process == scheduler or:[PureEventDriven]]) ifTrue:[
  3241                 block value.
  3243                 block value.
  3242                 timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3244                 timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal.
  3243             ] ifFalse:[
  3245             ] ifFalse:[
  3244                 p isDead ifTrue:[
  3246                 process isDead ifTrue:[
  3245                     "/ a timedBlock for a process which has already terminated
  3247                     "/ a timedBlock for a process which has already terminated
  3246                     "/ issue a warning and do not execute it.
  3248                     "/ issue a warning and do not execute it.
  3247                     "/ (executing here may be dangerous, since it would run at scheduler priority here,
  3249                     "/ (executing here may be dangerous, since it would run at scheduler priority here,
  3248                     "/  and thereby could block the whole smalltalk system.
  3250                     "/  and thereby could block the whole smalltalk system.
  3249                     "/  For this reason is it IGNORED here.)
  3251                     "/  For this reason is it IGNORED here.)
  3251                     "/ Could handle it in timeoutProcess, but we don't,
  3253                     "/ Could handle it in timeoutProcess, but we don't,
  3252                     "/ because otherwise timeouts might be reissued forever...
  3254                     "/ because otherwise timeouts might be reissued forever...
  3253                     "/      (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3255                     "/      (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3254                     "/          timeoutHandlerProcess interruptWith:block.
  3256                     "/          timeoutHandlerProcess interruptWith:block.
  3255                     "/      ] ifFalse:[
  3257                     "/      ] ifFalse:[
  3256                         ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , p name , '''') errorPrintCR.
  3258                         ('ProcessorScheduler [warning]: cannot evaluate timedBlock (', block displayString, ') for dead process: ''' , process name , '''') errorPrintCR.
  3257                     "/      ].
  3259                     "/      ].
  3258                 ] ifFalse:[
  3260                 ] ifFalse:[
  3259                     timedActionCounter := (timedActionCounter + 1 bitAnd:SmallInteger maxVal).
  3261                     timedActionCounter := (timedActionCounter + 1) bitAnd:SmallInteger maxVal.
  3260                     p interruptWith:block
  3262                     process interruptWith:block
  3261                 ]
  3263                 ]
  3262             ]
  3264             ]
  3263         ]
  3265         ]
  3264     ].
  3266     ].
  3265 
  3267     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3266     "Modified: / 24-07-2017 / 16:15:36 / stefan"
  3268 
       
  3269     "Modified: / 25-07-2017 / 14:49:46 / stefan"
  3267     "Modified: / 25-07-2017 / 11:27:00 / cg"
  3270     "Modified: / 25-07-2017 / 11:27:00 / cg"
  3268 !
  3271 !
  3269 
  3272 
  3270 removeTimedBlock:aBlock
  3273 removeTimedBlock:aBlock
  3271     "remove the argument, aBlock from the list of time-sceduled-blocks."
  3274     "remove the argument, aBlock from the list of time-sceduled-blocks."
  3276     aBlock isNil ifTrue:[^ self].
  3279     aBlock isNil ifTrue:[^ self].
  3277 
  3280 
  3278     wasBlocked := OperatingSystem blockInterrupts.
  3281     wasBlocked := OperatingSystem blockInterrupts.
  3279     index := timeoutActionArray identityIndexOf:aBlock startingAt:1.
  3282     index := timeoutActionArray identityIndexOf:aBlock startingAt:1.
  3280     (index ~~ 0) ifTrue:[
  3283     (index ~~ 0) ifTrue:[
  3281 	timeoutArray at:index put:nil.
  3284         timeoutArray at:index put:nil.
  3282 	timeoutActionArray at:index put:nil.
  3285         timeoutActionArray at:index put:nil.
  3283 	timeoutSemaphoreArray at:index put:nil.
  3286         timeoutSemaphoreArray at:index put:nil.
  3284 	timeoutProcessArray at:index put:nil.
  3287         timeoutProcessArray at:index put:nil.
  3285     ].
  3288     ].
  3286     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3289     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3287 !
  3290 !
  3288 
  3291 
  3289 removeTimeoutForSemaphore:aSemaphore
  3292 removeTimeoutForSemaphore:aSemaphore
  3316     |index "{ Class: SmallInteger }"
  3319     |index "{ Class: SmallInteger }"
  3317      wasBlocked|
  3320      wasBlocked|
  3318 
  3321 
  3319     index := anID.
  3322     index := anID.
  3320     (index > 0) ifTrue:[
  3323     (index > 0) ifTrue:[
  3321 	wasBlocked := OperatingSystem blockInterrupts.
  3324         wasBlocked := OperatingSystem blockInterrupts.
  3322 
  3325 
  3323 	timeoutArray at:index put:nil.
  3326         timeoutArray at:index put:nil.
  3324 	timeoutActionArray at:index put:nil.
  3327         timeoutActionArray at:index put:nil.
  3325 	timeoutSemaphoreArray at:index put:nil.
  3328         timeoutSemaphoreArray at:index put:nil.
  3326 	timeoutProcessArray at:index put:nil.
  3329         timeoutProcessArray at:index put:nil.
  3327 
  3330 
  3328 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3331         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3329     ]
  3332     ]
  3330 
  3333 
  3331     "Created: 23.9.1996 / 14:32:33 / cg"
  3334     "Created: 23.9.1996 / 14:32:33 / cg"
  3332     "Modified: 23.9.1996 / 14:35:09 / cg"
  3335     "Modified: 23.9.1996 / 14:35:09 / cg"
  3333 !
  3336 !
  3341     |index "{ Class: SmallInteger }"
  3344     |index "{ Class: SmallInteger }"
  3342      wasBlocked|
  3345      wasBlocked|
  3343 
  3346 
  3344     index := anID.
  3347     index := anID.
  3345     (anID notNil and:[index > 0]) ifTrue:[
  3348     (anID notNil and:[index > 0]) ifTrue:[
  3346 	wasBlocked := OperatingSystem blockInterrupts.
  3349         wasBlocked := OperatingSystem blockInterrupts.
  3347 
  3350 
  3348 	(aBlockOrSemaphore notNil
  3351         (aBlockOrSemaphore notNil
  3349 	  and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore
  3352           and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore
  3350 	  and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[
  3353           and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[
  3351 	    'Processor: trying to remove stale timeout id - ignored' errorPrintCR.
  3354             'Processor: trying to remove stale timeout id - ignored' errorPrintCR.
  3352 	] ifFalse:[
  3355         ] ifFalse:[
  3353 	    timeoutArray at:index put:nil.
  3356             timeoutArray at:index put:nil.
  3354 	    timeoutActionArray at:index put:nil.
  3357             timeoutActionArray at:index put:nil.
  3355 	    timeoutSemaphoreArray at:index put:nil.
  3358             timeoutSemaphoreArray at:index put:nil.
  3356 	    timeoutProcessArray at:index put:nil.
  3359             timeoutProcessArray at:index put:nil.
  3357 	].
  3360         ].
  3358 
  3361 
  3359 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3362         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3360     ]
  3363     ]
  3361 !
  3364 !
  3362 
  3365 
  3363 timeoutHandlerProcess
  3366 timeoutHandlerProcess
  3364     (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[
  3367     (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[
  3365 	timeoutHandlerProcess :=
  3368         timeoutHandlerProcess :=
  3366 		[
  3369                 [
  3367 		    [
  3370                     [
  3368 			self timeoutHandlerProcessLoop.
  3371                         self timeoutHandlerProcessLoop.
  3369 		    ] ensure:[
  3372                     ] ensure:[
  3370 			timeoutHandlerProcess := nil
  3373                         timeoutHandlerProcess := nil
  3371 		    ].
  3374                     ].
  3372 		] newProcess.
  3375                 ] newProcess.
  3373 
  3376 
  3374 	timeoutHandlerProcess
  3377         timeoutHandlerProcess
  3375 	    priority:TimingPriority;
  3378             priority:TimingPriority;
  3376 	    name:'timeout handler';
  3379             name:'timeout handler';
  3377 	    beSystemProcess;
  3380             beSystemProcess;
  3378 	    resume.
  3381             resume.
  3379     ].
  3382     ].
  3380     ^ timeoutHandlerProcess.
  3383     ^ timeoutHandlerProcess.
  3381 
  3384 
  3382     "Modified: / 20-07-2006 / 09:52:27 / cg"
  3385     "Modified: / 20-07-2006 / 09:52:27 / cg"
  3383 !
  3386 !
  3417 
  3420 
  3418     |wasBlocked|
  3421     |wasBlocked|
  3419 
  3422 
  3420     wasBlocked := OperatingSystem blockInterrupts.
  3423     wasBlocked := OperatingSystem blockInterrupts.
  3421     preWaitActions isNil ifTrue:[
  3424     preWaitActions isNil ifTrue:[
  3422 	preWaitActions := OrderedCollection new
  3425         preWaitActions := OrderedCollection new
  3423     ].
  3426     ].
  3424     preWaitActions add:aBlock.
  3427     preWaitActions add:aBlock.
  3425     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3428     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3426 !
  3429 !
  3427 
  3430 
  3653      Notice, that at the time of the message, we are still in the context
  3656      Notice, that at the time of the message, we are still in the context
  3654      of whichever process is currently running."
  3657      of whichever process is currently running."
  3655 
  3658 
  3656     gotIOInterrupt := true.
  3659     gotIOInterrupt := true.
  3657     activeProcess ~~ scheduler ifTrue:[
  3660     activeProcess ~~ scheduler ifTrue:[
  3658 	interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3661         interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3659 	interruptedProcess := activeProcess.
  3662         interruptedProcess := activeProcess.
  3660 	self threadSwitch:scheduler
  3663         self threadSwitch:scheduler
  3661     ]
  3664     ]
  3662 
  3665 
  3663     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3666     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3664     "Modified: 4.8.1997 / 14:23:08 / cg"
  3667     "Modified: 4.8.1997 / 14:23:08 / cg"
  3665 !
  3668 !
  3673      an #EBADF error, leading to high-frequency polling and a locked up system.
  3676      an #EBADF error, leading to high-frequency polling and a locked up system.
  3674      (you could still fix things by interrupting on the console and fixing the
  3677      (you could still fix things by interrupting on the console and fixing the
  3675       readFdArray/writeFdArray in the debugger)"
  3678       readFdArray/writeFdArray in the debugger)"
  3676 
  3679 
  3677     readFdArray keysAndValuesDo:[:idx :fd |
  3680     readFdArray keysAndValuesDo:[:idx :fd |
  3678 	|result sema|
  3681         |result sema|
  3679 
  3682 
  3680 	fd notNil ifTrue:[
  3683         fd notNil ifTrue:[
  3681 	    result := OperatingSystem
  3684             result := OperatingSystem
  3682 			selectOnAnyReadable:(Array with:fd) writable:nil exception:nil
  3685                         selectOnAnyReadable:(Array with:fd) writable:nil exception:nil
  3683 			   readableInto:nil writableInto:nil exceptionInto:nil
  3686                            readableInto:nil writableInto:nil exceptionInto:nil
  3684 			   withTimeOut:0.
  3687                            withTimeOut:0.
  3685 
  3688 
  3686 	    result < 0 ifTrue:[
  3689             result < 0 ifTrue:[
  3687 		'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3690                 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3688 		readFdArray at:idx put:nil.
  3691                 readFdArray at:idx put:nil.
  3689 		readCheckArray at:idx put:nil.
  3692                 readCheckArray at:idx put:nil.
  3690 		(sema := readSemaphoreArray at:idx) notNil ifTrue:[
  3693                 (sema := readSemaphoreArray at:idx) notNil ifTrue:[
  3691 		    readSemaphoreArray at:idx put:nil.
  3694                     readSemaphoreArray at:idx put:nil.
  3692 		    self removeTimeoutForSemaphore:sema.
  3695                     self removeTimeoutForSemaphore:sema.
  3693 		    sema signalForAll.
  3696                     sema signalForAll.
  3694 		].
  3697                 ].
  3695 	    ]
  3698             ]
  3696 	].
  3699         ].
  3697     ].
  3700     ].
  3698 
  3701 
  3699     writeFdArray keysAndValuesDo:[:idx :fd |
  3702     writeFdArray keysAndValuesDo:[:idx :fd |
  3700 	|result sema|
  3703         |result sema|
  3701 
  3704 
  3702 	fd notNil ifTrue:[
  3705         fd notNil ifTrue:[
  3703 	    result := OperatingSystem
  3706             result := OperatingSystem
  3704 			selectOnAnyReadable:nil writable:(Array with:fd) exception:nil
  3707                         selectOnAnyReadable:nil writable:(Array with:fd) exception:nil
  3705 			   readableInto:nil writableInto:nil exceptionInto:nil
  3708                            readableInto:nil writableInto:nil exceptionInto:nil
  3706 			   withTimeOut:0.
  3709                            withTimeOut:0.
  3707 
  3710 
  3708 	    result < 0 ifTrue:[
  3711             result < 0 ifTrue:[
  3709 		'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3712                 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3710 		writeFdArray at:idx put:nil.
  3713                 writeFdArray at:idx put:nil.
  3711 		writeCheckArray at:idx put:nil.
  3714                 writeCheckArray at:idx put:nil.
  3712 		(sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  3715                 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  3713 		    writeSemaphoreArray at:idx put:nil.
  3716                     writeSemaphoreArray at:idx put:nil.
  3714 		    self removeTimeoutForSemaphore:sema.
  3717                     self removeTimeoutForSemaphore:sema.
  3715 		    sema signalForAll.
  3718                     sema signalForAll.
  3716 		].
  3719                 ].
  3717 	    ]
  3720             ]
  3718 	]
  3721         ]
  3719     ].
  3722     ].
  3720 
  3723 
  3721     exceptFdArray keysAndValuesDo:[:idx :fd |
  3724     exceptFdArray keysAndValuesDo:[:idx :fd |
  3722 	|result sema|
  3725         |result sema|
  3723 
  3726 
  3724 	fd notNil ifTrue:[
  3727         fd notNil ifTrue:[
  3725 	    result := OperatingSystem
  3728             result := OperatingSystem
  3726 			selectOnAnyReadable:nil writable:nil exception:(Array with:fd)
  3729                         selectOnAnyReadable:nil writable:nil exception:(Array with:fd)
  3727 			   readableInto:nil writableInto:nil exceptionInto:nil
  3730                            readableInto:nil writableInto:nil exceptionInto:nil
  3728 			   withTimeOut:0.
  3731                            withTimeOut:0.
  3729 
  3732 
  3730 	    result < 0 ifTrue:[
  3733             result < 0 ifTrue:[
  3731 		'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3734                 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3732 		exceptFdArray at:idx put:nil.
  3735                 exceptFdArray at:idx put:nil.
  3733 		(sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  3736                 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  3734 		    exceptSemaphoreArray at:idx put:nil.
  3737                     exceptSemaphoreArray at:idx put:nil.
  3735 		    self removeTimeoutForSemaphore:sema.
  3738                     self removeTimeoutForSemaphore:sema.
  3736 		    sema signalForAll.
  3739                     sema signalForAll.
  3737 		].
  3740                 ].
  3738 	    ]
  3741             ]
  3739 	]
  3742         ]
  3740     ].
  3743     ].
  3741 
  3744 
  3742 
  3745 
  3743     OperatingSystem isMSWINDOWSlike ifTrue:[
  3746     OperatingSystem isMSWINDOWSlike ifTrue:[
  3744 	"/
  3747         "/
  3745 	"/ win32 does a WaitForMultipleObjects in select...
  3748         "/ win32 does a WaitForMultipleObjects in select...
  3746 	"/ unix waits for SIGCHLD
  3749         "/ unix waits for SIGCHLD
  3747 	"/
  3750         "/
  3748 	osChildExitActions keysDo:[:eachPid |
  3751         osChildExitActions keysDo:[:eachPid |
  3749 	    |result sema|
  3752             |result sema|
  3750 
  3753 
  3751 	    eachPid notNil ifTrue:[
  3754             eachPid notNil ifTrue:[
  3752 		result := OperatingSystem
  3755                 result := OperatingSystem
  3753 			    selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid)
  3756                             selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid)
  3754 			       readableInto:nil writableInto:nil exceptionInto:nil
  3757                                readableInto:nil writableInto:nil exceptionInto:nil
  3755 			       withTimeOut:0.
  3758                                withTimeOut:0.
  3756 
  3759 
  3757 		result < 0 ifTrue:[
  3760                 result < 0 ifTrue:[
  3758 		    'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR.
  3761                     'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR.
  3759 		    osChildExitActions safeRemoveKey:eachPid.
  3762                     osChildExitActions safeRemoveKey:eachPid.
  3760 		]
  3763                 ]
  3761 	    ]
  3764             ]
  3762 	].
  3765         ].
  3763     ].
  3766     ].
  3764 
  3767 
  3765     "Modified: 12.4.1996 / 09:32:58 / stefan"
  3768     "Modified: 12.4.1996 / 09:32:58 / stefan"
  3766     "Modified: 27.1.1997 / 20:09:27 / cg"
  3769     "Modified: 27.1.1997 / 20:09:27 / cg"
  3767 !
  3770 !
  3769 schedulerInterrupt
  3772 schedulerInterrupt
  3770     "forced reschedule - switch to scheduler process which will decide
  3773     "forced reschedule - switch to scheduler process which will decide
  3771      what to do now."
  3774      what to do now."
  3772 
  3775 
  3773     activeProcess ~~ scheduler ifTrue:[
  3776     activeProcess ~~ scheduler ifTrue:[
  3774 	interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3777         interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3775 	interruptedProcess := activeProcess.
  3778         interruptedProcess := activeProcess.
  3776 	self threadSwitch:scheduler
  3779         self threadSwitch:scheduler
  3777     ]
  3780     ]
  3778 !
  3781 !
  3779 
  3782 
  3780 timeToNextTimeout
  3783 timeToNextTimeout
  3781     "return the delta-T (in millis) to next timeout, or nil if
  3784     "return the delta-T (in millis) to next timeout, or nil if
  3787      If there were many, the list should be kept sorted ... keeping deltas
  3790      If there were many, the list should be kept sorted ... keeping deltas
  3788      to next (as in Unix kernel)"
  3791      to next (as in Unix kernel)"
  3789 
  3792 
  3790     n := timeoutArray size.
  3793     n := timeoutArray size.
  3791     1 to:n do:[:index |
  3794     1 to:n do:[:index |
  3792 	aTime := timeoutArray at:index.
  3795         aTime := timeoutArray at:index.
  3793 	aTime notNil ifTrue:[
  3796         aTime notNil ifTrue:[
  3794 	    now isNil ifTrue:[
  3797             now isNil ifTrue:[
  3795 		now := OperatingSystem getMillisecondTime.
  3798                 now := OperatingSystem getMillisecondTime.
  3796 	    ].
  3799             ].
  3797 	    delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now.
  3800             delta := OperatingSystem millisecondTimeDeltaBetween:aTime and:now.
  3798 	    delta <= 0 ifTrue:[
  3801             delta <= 0 ifTrue:[
  3799 		^ 0.
  3802                 ^ 0.
  3800 	    ].
  3803             ].
  3801 	    minDelta isNil ifTrue:[
  3804             minDelta isNil ifTrue:[
  3802 		minDelta := delta
  3805                 minDelta := delta
  3803 	    ] ifFalse:[
  3806             ] ifFalse:[
  3804 		minDelta := minDelta min:delta
  3807                 minDelta := minDelta min:delta
  3805 	    ]
  3808             ]
  3806 	]
  3809         ]
  3807     ].
  3810     ].
  3808     minDelta isNil ifTrue:[
  3811     minDelta isNil ifTrue:[
  3809 	"this is safe, since always called with interruptsBlocked"
  3812         "this is safe, since always called with interruptsBlocked"
  3810 	anyTimeouts := false.
  3813         anyTimeouts := false.
  3811     ].
  3814     ].
  3812 
  3815 
  3813     ^ minDelta
  3816     ^ minDelta
  3814 !
  3817 !
  3815 
  3818 
  3821      This method is called by the VM' interrupt handling mechanism.
  3824      This method is called by the VM' interrupt handling mechanism.
  3822      Notice, that at the time of the message, we are still in the context
  3825      Notice, that at the time of the message, we are still in the context
  3823      of whichever process is currently running."
  3826      of whichever process is currently running."
  3824 
  3827 
  3825     activeProcess ~~ scheduler ifTrue:[
  3828     activeProcess ~~ scheduler ifTrue:[
  3826 	interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3829         interruptCounter := interruptCounter + 1 bitAnd:SmallInteger maxVal.
  3827 	interruptedProcess := activeProcess.
  3830         interruptedProcess := activeProcess.
  3828 	self threadSwitch:scheduler
  3831         self threadSwitch:scheduler
  3829     ]
  3832     ]
  3830 
  3833 
  3831     "Modified: 18.10.1996 / 20:35:54 / cg"
  3834     "Modified: 18.10.1996 / 20:35:54 / cg"
  3832 !
  3835 !
  3833 
  3836