ProcessorScheduler.st
changeset 19850 c30c21be7440
parent 19083 504ff3f2cfa0
child 19853 b5615ba2f049
equal deleted inserted replaced
19849:e989f43ce274 19850:c30c21be7440
    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'
    28 		exceptResultFdArray exceptSemaphoreArray interruptCounter
       
    29 		timedActionCounter'
    29 	classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    30 	classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    30 		UserSchedulingPriority UserInterruptPriority TimingPriority
    31 		UserSchedulingPriority UserInterruptPriority TimingPriority
    31 		HighestPriority SchedulingPriority MaxNumberOfProcesses
    32 		HighestPriority SchedulingPriority MaxNumberOfProcesses
    32 		InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval
    33 		InvalidProcessSignal TimeSlicingPriorityLimit TimeSliceInterval
    33 		EventPollingInterval MaxProcessId'
    34 		EventPollingInterval MaxProcessId'
   575     ^ currentPriority
   576     ^ currentPriority
   576 
   577 
   577     "Processor currentPriority"
   578     "Processor currentPriority"
   578 !
   579 !
   579 
   580 
       
   581 interruptCounter
       
   582     "for statistics: counts the overall number of interrupts"
       
   583     
       
   584     ^ interruptCounter
       
   585 
       
   586     "
       
   587      Processor interruptCounter
       
   588     "
       
   589 !
       
   590 
   580 interruptedProcess
   591 interruptedProcess
   581     "returns the process which was interrupted by the active one"
   592     "returns the process which was interrupted by the active one"
   582 
   593 
   583     ^ interruptedProcess
   594     ^ interruptedProcess
   584 !
   595 !
   591 
   602 
   592 scheduler
   603 scheduler
   593     "return the scheduling process"
   604     "return the scheduling process"
   594 
   605 
   595     ^ scheduler
   606     ^ scheduler
       
   607 !
       
   608 
       
   609 timedActionCounter
       
   610     "for statistics: counts the overall number of timer actions"
       
   611     
       
   612     ^ timedActionCounter
       
   613 
       
   614     "
       
   615      Processor timedActionCounter
       
   616     "
   596 ! !
   617 ! !
   597 
   618 
   598 !ProcessorScheduler methodsFor:'background processing'!
   619 !ProcessorScheduler methodsFor:'background processing'!
   599 
   620 
   600 addIdleBlock:aBlock
   621 addIdleBlock:aBlock
   644 
   665 
   645     "
   666     "
   646      handle all timeout actions
   667      handle all timeout actions
   647     "
   668     "
   648     anyTimeouts ifTrue:[
   669     anyTimeouts ifTrue:[
   649         self evaluateTimeouts
   670 	self evaluateTimeouts
   650     ].
   671     ].
   651 
   672 
   652     "first do a quick check for semaphores using checkActions - this is needed for
   673     "first do a quick check for semaphores using checkActions - this is needed for
   653      devices like the X-connection, where some events might be in the event
   674      devices like the X-connection, where some events might be in the event
   654      queue but the sockets input queue is empty.
   675      queue but the sockets input queue is empty.
   656      Also, this is needed for poor MSDOS, where WaitForObject does not work with
   677      Also, this is needed for poor MSDOS, where WaitForObject does not work with
   657      sockets and pipes (sigh)
   678      sockets and pipes (sigh)
   658     "
   679     "
   659     nActions := readCheckArray size.
   680     nActions := readCheckArray size.
   660     1 to:nActions do:[:index |
   681     1 to:nActions do:[:index |
   661         checkBlock := readCheckArray at:index.
   682 	checkBlock := readCheckArray at:index.
   662         (checkBlock notNil and:[checkBlock value]) ifTrue:[
   683 	(checkBlock notNil and:[checkBlock value]) ifTrue:[
   663             sema := readSemaphoreArray at:index.
   684 	    sema := readSemaphoreArray at:index.
   664             sema notNil ifTrue:[
   685 	    sema notNil ifTrue:[
   665                 sema signalOnce.
   686 		sema signalOnce.
   666             ].
   687 	    ].
   667         ]
   688 	]
   668     ].
   689     ].
   669     nActions := writeCheckArray size.
   690     nActions := writeCheckArray size.
   670     1 to:nActions do:[:index |
   691     1 to:nActions do:[:index |
   671         checkBlock := writeCheckArray at:index.
   692 	checkBlock := writeCheckArray at:index.
   672         (checkBlock notNil and:[checkBlock value]) ifTrue:[
   693 	(checkBlock notNil and:[checkBlock value]) ifTrue:[
   673             sema := writeSemaphoreArray at:index.
   694 	    sema := writeSemaphoreArray at:index.
   674             sema notNil ifTrue:[
   695 	    sema notNil ifTrue:[
   675                 sema signalOnce.
   696 		sema signalOnce.
   676             ].
   697 	    ].
   677         ]
   698 	]
   678     ].
   699     ].
   679 
   700 
   680     "now, someone might be runnable ..."
   701     "now, someone might be runnable ..."
   681 
   702 
   682     p := self highestPriorityRunnableProcess.
   703     p := self highestPriorityRunnableProcess.
   683     p isNil ifTrue:[
   704     p isNil ifTrue:[
   684         "/ no one runnable, hard wait for event or timeout
   705 	"/ no one runnable, hard wait for event or timeout
   685         "/ Trace ifTrue:['w' printCR.].
   706 	"/ Trace ifTrue:['w' printCR.].
   686         self waitForEventOrTimeout.
   707 	self waitForEventOrTimeout.
   687 
   708 
   688         "/ check for OS process termination
   709 	"/ check for OS process termination
   689         gotChildSignalInterrupt ifTrue:[
   710 	gotChildSignalInterrupt ifTrue:[
   690             gotChildSignalInterrupt := false.
   711 	    gotChildSignalInterrupt := false.
   691             self handleChildSignalInterrupt
   712 	    self handleChildSignalInterrupt
   692         ].
   713 	].
   693         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   714 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   694         ^ self
   715 	^ self
   695     ].
   716     ].
   696 
   717 
   697     pri := p priority.
   718     pri := p priority.
   698 
   719 
   699     "
   720     "
   720  (a future version will have a process running to handle a timeout queue)
   741  (a future version will have a process running to handle a timeout queue)
   721 "
   742 "
   722 
   743 
   723 "
   744 "
   724     pri < TimingPriority ifTrue:[
   745     pri < TimingPriority ifTrue:[
   725         anyTimeouts ifTrue:[
   746 	anyTimeouts ifTrue:[
   726             millis := self timeToNextTimeout.
   747 	    millis := self timeToNextTimeout.
   727             millis == 0 ifTrue:[
   748 	    millis == 0 ifTrue:[
   728                 wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   749 		wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   729                 ^ self
   750 		^ self
   730             ]
   751 	    ]
   731         ]
   752 	]
   732     ].
   753     ].
   733 "
   754 "
   734 
   755 
   735     "
   756     "
   736      if the process to run has a lower than UserInterruptPriority,
   757      if the process to run has a lower than UserInterruptPriority,
   739      or by installing a poll-interrupt after 50ms (if the OS does not).
   760      or by installing a poll-interrupt after 50ms (if the OS does not).
   740     "
   761     "
   741     pri < UserInterruptPriority ifTrue:[
   762     pri < UserInterruptPriority ifTrue:[
   742 
   763 
   743 "comment out this if above is uncommented"
   764 "comment out this if above is uncommented"
   744         anyTimeouts ifTrue:[
   765 	anyTimeouts ifTrue:[
   745             millis := self timeToNextTimeout.
   766 	    millis := self timeToNextTimeout.
   746             millis == 0 ifTrue:[
   767 	    millis == 0 ifTrue:[
   747                 wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   768 		wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   748                 ^ self
   769 		^ self
   749             ].
   770 	    ].
   750         ].
   771 	].
   751 "---"
   772 "---"
   752 
   773 
   753         useIOInterrupts ifTrue:[
   774 	useIOInterrupts ifTrue:[
   754 "/            readFdArray do:[:fd |
   775 "/            readFdArray do:[:fd |
   755 "/                (fd notNil and:[fd >= 0]) ifTrue:[
   776 "/                (fd notNil and:[fd >= 0]) ifTrue:[
   756 "/                    OperatingSystem enableIOInterruptsOn:fd
   777 "/                    OperatingSystem enableIOInterruptsOn:fd
   757 "/                ].
   778 "/                ].
   758 "/            ].
   779 "/            ].
   759         ] ifFalse:[
   780 	] ifFalse:[
   760             millis notNil ifTrue:[
   781 	    millis notNil ifTrue:[
   761                 millis := millis min:EventPollingInterval
   782 		millis := millis min:EventPollingInterval
   762             ] ifFalse:[
   783 	    ] ifFalse:[
   763                 millis := EventPollingInterval
   784 		millis := EventPollingInterval
   764             ]
   785 	    ]
   765         ]
   786 	]
   766     ].
   787     ].
   767 
   788 
   768     millis notNil ifTrue:[
   789     millis notNil ifTrue:[
   769         "/ Trace ifTrue:['C' print. millis printCR.].
   790 	"/ Trace ifTrue:['C' print. millis printCR.].
   770         "schedule a clock interrupt after millis milliseconds"
   791 	"schedule a clock interrupt after millis milliseconds"
   771         OperatingSystem enableTimer:millis rounded.
   792 	OperatingSystem enableTimer:millis rounded.
   772     ].
   793     ].
   773 
   794 
   774     scheduledProcesses notNil ifTrue:[
   795     scheduledProcesses notNil ifTrue:[
   775         scheduledProcesses add:p
   796 	scheduledProcesses add:p
   776     ].
   797     ].
   777 
   798 
   778     "
   799     "
   779      now let the process run - will come back here by reschedule
   800      now let the process run - will come back here by reschedule
   780      from ioInterrupt, scheduler or timerInterrupt ... (running at max+1)
   801      from ioInterrupt, scheduler or timerInterrupt ... (running at max+1)
   782     "/ Trace ifTrue:['->' print. p printCR.].
   803     "/ Trace ifTrue:['->' print. p printCR.].
   783     self threadSwitch:p.
   804     self threadSwitch:p.
   784     "/ Trace ifTrue:['<-' printCR.].
   805     "/ Trace ifTrue:['<-' printCR.].
   785 
   806 
   786     "... when we arrive here, we are back on stage.
   807     "... when we arrive here, we are back on stage.
   787          Either by an ALARM or IO signal, or by a suspend of another process
   808 	 Either by an ALARM or IO signal, or by a suspend of another process
   788     "
   809     "
   789 
   810 
   790     millis notNil ifTrue:[
   811     millis notNil ifTrue:[
   791         OperatingSystem disableTimer.
   812 	OperatingSystem disableTimer.
   792     ].
   813     ].
   793 
   814 
   794     "/ check for OS process termination
   815     "/ check for OS process termination
   795     gotChildSignalInterrupt ifTrue:[
   816     gotChildSignalInterrupt ifTrue:[
   796         gotChildSignalInterrupt := false.
   817 	gotChildSignalInterrupt := false.
   797         self handleChildSignalInterrupt
   818 	self handleChildSignalInterrupt
   798     ].
   819     ].
   799 
   820 
   800     "/ check for new input
   821     "/ check for new input
   801 
   822 
   802     OperatingSystem unblockInterrupts.
   823     OperatingSystem unblockInterrupts.
   803 
   824 
   804     (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[
   825     (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[
   805         gotIOInterrupt := false.
   826 	gotIOInterrupt := false.
   806         self checkForIOWithTimeout:0.
   827 	self checkForIOWithTimeout:0.
   807     ].
   828     ].
   808 
   829 
   809     wasBlocked ifTrue:[OperatingSystem blockInterrupts].
   830     wasBlocked ifTrue:[OperatingSystem blockInterrupts].
   810 
   831 
   811     "Modified: / 12.4.1996 / 10:14:18 / stefan"
   832     "Modified: / 12.4.1996 / 10:14:18 / stefan"
   889 
   910 
   890     |nPrios "{ Class: SmallInteger }"
   911     |nPrios "{ Class: SmallInteger }"
   891      p l|
   912      p l|
   892 
   913 
   893     KnownProcesses isNil ifTrue:[
   914     KnownProcesses isNil ifTrue:[
   894         KnownProcesses := WeakArray new:30.
   915 	KnownProcesses := WeakArray new:30.
   895         KnownProcesses addDependent:self class.
   916 	KnownProcesses addDependent:self class.
   896         KnownProcessIds := OrderedCollection new:30.
   917 	KnownProcessIds := OrderedCollection new:30.
   897     ].
   918     ].
   898 
   919 
   899     "
   920     "
   900      create a collection with process lists; accessed using the priority as key
   921      create a collection with process lists; accessed using the priority as key
   901     "
   922     "
   920     dispatching := false.
   941     dispatching := false.
   921     useIOInterrupts := OperatingSystem supportsIOInterrupts.
   942     useIOInterrupts := OperatingSystem supportsIOInterrupts.
   922     gotIOInterrupt := false.
   943     gotIOInterrupt := false.
   923     osChildExitActions := Dictionary new.
   944     osChildExitActions := Dictionary new.
   924     gotChildSignalInterrupt := false.
   945     gotChildSignalInterrupt := false.
       
   946     interruptCounter := timedActionCounter := 0.
   925 
   947 
   926     supportDynamicPriorities := false.
   948     supportDynamicPriorities := false.
   927     exitWhenNoMoreUserProcesses isNil ifTrue:[
   949     exitWhenNoMoreUserProcesses isNil ifTrue:[
   928         exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ?
   950 	exitWhenNoMoreUserProcesses := false. "/ mhmh - how about true ?
   929     ].
   951     ].
   930 
   952 
   931     "
   953     "
   932      handcraft the first (dispatcher-) process - this one will never
   954      handcraft the first (dispatcher-) process - this one will never
   933      block, but go into a select if there is nothing to do.
   955      block, but go into a select if there is nothing to do.
   935      for a runnable process.
   957      for a runnable process.
   936     "
   958     "
   937     currentPriority := SchedulingPriority.
   959     currentPriority := SchedulingPriority.
   938     p := Process basicNew.
   960     p := Process basicNew.
   939     p
   961     p
   940         setId:0 state:#run;
   962 	setId:0 state:#run;
   941         setPriority:currentPriority;
   963 	setPriority:currentPriority;
   942         name:'scheduler';
   964 	name:'scheduler';
   943         beSystemProcess.
   965 	beSystemProcess.
   944 
   966 
   945     scheduler := activeProcess := p.
   967     scheduler := activeProcess := p.
   946     activeProcessId := 0.
   968     activeProcessId := 0.
   947 
   969 
   948     quiescentProcessLists at:currentPriority put:(l := LinkedList new).
   970     quiescentProcessLists at:currentPriority put:(l := LinkedList new).
   951     "
   973     "
   952      let me handle IO and timer interrupts
   974      let me handle IO and timer interrupts
   953     "
   975     "
   954     useIOInterrupts ifTrue:[ObjectMemory ioInterruptHandler:self].
   976     useIOInterrupts ifTrue:[ObjectMemory ioInterruptHandler:self].
   955     ObjectMemory
   977     ObjectMemory
   956         timerInterruptHandler:self;
   978 	timerInterruptHandler:self;
   957         childSignalInterruptHandler:self.
   979 	childSignalInterruptHandler:self.
   958 
   980 
   959     "Modified: / 7.1.1997 / 16:48:26 / stefan"
   981     "Modified: / 7.1.1997 / 16:48:26 / stefan"
   960     "Modified: / 4.2.1999 / 13:08:39 / cg"
   982     "Modified: / 4.2.1999 / 13:08:39 / cg"
   961 !
   983 !
   962 
   984 
  1016     <context: #return>
  1038     <context: #return>
  1017 
  1039 
  1018     |index pri aProcess l|
  1040     |index pri aProcess l|
  1019 
  1041 
  1020     OperatingSystem interruptsBlocked ifFalse:[
  1042     OperatingSystem interruptsBlocked ifFalse:[
  1021         MiniDebugger
  1043 	MiniDebugger
  1022             enterWithMessage:'vmResumeInterrupt with no interruptsBlocked'
  1044 	    enterWithMessage:'vmResumeInterrupt with no interruptsBlocked'
  1023             mayProceed:true.
  1045 	    mayProceed:true.
  1024     ].
  1046     ].
  1025 
  1047 
  1026     index := KnownProcessIds identityIndexOf:id.
  1048     index := KnownProcessIds identityIndexOf:id.
  1027     index ~~ 0 ifTrue:[
  1049     index ~~ 0 ifTrue:[
  1028         aProcess := KnownProcesses at:index.
  1050 	aProcess := KnownProcesses at:index.
  1029         pri := aProcess priority.
  1051 	pri := aProcess priority.
  1030         l := quiescentProcessLists at:pri.
  1052 	l := quiescentProcessLists at:pri.
  1031         l notNil ifTrue:[
  1053 	l notNil ifTrue:[
  1032             (l includesIdentical:aProcess) ifTrue:[
  1054 	    (l includesIdentical:aProcess) ifTrue:[
  1033                 "/ aProcess is on a run queue.
  1055 		"/ aProcess is on a run queue.
  1034                 "/ CG: this situation may happen, if the wrapCall
  1056 		"/ CG: this situation may happen, if the wrapCall
  1035                 "/ finishes before the process was layed to sleep
  1057 		"/ finishes before the process was layed to sleep
  1036                 "/ (i.e. schedulerIRQ arrives before the threadSwitch was finished).
  1058 		"/ (i.e. schedulerIRQ arrives before the threadSwitch was finished).
  1037                 "/ In that case, simply resume it and everything is OK.
  1059 		"/ In that case, simply resume it and everything is OK.
  1038                 "/ If the process is state running, ignore.
  1060 		"/ If the process is state running, ignore.
  1039 
  1061 
  1040                 |state|
  1062 		|state|
  1041 
  1063 
  1042                 state := aProcess state.
  1064 		state := aProcess state.
  1043                 (state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[
  1065 		(state == #wrapWait or:[(state == #osWait) or:[state == #stopped]]) ifTrue:[
  1044                     aProcess state:#run.
  1066 		    aProcess state:#run.
  1045                 ].
  1067 		].
  1046                 'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint.
  1068 		'ProcSched [info]: resumeIRQ ignored for process: ' infoPrint.
  1047                 aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR.
  1069 		aProcess id infoPrint. ' in state: ' infoPrint. state infoPrintCR.
  1048                 ^ self
  1070 		^ self
  1049             ]
  1071 	    ]
  1050         ] ifFalse:[
  1072 	] ifFalse:[
  1051             l := LinkedList new.
  1073 	    l := LinkedList new.
  1052             quiescentProcessLists at:pri put:l.
  1074 	    quiescentProcessLists at:pri put:l.
  1053         ].
  1075 	].
  1054         l addLast:aProcess.
  1076 	l addLast:aProcess.
  1055         aProcess state:#run.
  1077 	aProcess state:#run.
  1056     ] ifFalse:[
  1078     ] ifFalse:[
  1057         'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint.
  1079 	'ProcSched [info]: resumeIRQ for unknown process: ' infoPrint.
  1058         id infoPrintCR.
  1080 	id infoPrintCR.
  1059     ]
  1081     ]
  1060 
  1082 
  1061     "Modified: / 28.9.1998 / 11:36:53 / cg"
  1083     "Modified: / 28.9.1998 / 11:36:53 / cg"
  1062 !
  1084 !
  1063 
  1085 
  1109     "child changed state - switch to scheduler process which will decide
  1131     "child changed state - switch to scheduler process which will decide
  1110      what to do now."
  1132      what to do now."
  1111 
  1133 
  1112     gotChildSignalInterrupt := true.
  1134     gotChildSignalInterrupt := true.
  1113     activeProcess ~~ scheduler ifTrue:[
  1135     activeProcess ~~ scheduler ifTrue:[
  1114 	interruptedProcess := activeProcess.
  1136         interruptCounter := (interruptCounter + 1 bitAnd:16r3FFFFFFF).
  1115 	self threadSwitch:scheduler
  1137         interruptedProcess := activeProcess.
       
  1138         self threadSwitch:scheduler
  1116     ]
  1139     ]
  1117 
  1140 
  1118     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1141     "Modified: 12.4.1996 / 10:12:18 / stefan"
  1119 !
  1142 !
  1120 
  1143 
  1540     wasBlocked := OperatingSystem blockInterrupts.
  1563     wasBlocked := OperatingSystem blockInterrupts.
  1541 
  1564 
  1542     listArray := quiescentProcessLists.
  1565     listArray := quiescentProcessLists.
  1543 
  1566 
  1544     [prio >= 1] whileTrue:[
  1567     [prio >= 1] whileTrue:[
  1545         l := listArray at:prio.
  1568 	l := listArray at:prio.
  1546         l notNil ifTrue:[
  1569 	l notNil ifTrue:[
  1547             l linksDo:[:aProcess |
  1570 	    l linksDo:[:aProcess |
  1548                 aProcess isUserProcess ifTrue:[
  1571 		aProcess isUserProcess ifTrue:[
  1549                     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1572 		    wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1550                     ^ true.
  1573 		    ^ true.
  1551                 ]
  1574 		]
  1552             ]
  1575 	    ]
  1553         ].
  1576 	].
  1554         prio := prio - 1
  1577 	prio := prio - 1
  1555     ].
  1578     ].
  1556 
  1579 
  1557     "/ any user process waiting on a sema?
  1580     "/ any user process waiting on a sema?
  1558     (readSemaphoreArray contains:[:sema | 
  1581     (readSemaphoreArray contains:[:sema |
  1559         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1582 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1560     ) ifTrue:[
  1583     ) ifTrue:[
  1561         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1584 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1562         ^ true.
  1585 	^ true.
  1563     ].
  1586     ].
  1564     (writeSemaphoreArray contains:[:sema | 
  1587     (writeSemaphoreArray contains:[:sema |
  1565         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1588 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1566     ) ifTrue:[
  1589     ) ifTrue:[
  1567         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1590 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1568         ^ true.
  1591 	^ true.
  1569     ].
  1592     ].
  1570     (timeoutSemaphoreArray contains:[:sema | 
  1593     (timeoutSemaphoreArray contains:[:sema |
  1571         sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1594 	sema notNil and:[sema waitingProcesses contains:[:p | p notNil and:[p isUserProcess] ]]]
  1572     ) ifTrue:[
  1595     ) ifTrue:[
  1573         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1596 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1574         ^ true.
  1597 	^ true.
  1575     ].
  1598     ].
  1576     (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ]
  1599     (timeoutProcessArray contains:[:p | p notNil and:[p isUserProcess] ]
  1577     ) ifTrue:[
  1600     ) ifTrue:[
  1578         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1601 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1579         ^ true.
  1602 	^ true.
  1580     ].
  1603     ].
  1581 
  1604 
  1582     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1605     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  1583     ^ false
  1606     ^ false
  1584 
  1607 
  2321     |idx "{ Class: SmallInteger }"
  2344     |idx "{ Class: SmallInteger }"
  2322      wasBlocked sema|
  2345      wasBlocked sema|
  2323 
  2346 
  2324     wasBlocked := OperatingSystem blockInterrupts.
  2347     wasBlocked := OperatingSystem blockInterrupts.
  2325     useIOInterrupts ifTrue:[
  2348     useIOInterrupts ifTrue:[
  2326         OperatingSystem disableIOInterruptsOn:aFileDescriptor.
  2349 	OperatingSystem disableIOInterruptsOn:aFileDescriptor.
  2327     ].
  2350     ].
  2328 
  2351 
  2329     idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2352     idx := readFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2330     [idx ~~ 0] whileTrue:[
  2353     [idx ~~ 0] whileTrue:[
  2331         readFdArray at:idx put:nil.
  2354 	readFdArray at:idx put:nil.
  2332         readCheckArray at:idx put:nil.
  2355 	readCheckArray at:idx put:nil.
  2333         (sema := readSemaphoreArray at:idx) notNil ifTrue:[
  2356 	(sema := readSemaphoreArray at:idx) notNil ifTrue:[
  2334             readSemaphoreArray at:idx put:nil.
  2357 	    readSemaphoreArray at:idx put:nil.
  2335             doSignal ifTrue:[
  2358 	    doSignal ifTrue:[
  2336                 sema signalForAll.
  2359 		sema signalForAll.
  2337             ].
  2360 	    ].
  2338         ].
  2361 	].
  2339         idx := readFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2362 	idx := readFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2340     ].
  2363     ].
  2341     idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2364     idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2342     [idx ~~ 0] whileTrue:[
  2365     [idx ~~ 0] whileTrue:[
  2343         writeFdArray at:idx put:nil.
  2366 	writeFdArray at:idx put:nil.
  2344         writeCheckArray at:idx put:nil.
  2367 	writeCheckArray at:idx put:nil.
  2345         (sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  2368 	(sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  2346             writeSemaphoreArray at:idx put:nil.
  2369 	    writeSemaphoreArray at:idx put:nil.
  2347             doSignal ifTrue:[
  2370 	    doSignal ifTrue:[
  2348                 sema signalForAll.
  2371 		sema signalForAll.
  2349             ].
  2372 	    ].
  2350         ].
  2373 	].
  2351         idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2374 	idx := writeFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2352     ].
  2375     ].
  2353     idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2376     idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:1.
  2354     [idx ~~ 0] whileTrue:[
  2377     [idx ~~ 0] whileTrue:[
  2355         exceptFdArray at:idx put:nil.
  2378 	exceptFdArray at:idx put:nil.
  2356         (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  2379 	(sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  2357             exceptSemaphoreArray at:idx put:nil.
  2380 	    exceptSemaphoreArray at:idx put:nil.
  2358             doSignal ifTrue:[
  2381 	    doSignal ifTrue:[
  2359                 sema signalForAll.
  2382 		sema signalForAll.
  2360             ].
  2383 	    ].
  2361         ].
  2384 	].
  2362         idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2385 	idx := exceptFdArray identityIndexOf:aFileDescriptor startingAt:idx+1.
  2363     ].
  2386     ].
  2364     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2387     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2365 !
  2388 !
  2366 
  2389 
  2367 disableSemaphore:aSemaphore
  2390 disableSemaphore:aSemaphore
  2371      wasBlocked fd|
  2394      wasBlocked fd|
  2372 
  2395 
  2373     wasBlocked := OperatingSystem blockInterrupts.
  2396     wasBlocked := OperatingSystem blockInterrupts.
  2374     idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2397     idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2375     [idx ~~ 0] whileTrue:[
  2398     [idx ~~ 0] whileTrue:[
  2376         useIOInterrupts ifTrue:[
  2399 	useIOInterrupts ifTrue:[
  2377             fd := readFdArray at:idx.
  2400 	    fd := readFdArray at:idx.
  2378             fd notNil ifTrue:[
  2401 	    fd notNil ifTrue:[
  2379                 OperatingSystem disableIOInterruptsOn:fd
  2402 		OperatingSystem disableIOInterruptsOn:fd
  2380             ].
  2403 	    ].
  2381         ].
  2404 	].
  2382         readFdArray at:idx put:nil.
  2405 	readFdArray at:idx put:nil.
  2383         readSemaphoreArray at:idx put:nil.
  2406 	readSemaphoreArray at:idx put:nil.
  2384         readCheckArray at:idx put:nil.
  2407 	readCheckArray at:idx put:nil.
  2385         idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2408 	idx := readSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2386     ].
  2409     ].
  2387     idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2410     idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2388     [idx ~~ 0] whileTrue:[
  2411     [idx ~~ 0] whileTrue:[
  2389         useIOInterrupts ifTrue:[
  2412 	useIOInterrupts ifTrue:[
  2390             fd := writeFdArray at:idx.
  2413 	    fd := writeFdArray at:idx.
  2391             fd notNil ifTrue:[
  2414 	    fd notNil ifTrue:[
  2392                 OperatingSystem disableIOInterruptsOn:fd
  2415 		OperatingSystem disableIOInterruptsOn:fd
  2393             ].
  2416 	    ].
  2394         ].
  2417 	].
  2395         writeFdArray at:idx put:nil.
  2418 	writeFdArray at:idx put:nil.
  2396         writeSemaphoreArray at:idx put:nil.
  2419 	writeSemaphoreArray at:idx put:nil.
  2397         writeCheckArray at:idx put:nil.
  2420 	writeCheckArray at:idx put:nil.
  2398         idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2421 	idx := writeSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2399     ].
  2422     ].
  2400     idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2423     idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2401     [idx ~~ 0] whileTrue:[
  2424     [idx ~~ 0] whileTrue:[
  2402         timeoutArray at:idx put:nil.
  2425 	timeoutArray at:idx put:nil.
  2403         timeoutSemaphoreArray at:idx put:nil.
  2426 	timeoutSemaphoreArray at:idx put:nil.
  2404         timeoutActionArray at:idx put:nil.
  2427 	timeoutActionArray at:idx put:nil.
  2405         timeoutProcessArray at:idx put:nil.
  2428 	timeoutProcessArray at:idx put:nil.
  2406         idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2429 	idx := timeoutSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2407     ].
  2430     ].
  2408     idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2431     idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:1.
  2409     [idx ~~ 0] whileTrue:[
  2432     [idx ~~ 0] whileTrue:[
  2410         exceptFdArray at:idx put:nil.
  2433 	exceptFdArray at:idx put:nil.
  2411         exceptSemaphoreArray at:idx put:nil.
  2434 	exceptSemaphoreArray at:idx put:nil.
  2412         idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2435 	idx := exceptSemaphoreArray identityIndexOf:aSemaphore startingAt:idx+1.
  2413     ].
  2436     ].
  2414     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2437     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2415 
  2438 
  2416     "Modified: 4.8.1997 / 15:19:33 / cg"
  2439     "Modified: 4.8.1997 / 15:19:33 / cg"
  2417 !
  2440 !
  2504 
  2527 
  2505     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2528     "Here we assume, that for every triple (aSemaphore, aFileDescriptor, aBlock)
  2506      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2529      aSemphore is never nil, but one of aFileDescriptor, aBlock may be nil"
  2507 
  2530 
  2508     aFileDescriptor isNil ifTrue:[
  2531     aFileDescriptor isNil ifTrue:[
  2509         idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2532 	idx := exceptSemaphoreArray identityIndexOf:aSemaphore or:nil.
  2510         idx == 0 ifTrue:[
  2533 	idx == 0 ifTrue:[
  2511             "aSemaphore is not registered yet, have to create a new slot"
  2534 	    "aSemaphore is not registered yet, have to create a new slot"
  2512             exceptFdArray := exceptFdArray copyWith:nil.
  2535 	    exceptFdArray := exceptFdArray copyWith:nil.
  2513             exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2536 	    exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2514         ] ifFalse:[
  2537 	] ifFalse:[
  2515             slot := exceptSemaphoreArray at:idx.
  2538 	    slot := exceptSemaphoreArray at:idx.
  2516             slot isNil ifTrue:[
  2539 	    slot isNil ifTrue:[
  2517                 exceptSemaphoreArray at:idx put:aSemaphore.
  2540 		exceptSemaphoreArray at:idx put:aSemaphore.
  2518             ]
  2541 	    ]
  2519         ]
  2542 	]
  2520     ] ifFalse:[
  2543     ] ifFalse:[
  2521         idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil.
  2544 	idx := exceptFdArray identityIndexOf:aFileDescriptor or:nil.
  2522         idx == 0 ifTrue:[
  2545 	idx == 0 ifTrue:[
  2523             "aFileDescriptor is not registered yet, have to create a new slot"
  2546 	    "aFileDescriptor is not registered yet, have to create a new slot"
  2524             exceptFdArray := exceptFdArray copyWith:aFileDescriptor.
  2547 	    exceptFdArray := exceptFdArray copyWith:aFileDescriptor.
  2525             exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2548 	    exceptSemaphoreArray := exceptSemaphoreArray copyWith:aSemaphore.
  2526         ] ifFalse:[
  2549 	] ifFalse:[
  2527             slot := exceptFdArray at:idx.
  2550 	    slot := exceptFdArray at:idx.
  2528             slot isNil ifTrue:[
  2551 	    slot isNil ifTrue:[
  2529                 exceptFdArray at:idx put:aFileDescriptor.
  2552 		exceptFdArray at:idx put:aFileDescriptor.
  2530                 exceptSemaphoreArray at:idx put:aSemaphore.
  2553 		exceptSemaphoreArray at:idx put:aSemaphore.
  2531             ].
  2554 	    ].
  2532         ].
  2555 	].
  2533 "/        (useIOInterrupts and:[slot isNil]) ifTrue:[
  2556 "/        (useIOInterrupts and:[slot isNil]) ifTrue:[
  2534 "/            OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2557 "/            OperatingSystem enableIOInterruptsOn:aFileDescriptor
  2535 "/        ].
  2558 "/        ].
  2536     ].
  2559     ].
  2537     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2560     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  2993      n "{ Class: SmallInteger }"
  3016      n "{ Class: SmallInteger }"
  2994      indexOfLastTimeout "{ Class: SmallInteger }"
  3017      indexOfLastTimeout "{ Class: SmallInteger }"
  2995      halfSize "{ Class: SmallInteger }"
  3018      halfSize "{ Class: SmallInteger }"
  2996      wasBlocked p|
  3019      wasBlocked p|
  2997 
  3020 
  2998 
       
  2999     anyTimeouts ifFalse:[ ^ self].
  3021     anyTimeouts ifFalse:[ ^ self].
  3000     anyTimeouts := false.
  3022     anyTimeouts := false.
  3001 
  3023 
  3002     "have to collect the blocks first, then evaluate them.
  3024     "have to collect the blocks first, then evaluate them.
  3003      This avoids problems due to newly inserted blocks."
  3025      This avoids problems due to newly inserted blocks."
  3011     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3033     "/ looks ugly, but as this is called very often, reduces idle allocation by a lot.
  3012 
  3034 
  3013     now := OperatingSystem getMillisecondTime.
  3035     now := OperatingSystem getMillisecondTime.
  3014     n := timeoutArray size.
  3036     n := timeoutArray size.
  3015     1 to:n do:[:index |
  3037     1 to:n do:[:index |
  3016 	aTime := timeoutArray at:index.
  3038         aTime := timeoutArray at:index.
  3017 	aTime notNil ifTrue:[
  3039         aTime notNil ifTrue:[
  3018 	    (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[
  3040             (OperatingSystem millisecondTime:now isAfter:aTime) ifTrue:[
  3019 		"this one should be triggered"
  3041                 "this one should be triggered"
  3020 
  3042 
  3021 		sema := timeoutSemaphoreArray at:index.
  3043                 sema := timeoutSemaphoreArray at:index.
  3022 		sema notNil ifTrue:[
  3044                 sema notNil ifTrue:[
  3023 		    timeoutSemaphoreArray at:index put:nil.
  3045                     timeoutSemaphoreArray at:index put:nil.
  3024 		    sema signalOnce.
  3046                     timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF).
  3025 		] ifFalse:[
  3047                     sema signalOnce.
  3026 		    "to support pure-events"
  3048                 ] ifFalse:[
  3027 		    block := timeoutActionArray at:index.
  3049                     "to support pure-events"
  3028 		    block notNil ifTrue:[
  3050                     block := timeoutActionArray at:index.
  3029 			firstBlockToEvaluate isNil ifTrue:[
  3051                     block notNil ifTrue:[
  3030 			    firstBlockToEvaluate := block.
  3052                         "/ usually (>99%), there is only one single timeout action to call;
  3031 			    firstProcess := timeoutProcessArray at:index.
  3053                         "/ avoid creation of an OrderedCollection 
  3032 			] ifFalse:[
  3054                         firstBlockToEvaluate isNil ifTrue:[
  3033 			    blocksAndProcessesToEvaluate isNil ifTrue:[
  3055                             firstBlockToEvaluate := block.
  3034 				blocksAndProcessesToEvaluate := OrderedCollection
  3056                             firstProcess := timeoutProcessArray at:index.
  3035 								    with:firstBlockToEvaluate
  3057                         ] ifFalse:[
  3036 								    with:firstProcess.
  3058                             blocksAndProcessesToEvaluate isNil ifTrue:[
  3037 			    ].
  3059                                 blocksAndProcessesToEvaluate := OrderedCollection
  3038 			    blocksAndProcessesToEvaluate add:block.
  3060                                                                     with:firstBlockToEvaluate
  3039 			    blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index).
  3061                                                                     with:firstProcess.
  3040 			].
  3062                             ].
  3041 			timeoutActionArray at:index put:nil.
  3063                             blocksAndProcessesToEvaluate add:block.
  3042 			timeoutProcessArray at:index put:nil.
  3064                             blocksAndProcessesToEvaluate add:(timeoutProcessArray at:index).
  3043 		    ]
  3065                         ].
  3044 		].
  3066                         timeoutActionArray at:index put:nil.
  3045 		timeoutArray at:index put:nil.
  3067                         timeoutProcessArray at:index put:nil.
  3046 	    ] ifFalse:[
  3068                     ]
  3047 		"there are still pending timeouts"
  3069                 ].
  3048 		anyTimeouts := true.
  3070                 timeoutArray at:index put:nil.
  3049 		indexOfLastTimeout := index.
  3071             ] ifFalse:[
  3050 	    ]
  3072                 "there are still pending timeouts"
  3051 	]
  3073                 anyTimeouts := true.
       
  3074                 indexOfLastTimeout := index.
       
  3075             ]
       
  3076         ]
  3052     ].
  3077     ].
  3053 
  3078 
  3054     "shrink the arrays, if they are 50% free"
  3079     "shrink the arrays, if they are 50% free"
  3055     n > 20 ifTrue:[
  3080     n > 20 ifTrue:[
  3056 	halfSize := n // 2.
  3081         halfSize := n // 2.
  3057 	indexOfLastTimeout < halfSize ifTrue:[
  3082         indexOfLastTimeout < halfSize ifTrue:[
  3058 	    wasBlocked := OperatingSystem blockInterrupts.
  3083             wasBlocked := OperatingSystem blockInterrupts.
  3059 	    (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[   "/ no new timeouts arrived
  3084             (timeoutArray at:indexOfLastTimeout+1) isNil ifTrue:[   "/ no new timeouts arrived
  3060 		timeoutArray := timeoutArray copyTo:halfSize.
  3085                 timeoutArray := timeoutArray copyTo:halfSize.
  3061 		timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3086                 timeoutSemaphoreArray := timeoutSemaphoreArray copyTo:halfSize.
  3062 		timeoutActionArray := timeoutActionArray copyTo:halfSize.
  3087                 timeoutActionArray := timeoutActionArray copyTo:halfSize.
  3063 		timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
  3088                 timeoutProcessArray := timeoutProcessArray copyTo:halfSize.
  3064 	    ].
  3089             ].
  3065 	    wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
  3090             wasBlocked ifFalse:[ OperatingSystem unblockInterrupts ].
  3066 	].
  3091         ].
  3067     ].
  3092     ].
  3068 
  3093 
       
  3094     "/ usually (>99%), there is only one single timeout action to call;
       
  3095     "/ above code avoided the creation of an OrderedCollection 
  3069     blocksAndProcessesToEvaluate isNil ifTrue:[
  3096     blocksAndProcessesToEvaluate isNil ifTrue:[
  3070 	firstBlockToEvaluate notNil ifTrue:[
  3097         firstBlockToEvaluate notNil ifTrue:[
  3071 	    (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3098             timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF).
  3072 		firstBlockToEvaluate value
  3099             (firstProcess isNil or:[firstProcess == scheduler or:[PureEventDriven]]) ifTrue:[
  3073 	    ] ifFalse:[
  3100                 firstBlockToEvaluate value
  3074 		firstProcess isDead ifTrue:[
  3101             ] ifFalse:[
  3075 		    "/ a timedBlock for a process which has already terminated
  3102                 firstProcess isDead ifTrue:[
  3076 		    "/ issue a warning and do not execute it.
  3103                     "/ a timedBlock for a process which has already terminated
  3077 		    "/ (exeuting here may be dangerous, since it would run at scheduler priority here,
  3104                     "/ issue a warning and do not execute it.
  3078 		    "/  and thereby could block the whole smalltalk system.
  3105                     "/ (exeuting here may be dangerous, since it would run at scheduler priority here,
  3079 		    "/  For this reason is it IGNORED here.)
  3106                     "/  and thereby could block the whole smalltalk system.
       
  3107                     "/  For this reason is it IGNORED here.)
  3080 "/ Could handle it in timeoutProcess, but we don't,
  3108 "/ Could handle it in timeoutProcess, but we don't,
  3081 "/ because otherwise timeouts might be reissued forever...
  3109 "/ because otherwise timeouts might be reissued forever...
  3082 "/                    (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3110 "/                    (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3083 "/                        timeoutHandlerProcess interruptWith:block.
  3111 "/                        timeoutHandlerProcess interruptWith:block.
  3084 "/                    ] ifFalse:[
  3112 "/                    ] ifFalse:[
  3085 			('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , firstProcess name , '''') infoPrintCR.
  3113                         ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , firstProcess name , '''') infoPrintCR.
  3086 			('ProcessorScheduler [warning]: the timedBlock is: ' , firstBlockToEvaluate displayString) infoPrintCR.
  3114                         ('ProcessorScheduler [warning]: the timedBlock is: ' , firstBlockToEvaluate displayString) infoPrintCR.
  3087 "/                    ].
  3115 "/                    ].
  3088 		] ifFalse:[
  3116                 ] ifFalse:[
  3089 		    firstProcess interruptWith:firstBlockToEvaluate
  3117                     firstProcess interruptWith:firstBlockToEvaluate
  3090 		]
  3118                 ]
  3091 	    ]
  3119             ]
  3092 	].
  3120         ].
  3093     ] ifFalse:[
  3121     ] ifFalse:[
  3094 	n := blocksAndProcessesToEvaluate size.
  3122         n := blocksAndProcessesToEvaluate size.
  3095 	1 to:n by:2 do:[:index |
  3123         1 to:n by:2 do:[:index |
  3096 	    block := blocksAndProcessesToEvaluate at:index.
  3124             timedActionCounter := (timedActionCounter + 1 bitAnd:16r3FFFFFFF).
  3097 	    p := blocksAndProcessesToEvaluate at:index+1.
  3125             block := blocksAndProcessesToEvaluate at:index.
  3098 	    (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[
  3126             p := blocksAndProcessesToEvaluate at:index+1.
  3099 		block value
  3127             (p isNil or:[p == scheduler or:[PureEventDriven]]) ifTrue:[
  3100 	    ] ifFalse:[
  3128                 "/ 'irq*: ' infoPrint. block infoPrintCR.
  3101 		p isDead ifTrue:[
  3129                 block value
  3102 		    "/ a timedBlock for a process which has already terminated
  3130             ] ifFalse:[
  3103 		    "/ issue a warning and do not execute it.
  3131                 p isDead ifTrue:[
  3104 		    "/ (exeuting here may be dangerous, since it would run at scheduler priority here,
  3132                     "/ see comment above
  3105 		    "/  and thereby could block the whole smalltalk system.
  3133                     ('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , p name , '''') infoPrintCR.
  3106 		    "/  For this reason is it IGNORED here.)
  3134                     ('ProcessorScheduler [warning]: the timedBlock is: ' , block displayString) infoPrintCR.
  3107 "/ Could handle it in timeoutProcess, but we don't,
  3135                 ] ifFalse:[
  3108 "/ because otherwise timeouts might be reissued forever...
  3136                     p interruptWith:block.
  3109 "/                    (timeoutHandlerProcess notNil and:[timeoutHandlerProcess isDead not]) ifTrue:[
  3137                     "/ 'irq: ' infoPrint. block infoPrintCR.
  3110 "/                        timeoutHandlerProcess interruptWith:block.
  3138                 ]
  3111 "/                    ] ifFalse:[
  3139             ]
  3112 			('ProcessorScheduler [warning]: cannot evaluate timedBlock for dead process: ''' , p name , '''') infoPrintCR.
  3140         ]
  3113 			('ProcessorScheduler [warning]: the timedBlock is: ' , block displayString) infoPrintCR.
       
  3114 "/                    ].
       
  3115 		] ifFalse:[
       
  3116 		    p interruptWith:block
       
  3117 		]
       
  3118 	    ]
       
  3119 	]
       
  3120     ].
  3141     ].
  3121 
  3142 
  3122     "Modified: / 30-07-2013 / 19:33:24 / cg"
  3143     "Modified: / 30-07-2013 / 19:33:24 / cg"
  3123 !
  3144 !
  3124 
  3145 
  3173     |index "{ Class: SmallInteger }"
  3194     |index "{ Class: SmallInteger }"
  3174      wasBlocked|
  3195      wasBlocked|
  3175 
  3196 
  3176     index := anID.
  3197     index := anID.
  3177     (anID notNil and:[index > 0]) ifTrue:[
  3198     (anID notNil and:[index > 0]) ifTrue:[
  3178         wasBlocked := OperatingSystem blockInterrupts.
  3199 	wasBlocked := OperatingSystem blockInterrupts.
  3179 
  3200 
  3180         (aBlockOrSemaphore notNil 
  3201 	(aBlockOrSemaphore notNil
  3181           and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore
  3202 	  and:[(timeoutActionArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore
  3182           and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[
  3203 	  and:[(timeoutSemaphoreArray at:index ifAbsent:[]) ~~ aBlockOrSemaphore]]) ifTrue:[
  3183             'Processor: trying to remove stale timeout id - ignored' errorPrintCR.
  3204 	    'Processor: trying to remove stale timeout id - ignored' errorPrintCR.
  3184         ] ifFalse:[
  3205 	] ifFalse:[
  3185             timeoutArray at:index put:nil.
  3206 	    timeoutArray at:index put:nil.
  3186             timeoutActionArray at:index put:nil.
  3207 	    timeoutActionArray at:index put:nil.
  3187             timeoutSemaphoreArray at:index put:nil.
  3208 	    timeoutSemaphoreArray at:index put:nil.
  3188             timeoutProcessArray at:index put:nil.
  3209 	    timeoutProcessArray at:index put:nil.
  3189         ].
  3210 	].
  3190 
  3211 
  3191         wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3212 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
  3192     ]
  3213     ]
  3193 !
  3214 !
  3194 
  3215 
  3195 timeoutHandlerProcess
  3216 timeoutHandlerProcess
  3196     (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[
  3217     (timeoutHandlerProcess isNil or:[timeoutHandlerProcess isDead]) ifTrue:[
  3214     "Modified: / 20-07-2006 / 09:52:27 / cg"
  3235     "Modified: / 20-07-2006 / 09:52:27 / cg"
  3215 !
  3236 !
  3216 
  3237 
  3217 timeoutHandlerProcessLoop
  3238 timeoutHandlerProcessLoop
  3218     "The timeoutHandlerProcess does nothing but wait.
  3239     "The timeoutHandlerProcess does nothing but wait.
  3219      It exists only, so that timeout blocks may be executed in its context."
  3240      It exists only, so that timeout blocks may be executed in its context
       
  3241      (i.e. it will always just wait forever, and perform timeout actions
       
  3242      in it's interrupt handler)."
  3220 
  3243 
  3221     [
  3244     [
  3222 	[
  3245         [
  3223 	    (Semaphore new name:'timeoutHandler') wait.
  3246             (Semaphore new name:'timeoutHandler') wait.
  3224 	] on:Exception do:[:ex|
  3247         ] on:Exception do:[:ex|
  3225 	    "ignore errors, but tell the user"
  3248             "ignore errors, but tell the user"
  3226 	    InfoPrinting == true ifTrue:[
  3249             InfoPrinting == true ifTrue:[
  3227 		('ProcessorScheduler [warning]: error while handling timeouts in TimeoutHandlerProcess: ''' , ex description , '''') infoPrintCR.
  3250                 ('ProcessorScheduler [warning]: error while handling timeouts in TimeoutHandlerProcess: ''' , ex description , '''') infoPrintCR.
  3228 		thisContext fullPrintAll.
  3251                 thisContext fullPrintAll.
  3229 	    ].
  3252             ].
  3230 	].
  3253         ].
  3231     ] loop.
  3254     ] loop.
  3232 ! !
  3255 ! !
  3233 
  3256 
  3234 !ProcessorScheduler methodsFor:'wait hooks'!
  3257 !ProcessorScheduler methodsFor:'wait hooks'!
  3235 
  3258 
  3277 
  3300 
  3278     wasBlocked := OperatingSystem unblockInterrupts.
  3301     wasBlocked := OperatingSystem unblockInterrupts.
  3279 
  3302 
  3280     newProcessMaybeReady := false.
  3303     newProcessMaybeReady := false.
  3281     readableResultFdArray size < readFdArray size ifTrue:[
  3304     readableResultFdArray size < readFdArray size ifTrue:[
  3282         readableResultFdArray := Array new:(40 max:readFdArray size).
  3305 	readableResultFdArray := Array new:(40 max:readFdArray size).
  3283     ].
  3306     ].
  3284     writableResultFdArray size < writeFdArray size ifTrue:[
  3307     writableResultFdArray size < writeFdArray size ifTrue:[
  3285         writableResultFdArray := Array new:(40 max:writeFdArray size).
  3308 	writableResultFdArray := Array new:(40 max:writeFdArray size).
  3286     ].
  3309     ].
  3287 
  3310 
  3288     exceptArray := exceptFdArray.
  3311     exceptArray := exceptFdArray.
  3289 
  3312 
  3290     OperatingSystem isMSWINDOWSlike ifTrue:[
  3313     OperatingSystem isMSWINDOWSlike ifTrue:[
  3291         "/
  3314 	"/
  3292         "/ win32 does a WaitForMultipleObjects in select...
  3315 	"/ win32 does a WaitForMultipleObjects in select...
  3293         "/ unix waits for SIGCHLD
  3316 	"/ unix waits for SIGCHLD
  3294         "/
  3317 	"/
  3295         |hasPids|
  3318 	|hasPids|
  3296 
  3319 
  3297         hasPids := false.
  3320 	hasPids := false.
  3298         osChildExitActions keysDo:[:eachPid|
  3321 	osChildExitActions keysDo:[:eachPid|
  3299             eachPid address = 0 ifTrue:[
  3322 	    eachPid address = 0 ifTrue:[
  3300                 'Processor: remove 0-handle pid: ' infoPrint. eachPid infoPrintCR.
  3323 		'Processor: remove 0-handle pid: ' infoPrint. eachPid infoPrintCR.
  3301                 osChildExitActions safeRemoveKey:eachPid.
  3324 		osChildExitActions safeRemoveKey:eachPid.
  3302             ] ifFalse:[
  3325 	    ] ifFalse:[
  3303                 hasPids := true.
  3326 		hasPids := true.
  3304             ].
  3327 	    ].
  3305         ].
  3328 	].
  3306         hasPids ifTrue:[
  3329 	hasPids ifTrue:[
  3307             exceptArray := (exceptArray upTo:nil), osChildExitActions keys asArray.
  3330 	    exceptArray := (exceptArray upTo:nil), osChildExitActions keys asArray.
  3308 "/'exceptArray: ' print. exceptArray printCR.
  3331 "/'exceptArray: ' print. exceptArray printCR.
  3309         ].
  3332 	].
  3310     ].
  3333     ].
  3311 
  3334 
  3312     exceptResultFdArray size < exceptArray size ifTrue:[
  3335     exceptResultFdArray size < exceptArray size ifTrue:[
  3313         exceptResultFdArray := Array new:(40 max:exceptArray size).
  3336 	exceptResultFdArray := Array new:(40 max:exceptArray size).
  3314     ].
  3337     ].
  3315 
  3338 
  3316     nReady := OperatingSystem
  3339     nReady := OperatingSystem
  3317                 selectOnAnyReadable:readFdArray
  3340 		selectOnAnyReadable:readFdArray
  3318                 writable:writeFdArray
  3341 		writable:writeFdArray
  3319                 exception:exceptArray
  3342 		exception:exceptArray
  3320                 readableInto:readableResultFdArray
  3343 		readableInto:readableResultFdArray
  3321                 writableInto:writableResultFdArray
  3344 		writableInto:writableResultFdArray
  3322                 exceptionInto:exceptResultFdArray
  3345 		exceptionInto:exceptResultFdArray
  3323                 withTimeOut:millis.
  3346 		withTimeOut:millis.
  3324 
  3347 
  3325     wasBlocked ifTrue:[
  3348     wasBlocked ifTrue:[
  3326         OperatingSystem blockInterrupts.
  3349 	OperatingSystem blockInterrupts.
  3327     ].
  3350     ].
  3328 
  3351 
  3329     nReady <= 0 ifTrue:[
  3352     nReady <= 0 ifTrue:[
  3330         "/ either still nothing to do,
  3353 	"/ either still nothing to do,
  3331         "/ or error (which should not happen)
  3354 	"/ or error (which should not happen)
  3332 
  3355 
  3333         (nReady < 0 and:[(err := OperatingSystem lastErrorSymbol) notNil]) ifTrue:[
  3356 	(nReady < 0 and:[(err := OperatingSystem lastErrorSymbol) notNil]) ifTrue:[
  3334             err == #EBADF ifTrue:[
  3357 	    err == #EBADF ifTrue:[
  3335                 "/ mhmh - one of the fd's given to me is corrupt.
  3358 		"/ mhmh - one of the fd's given to me is corrupt.
  3336                 "/ find out which one .... and remove it
  3359 		"/ find out which one .... and remove it
  3337                 self removeCorruptedFds
  3360 		self removeCorruptedFds
  3338             ] ifFalse:[
  3361 	    ] ifFalse:[
  3339                 err == #ENOENT ifTrue:[
  3362 		err == #ENOENT ifTrue:[
  3340                     'Processor [warning]: ENOENT in select; rd=' infoPrint.
  3363 		    'Processor [warning]: ENOENT in select; rd=' infoPrint.
  3341                     readFdArray infoPrint. ' wr=' infoPrint. writeFdArray infoPrintCR.
  3364 		    readFdArray infoPrint. ' wr=' infoPrint. writeFdArray infoPrintCR.
  3342                 ] ifFalse:[
  3365 		] ifFalse:[
  3343                     'Processor [warning]: error in select: ' infoPrint. err infoPrintCR.
  3366 		    'Processor [warning]: error in select: ' infoPrint. err infoPrintCR.
  3344                 ]
  3367 		]
  3345             ].
  3368 	    ].
  3346         ]
  3369 	]
  3347     ] ifFalse:[
  3370     ] ifFalse:[
  3348         readyIndex := 1.
  3371 	readyIndex := 1.
  3349         [nReady > 0
  3372 	[nReady > 0
  3350              and:[ readyIndex <= readableResultFdArray size
  3373 	     and:[ readyIndex <= readableResultFdArray size
  3351              and:[ (fd := readableResultFdArray at:readyIndex) notNil ]]
  3374 	     and:[ (fd := readableResultFdArray at:readyIndex) notNil ]]
  3352         ] whileTrue:[
  3375 	] whileTrue:[
  3353             index := readFdArray identityIndexOf:fd.
  3376 	    index := readFdArray identityIndexOf:fd.
  3354             index ~~ 0 ifTrue:[
  3377 	    index ~~ 0 ifTrue:[
  3355                 action := readCheckArray at:index.
  3378 		action := readCheckArray at:index.
  3356                 sema := readSemaphoreArray at:index.
  3379 		sema := readSemaphoreArray at:index.
  3357                 sema notNil ifTrue:[
  3380 		sema notNil ifTrue:[
  3358                     sema signalOnce.
  3381 		    sema signalOnce.
  3359                     newProcessMaybeReady := true.
  3382 		    newProcessMaybeReady := true.
  3360                     action isNil ifTrue:[
  3383 		    action isNil ifTrue:[
  3361                         "before May 2014 we disabled the sema in the caller after wakeup.
  3384 			"before May 2014 we disabled the sema in the caller after wakeup.
  3362                          This caused ST/X to consume 100% cpu, when the caller didn't read
  3385 			 This caused ST/X to consume 100% cpu, when the caller didn't read
  3363                          the data (e.g. because his process was stopped)."
  3386 			 the data (e.g. because his process was stopped)."
  3364                         "disable possible write side and timeouts as well"
  3387 			"disable possible write side and timeouts as well"
  3365                         self disableSemaphore:sema.
  3388 			self disableSemaphore:sema.
  3366                     ].
  3389 		    ].
  3367                 ].
  3390 		].
  3368                 (action notNil and:[action value]) ifTrue:[
  3391 		(action notNil and:[action value]) ifTrue:[
  3369                     newProcessMaybeReady := true.
  3392 		    newProcessMaybeReady := true.
  3370                 ].
  3393 		].
  3371             ].
  3394 	    ].
  3372             nReady := nReady - 1.
  3395 	    nReady := nReady - 1.
  3373             readyIndex := readyIndex + 1.
  3396 	    readyIndex := readyIndex + 1.
  3374         ].
  3397 	].
  3375 
  3398 
  3376         readyIndex := 1.
  3399 	readyIndex := 1.
  3377         [nReady > 0
  3400 	[nReady > 0
  3378              and:[ readyIndex <= writableResultFdArray size
  3401 	     and:[ readyIndex <= writableResultFdArray size
  3379              and:[ (fd := writableResultFdArray at:readyIndex) notNil ]]
  3402 	     and:[ (fd := writableResultFdArray at:readyIndex) notNil ]]
  3380         ] whileTrue:[
  3403 	] whileTrue:[
  3381             index := writeFdArray identityIndexOf:fd.
  3404 	    index := writeFdArray identityIndexOf:fd.
  3382             index ~~ 0 ifTrue:[
  3405 	    index ~~ 0 ifTrue:[
  3383                 action := writeCheckArray at:index.
  3406 		action := writeCheckArray at:index.
  3384                 sema := writeSemaphoreArray at:index.
  3407 		sema := writeSemaphoreArray at:index.
  3385                 sema notNil ifTrue:[
  3408 		sema notNil ifTrue:[
  3386                     sema signalOnce.
  3409 		    sema signalOnce.
  3387                     newProcessMaybeReady := true.
  3410 		    newProcessMaybeReady := true.
  3388                     action isNil ifTrue:[
  3411 		    action isNil ifTrue:[
  3389                         "now this is a one shot operation - see the input above"
  3412 			"now this is a one shot operation - see the input above"
  3390                         "disable possible read side and timeouts as well"
  3413 			"disable possible read side and timeouts as well"
  3391                         self disableSemaphore:sema.
  3414 			self disableSemaphore:sema.
  3392                     ].
  3415 		    ].
  3393                 ].
  3416 		].
  3394                 (action notNil and:[action value]) ifTrue:[
  3417 		(action notNil and:[action value]) ifTrue:[
  3395                     newProcessMaybeReady := true.
  3418 		    newProcessMaybeReady := true.
  3396                 ].
  3419 		].
  3397             ].
  3420 	    ].
  3398             nReady := nReady - 1.
  3421 	    nReady := nReady - 1.
  3399             readyIndex := readyIndex + 1.
  3422 	    readyIndex := readyIndex + 1.
  3400         ].
  3423 	].
  3401 
  3424 
  3402 "/'except result got: ' print. exceptArray printCR. exceptResultFdArray printCR.
  3425 "/'except result got: ' print. exceptArray printCR. exceptResultFdArray printCR.
  3403         readyIndex := 1.
  3426 	readyIndex := 1.
  3404         [nReady > 0
  3427 	[nReady > 0
  3405              and:[ readyIndex <= exceptResultFdArray size
  3428 	     and:[ readyIndex <= exceptResultFdArray size
  3406              and:[ (fdOrPid := exceptResultFdArray at:readyIndex) notNil ]]
  3429 	     and:[ (fdOrPid := exceptResultFdArray at:readyIndex) notNil ]]
  3407         ] whileTrue:[
  3430 	] whileTrue:[
  3408 "/'except got: ' print. fdOrPid printCR.
  3431 "/'except got: ' print. fdOrPid printCR.
  3409             index := exceptFdArray identityIndexOf:fdOrPid.
  3432 	    index := exceptFdArray identityIndexOf:fdOrPid.
  3410             index ~~ 0 ifTrue:[
  3433 	    index ~~ 0 ifTrue:[
  3411                 sema := exceptSemaphoreArray at:index.
  3434 		sema := exceptSemaphoreArray at:index.
  3412                 sema notNil ifTrue:[
  3435 		sema notNil ifTrue:[
  3413                     sema signalOnce.
  3436 		    sema signalOnce.
  3414                     newProcessMaybeReady := true.
  3437 		    newProcessMaybeReady := true.
  3415                     "disable possible read/write side and timeouts as well"
  3438 		    "disable possible read/write side and timeouts as well"
  3416                     self disableSemaphore:sema.
  3439 		    self disableSemaphore:sema.
  3417                 ].
  3440 		].
  3418             ] ifFalse:[ "may be a PID?"
  3441 	    ] ifFalse:[ "may be a PID?"
  3419                 |osProcessStatus actionBlock|
  3442 		|osProcessStatus actionBlock|
  3420 
  3443 
  3421                 actionBlock := osChildExitActions removeKey:fdOrPid ifAbsent:nil.
  3444 		actionBlock := osChildExitActions removeKey:fdOrPid ifAbsent:nil.
  3422 "/'pid signaled: ' print. fdOrPid printCR.
  3445 "/'pid signaled: ' print. fdOrPid printCR.
  3423                 actionBlock notNil ifTrue:[
  3446 		actionBlock notNil ifTrue:[
  3424                     osProcessStatus := OperatingSystem childProcessWait:false pid:fdOrPid.
  3447 		    osProcessStatus := OperatingSystem childProcessWait:false pid:fdOrPid.
  3425                     (osProcessStatus notNil and:[osProcessStatus pid = fdOrPid]) ifTrue:[
  3448 		    (osProcessStatus notNil and:[osProcessStatus pid = fdOrPid]) ifTrue:[
  3426                         actionBlock value:osProcessStatus.
  3449 			actionBlock value:osProcessStatus.
  3427                         newProcessMaybeReady := true.
  3450 			newProcessMaybeReady := true.
  3428                     ].
  3451 		    ].
  3429                 ].
  3452 		].
  3430             ].
  3453 	    ].
  3431             nReady := nReady - 1.
  3454 	    nReady := nReady - 1.
  3432             readyIndex := readyIndex + 1.
  3455 	    readyIndex := readyIndex + 1.
  3433         ].
  3456 	].
  3434     ].
  3457     ].
  3435     ^ newProcessMaybeReady
  3458     ^ newProcessMaybeReady
  3436 
  3459 
  3437     "Modified: / 12-04-1996 / 09:31:22 / stefan"
  3460     "Modified: / 12-04-1996 / 09:31:22 / stefan"
  3438     "Modified: / 07-12-2006 / 19:48:17 / cg"
  3461     "Modified: / 07-12-2006 / 19:48:17 / cg"
  3447      Notice, that at the time of the message, we are still in the context
  3470      Notice, that at the time of the message, we are still in the context
  3448      of whichever process is currently running."
  3471      of whichever process is currently running."
  3449 
  3472 
  3450     gotIOInterrupt := true.
  3473     gotIOInterrupt := true.
  3451     activeProcess ~~ scheduler ifTrue:[
  3474     activeProcess ~~ scheduler ifTrue:[
  3452 	interruptedProcess := activeProcess.
  3475         interruptCounter := (interruptCounter + 1 bitAnd:16r3FFFFFFF).
  3453 	self threadSwitch:scheduler
  3476         interruptedProcess := activeProcess.
       
  3477         self threadSwitch:scheduler
  3454     ]
  3478     ]
  3455 
  3479 
  3456     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3480     "Modified: 21.12.1995 / 16:17:40 / stefan"
  3457     "Modified: 4.8.1997 / 14:23:08 / cg"
  3481     "Modified: 4.8.1997 / 14:23:08 / cg"
  3458 !
  3482 !
  3459 
  3483 
  3460 noMoreUserProcesses    
  3484 noMoreUserProcesses
  3461     "/ check if there are any processes at all
  3485     "/ check if there are any processes at all
  3462     "/ stop dispatching if there is none
  3486     "/ stop dispatching if there is none
  3463     "/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3487     "/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3464     "/ and no readSemaphores are present (which means that noone is waiting for input)
  3488     "/ and no readSemaphores are present (which means that noone is waiting for input)
  3465     "/ and no writeSemaphores are present
  3489     "/ and no writeSemaphores are present
  3466 
  3490 
  3467     anyTimeouts ifFalse:[
  3491     anyTimeouts ifFalse:[
  3468         ^ self anyUserProcessAtAll not.
  3492 	^ self anyUserProcessAtAll not.
  3469     ].    
  3493     ].
  3470     ^ false
  3494     ^ false
  3471 "/    |anySema|
  3495 "/    |anySema|
  3472 "/
  3496 "/
  3473 "/
  3497 "/
  3474 "/    anyTimeouts ifFalse:[
  3498 "/    anyTimeouts ifFalse:[
  3498      an #EBADF error, leading to high-frequency polling and a locked up system.
  3522      an #EBADF error, leading to high-frequency polling and a locked up system.
  3499      (you could still fix things by interrupting on the console and fixing the
  3523      (you could still fix things by interrupting on the console and fixing the
  3500       readFdArray/writeFdArray in the debugger)"
  3524       readFdArray/writeFdArray in the debugger)"
  3501 
  3525 
  3502     readFdArray keysAndValuesDo:[:idx :fd |
  3526     readFdArray keysAndValuesDo:[:idx :fd |
  3503         |result sema|
  3527 	|result sema|
  3504 
  3528 
  3505         fd notNil ifTrue:[
  3529 	fd notNil ifTrue:[
  3506             result := OperatingSystem
  3530 	    result := OperatingSystem
  3507                         selectOnAnyReadable:(Array with:fd) writable:nil exception:nil
  3531 			selectOnAnyReadable:(Array with:fd) writable:nil exception:nil
  3508                            readableInto:nil writableInto:nil exceptionInto:nil
  3532 			   readableInto:nil writableInto:nil exceptionInto:nil
  3509                            withTimeOut:0.
  3533 			   withTimeOut:0.
  3510 
  3534 
  3511             result < 0 ifTrue:[
  3535 	    result < 0 ifTrue:[
  3512                 'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3536 		'Processor [info]: removing invalid read-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3513                 readFdArray at:idx put:nil.
  3537 		readFdArray at:idx put:nil.
  3514                 readCheckArray at:idx put:nil.
  3538 		readCheckArray at:idx put:nil.
  3515                 (sema := readSemaphoreArray at:idx) notNil ifTrue:[
  3539 		(sema := readSemaphoreArray at:idx) notNil ifTrue:[
  3516                     readSemaphoreArray at:idx put:nil.
  3540 		    readSemaphoreArray at:idx put:nil.
  3517                     sema signalForAll.
  3541 		    sema signalForAll.
  3518                 ].
  3542 		].
  3519             ]
  3543 	    ]
  3520         ].
  3544 	].
  3521     ].
  3545     ].
  3522 
  3546 
  3523     writeFdArray keysAndValuesDo:[:idx :fd |
  3547     writeFdArray keysAndValuesDo:[:idx :fd |
  3524         |result sema|
  3548 	|result sema|
  3525 
  3549 
  3526         fd notNil ifTrue:[
  3550 	fd notNil ifTrue:[
  3527             result := OperatingSystem
  3551 	    result := OperatingSystem
  3528                         selectOnAnyReadable:nil writable:(Array with:fd) exception:nil
  3552 			selectOnAnyReadable:nil writable:(Array with:fd) exception:nil
  3529                            readableInto:nil writableInto:nil exceptionInto:nil
  3553 			   readableInto:nil writableInto:nil exceptionInto:nil
  3530                            withTimeOut:0.
  3554 			   withTimeOut:0.
  3531 
  3555 
  3532             result < 0 ifTrue:[
  3556 	    result < 0 ifTrue:[
  3533                 'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3557 		'Processor [info]: removing invalid write-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3534                 writeFdArray at:idx put:nil.
  3558 		writeFdArray at:idx put:nil.
  3535                 writeCheckArray at:idx put:nil.
  3559 		writeCheckArray at:idx put:nil.
  3536                 (sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  3560 		(sema := writeSemaphoreArray at:idx) notNil ifTrue:[
  3537                     writeSemaphoreArray at:idx put:nil.
  3561 		    writeSemaphoreArray at:idx put:nil.
  3538                     sema signalForAll.
  3562 		    sema signalForAll.
  3539                 ].
  3563 		].
  3540             ]
  3564 	    ]
  3541         ]
  3565 	]
  3542     ].
  3566     ].
  3543 
  3567 
  3544     exceptFdArray keysAndValuesDo:[:idx :fd |
  3568     exceptFdArray keysAndValuesDo:[:idx :fd |
  3545         |result sema|
  3569 	|result sema|
  3546 
  3570 
  3547         fd notNil ifTrue:[
  3571 	fd notNil ifTrue:[
  3548             result := OperatingSystem
  3572 	    result := OperatingSystem
  3549                         selectOnAnyReadable:nil writable:nil exception:(Array with:fd)
  3573 			selectOnAnyReadable:nil writable:nil exception:(Array with:fd)
  3550                            readableInto:nil writableInto:nil exceptionInto:nil
  3574 			   readableInto:nil writableInto:nil exceptionInto:nil
  3551                            withTimeOut:0.
  3575 			   withTimeOut:0.
  3552 
  3576 
  3553             result < 0 ifTrue:[
  3577 	    result < 0 ifTrue:[
  3554                 'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3578 		'Processor [info]: removing invalid exception-select fileDescriptor: ' infoPrint. fd infoPrint. ' idx: 'infoPrint. idx infoPrintCR.
  3555                 exceptFdArray at:idx put:nil.
  3579 		exceptFdArray at:idx put:nil.
  3556                 (sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  3580 		(sema := exceptSemaphoreArray at:idx) notNil ifTrue:[
  3557                     exceptSemaphoreArray at:idx put:nil.
  3581 		    exceptSemaphoreArray at:idx put:nil.
  3558                     sema signalForAll.
  3582 		    sema signalForAll.
  3559                 ].
  3583 		].
  3560             ]
  3584 	    ]
  3561         ]
  3585 	]
  3562     ].
  3586     ].
  3563 
  3587 
  3564 
  3588 
  3565     OperatingSystem isMSWINDOWSlike ifTrue:[
  3589     OperatingSystem isMSWINDOWSlike ifTrue:[
  3566         "/
  3590 	"/
  3567         "/ win32 does a WaitForMultipleObjects in select...
  3591 	"/ win32 does a WaitForMultipleObjects in select...
  3568         "/ unix waits for SIGCHLD
  3592 	"/ unix waits for SIGCHLD
  3569         "/
  3593 	"/
  3570         osChildExitActions keysDo:[:eachPid |
  3594 	osChildExitActions keysDo:[:eachPid |
  3571             |result sema|
  3595 	    |result sema|
  3572 
  3596 
  3573             eachPid notNil ifTrue:[
  3597 	    eachPid notNil ifTrue:[
  3574                 result := OperatingSystem
  3598 		result := OperatingSystem
  3575                             selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid)
  3599 			    selectOnAnyReadable:nil writable:nil exception:(Array with:eachPid)
  3576                                readableInto:nil writableInto:nil exceptionInto:nil
  3600 			       readableInto:nil writableInto:nil exceptionInto:nil
  3577                                withTimeOut:0.
  3601 			       withTimeOut:0.
  3578 
  3602 
  3579                 result < 0 ifTrue:[
  3603 		result < 0 ifTrue:[
  3580                     'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR.
  3604 		    'Processor [info]: removing invalid exception-select pid: ' infoPrint. eachPid infoPrintCR.
  3581                     osChildExitActions safeRemoveKey:eachPid.
  3605 		    osChildExitActions safeRemoveKey:eachPid.
  3582                 ]
  3606 		]
  3583             ]
  3607 	    ]
  3584         ].
  3608 	].
  3585     ].
  3609     ].
  3586 
  3610 
  3587     "Modified: 12.4.1996 / 09:32:58 / stefan"
  3611     "Modified: 12.4.1996 / 09:32:58 / stefan"
  3588     "Modified: 27.1.1997 / 20:09:27 / cg"
  3612     "Modified: 27.1.1997 / 20:09:27 / cg"
  3589 !
  3613 !
  3591 schedulerInterrupt
  3615 schedulerInterrupt
  3592     "forced reschedule - switch to scheduler process which will decide
  3616     "forced reschedule - switch to scheduler process which will decide
  3593      what to do now."
  3617      what to do now."
  3594 
  3618 
  3595     activeProcess ~~ scheduler ifTrue:[
  3619     activeProcess ~~ scheduler ifTrue:[
  3596 	interruptedProcess := activeProcess.
  3620         interruptCounter := (interruptCounter + 1 bitAnd:16r3FFFFFFF).
  3597 	self threadSwitch:scheduler
  3621         interruptedProcess := activeProcess.
       
  3622         self threadSwitch:scheduler
  3598     ]
  3623     ]
  3599 !
  3624 !
  3600 
  3625 
  3601 timeToNextTimeout
  3626 timeToNextTimeout
  3602     "return the delta-T (in millis) to next timeout, or nil if
  3627     "return the delta-T (in millis) to next timeout, or nil if
  3642      This method is called by the VM' interrupt handling mechanism.
  3667      This method is called by the VM' interrupt handling mechanism.
  3643      Notice, that at the time of the message, we are still in the context
  3668      Notice, that at the time of the message, we are still in the context
  3644      of whichever process is currently running."
  3669      of whichever process is currently running."
  3645 
  3670 
  3646     activeProcess ~~ scheduler ifTrue:[
  3671     activeProcess ~~ scheduler ifTrue:[
  3647 	interruptedProcess := activeProcess.
  3672         interruptCounter := (interruptCounter + 1 bitAnd:16r3FFFFFFF).
  3648 	self threadSwitch:scheduler
  3673         interruptedProcess := activeProcess.
       
  3674         self threadSwitch:scheduler
  3649     ]
  3675     ]
  3650 
  3676 
  3651     "Modified: 18.10.1996 / 20:35:54 / cg"
  3677     "Modified: 18.10.1996 / 20:35:54 / cg"
  3652 !
  3678 !
  3653 
  3679 
  3660 
  3686 
  3661     |millis doingGC dT|
  3687     |millis doingGC dT|
  3662 
  3688 
  3663     doingGC := true.
  3689     doingGC := true.
  3664     [doingGC] whileTrue:[
  3690     [doingGC] whileTrue:[
  3665         anyTimeouts ifTrue:[
  3691 	anyTimeouts ifTrue:[
  3666             millis := self timeToNextTimeout.
  3692 	    millis := self timeToNextTimeout.
  3667             (millis notNil and:[millis <= 0]) ifTrue:[
  3693 	    (millis notNil and:[millis <= 0]) ifTrue:[
  3668                 ^ self    "oops - hurry up checking"
  3694 		^ self    "oops - hurry up checking"
  3669             ].
  3695 	    ].
  3670         ].
  3696 	].
  3671 
  3697 
  3672         "
  3698 	"
  3673          if its worth doing, collect a bit of garbage;
  3699 	 if its worth doing, collect a bit of garbage;
  3674          but not, if a backgroundCollector is active
  3700 	 but not, if a backgroundCollector is active
  3675         "
  3701 	"
  3676         ObjectMemory backgroundCollectorRunning ifTrue:[
  3702 	ObjectMemory backgroundCollectorRunning ifTrue:[
  3677             doingGC := false
  3703 	    doingGC := false
  3678         ] ifFalse:[
  3704 	] ifFalse:[
  3679             doingGC := ObjectMemory gcStepIfUseful.
  3705 	    doingGC := ObjectMemory gcStepIfUseful.
  3680         ].
  3706 	].
  3681 
  3707 
  3682         "then do idle actions"
  3708 	"then do idle actions"
  3683         (idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[
  3709 	(idleActions notNil and:[idleActions size ~~ 0]) ifTrue:[
  3684             idleActions do:[:aBlock |
  3710 	    idleActions do:[:aBlock |
  3685                 aBlock value.
  3711 		aBlock value.
  3686             ].
  3712 	    ].
  3687             ^ self   "go back checking"
  3713 	    ^ self   "go back checking"
  3688         ].
  3714 	].
  3689 
  3715 
  3690         doingGC ifTrue:[
  3716 	doingGC ifTrue:[
  3691             (self checkForIOWithTimeout:0) ifTrue:[
  3717 	    (self checkForIOWithTimeout:0) ifTrue:[
  3692                 ^ self  "go back checking"
  3718 		^ self  "go back checking"
  3693             ]
  3719 	    ]
  3694         ]
  3720 	]
  3695     ].
  3721     ].
  3696 
  3722 
  3697     exitWhenNoMoreUserProcesses ifTrue:[
  3723     exitWhenNoMoreUserProcesses ifTrue:[
  3698         "/ check if there are any processes at all
  3724 	"/ check if there are any processes at all
  3699         "/ stop dispatching if there is none
  3725 	"/ stop dispatching if there is none
  3700         "/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3726 	"/ (and anyTimeouts is false, which means that no timeout blocks are present)
  3701         "/ and no readSemaphores are present (which means that noone is waiting for input)
  3727 	"/ and no readSemaphores are present (which means that noone is waiting for input)
  3702         "/ and no writeSemaphores are present
  3728 	"/ and no writeSemaphores are present
  3703 
  3729 
  3704         self noMoreUserProcesses ifTrue:[
  3730 	self noMoreUserProcesses ifTrue:[
  3705             dispatching := false.
  3731 	    dispatching := false.
  3706             ^ self
  3732 	    ^ self
  3707         ].
  3733 	].
  3708     ].
  3734     ].
  3709 
  3735 
  3710     preWaitActions notNil ifTrue:[
  3736     preWaitActions notNil ifTrue:[
  3711         preWaitActions do:[:action | action value].
  3737 	preWaitActions do:[:action | action value].
  3712     ].
  3738     ].
  3713 
  3739 
  3714     "/
  3740     "/
  3715     "/ absolutely nothing to do - simply wait
  3741     "/ absolutely nothing to do - simply wait
  3716     "/
  3742     "/
  3717     OperatingSystem supportsSelect ifFalse:[
  3743     OperatingSystem supportsSelect ifFalse:[
  3718         "SCO instant ShitStation has a bug here,
  3744 	"SCO instant ShitStation has a bug here,
  3719          waiting always 1 sec in the select - therefore we delay a bit and
  3745 	 waiting always 1 sec in the select - therefore we delay a bit and
  3720          return - effectively polling in 50ms cycles
  3746 	 return - effectively polling in 50ms cycles
  3721         "
  3747 	"
  3722         (self checkForIOWithTimeout:0) ifTrue:[
  3748 	(self checkForIOWithTimeout:0) ifTrue:[
  3723             ^ self  "go back checking"
  3749 	    ^ self  "go back checking"
  3724         ].
  3750 	].
  3725         OperatingSystem millisecondDelay:EventPollingInterval.
  3751 	OperatingSystem millisecondDelay:EventPollingInterval.
  3726         ^ self
  3752 	^ self
  3727     ].
  3753     ].
  3728 
  3754 
  3729     useIOInterrupts ifTrue:[
  3755     useIOInterrupts ifTrue:[
  3730         dT := 999999
  3756 	dT := 999999
  3731     ] ifFalse:[
  3757     ] ifFalse:[
  3732         dT := EventPollingInterval
  3758 	dT := EventPollingInterval
  3733     ].
  3759     ].
  3734 
  3760 
  3735     millis isNil ifTrue:[
  3761     millis isNil ifTrue:[
  3736         millis := dT.
  3762 	millis := dT.
  3737     ] ifFalse:[
  3763     ] ifFalse:[
  3738         millis := millis rounded min:dT.
  3764 	millis := millis rounded min:dT.
  3739     ].
  3765     ].
  3740 
  3766 
  3741     self checkForIOWithTimeout:millis
  3767     self checkForIOWithTimeout:millis
  3742 
  3768 
  3743     "Modified: 14.12.1995 / 13:37:46 / stefan"
  3769     "Modified: 14.12.1995 / 13:37:46 / stefan"