ProcessorScheduler.st
changeset 804 264d440a67a0
parent 786 789e2f20de44
child 806 409a8c189e01
equal deleted inserted replaced
803:7c7a4e2354b8 804:264d440a67a0
     8  be provided or otherwise made available to, or used by, any
     8  be provided or otherwise made available to, or used by, any
     9  other person.  No title to or ownership of the software is
     9  other person.  No title to or ownership of the software is
    10  hereby transferred.
    10  hereby transferred.
    11 "
    11 "
    12 
    12 
       
    13 'From Smalltalk/X, Version:2.10.8 on 21-dec-1995 at 16:28:28'                   !
       
    14 
    13 Object subclass:#ProcessorScheduler
    15 Object subclass:#ProcessorScheduler
    14 	instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess
    16 	instanceVariableNames:'quiescentProcessLists scheduler zombie activeProcess
    15 		currentPriority readFdArray readSemaphoreArray readCheckArray
    17 		currentPriority readFdArray readSemaphoreArray readCheckArray
    16 		writeFdArray writeSemaphoreArray timeoutArray timeoutActionArray
    18 		writeFdArray writeSemaphoreArray timeoutArray timeoutActionArray
    17 		timeoutProcessArray timeoutSemaphoreArray idleActions anyTimeouts
    19 		timeoutProcessArray timeoutSemaphoreArray idleActions anyTimeouts
    18 		dispatching interruptedProcess useIOInterrupts'
    20 		dispatching interruptedProcess useIOInterrupts gotIOInterrupt'
    19 	classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    21 	classVariableNames:'KnownProcesses KnownProcessIds PureEventDriven
    20 		UserSchedulingPriority UserInterruptPriority TimingPriority
    22 		UserSchedulingPriority UserInterruptPriority TimingPriority
    21 		HighestPriority SchedulingPriority MaxNumberOfProcesses'
    23 		HighestPriority SchedulingPriority MaxNumberOfProcesses'
    22 	poolDictionaries:''
    24 	poolDictionaries:''
    23 	category:'Kernel-Processes'
    25 	category:'Kernel-Processes'
   498 
   500 
   499     "
   501     "
   500      handle all timeout actions
   502      handle all timeout actions
   501     "
   503     "
   502     anyTimeouts ifTrue:[
   504     anyTimeouts ifTrue:[
   503 	self evaluateTimeouts
   505         self evaluateTimeouts
   504     ].
   506     ].
   505 
   507 
   506     "first do a quick check for semaphores using checkActions - this is needed for
   508     "first do a quick check for semaphores using checkActions - this is needed for
   507      devices like the X-connection, where some events might be in the event
   509      devices like the X-connection, where some events might be in the event
   508      queue. Without these checks, a select might block even though there is work to do
   510      queue. Without these checks, a select might block even though there is work to do
   509     "
   511     "
   510     any := false.
   512     any := false.
   511     nActions := readCheckArray size.
   513     nActions := readCheckArray size.
   512     1 to:nActions do:[:index |
   514     1 to:nActions do:[:index |
   513 	|checkBlock sema|
   515         |checkBlock sema|
   514 
   516 
   515 	checkBlock := readCheckArray at:index.
   517         checkBlock := readCheckArray at:index.
   516 	(checkBlock notNil and:[checkBlock value]) ifTrue:[
   518         (checkBlock notNil and:[checkBlock value]) ifTrue:[
   517 	    sema := readSemaphoreArray at:index.
   519             sema := readSemaphoreArray at:index.
   518 	    sema notNil ifTrue:[
   520             sema notNil ifTrue:[
   519 		sema signalOnce.
   521                 sema signalOnce.
   520 	    ].
   522             ].
   521 	    any := true.
   523             any := true.
   522 	]
   524         ]
   523     ].
   525     ].
   524 
   526 
   525     "now, someone might be runnable ..."
   527     "now, someone might be runnable ..."
   526 
   528 
   527     p := self highestPriorityRunnableProcess.
   529     p := self highestPriorityRunnableProcess.
   528     p isNil ifTrue:[
   530     p isNil ifTrue:[
   529 	"no one runnable, hard wait for event or timeout"
   531         "no one runnable, hard wait for event or timeout"
   530 
   532 
   531 	self waitForEventOrTimeout.
   533         self waitForEventOrTimeout.
   532 	^ self
   534         ^ self
   533     ].
   535     ].
   534 
   536 
   535     pri := p priority.
   537     pri := p priority.
   536 
   538 
   537     "
   539     "
   558  (a future version will have a process running to handle a timeout queue)
   560  (a future version will have a process running to handle a timeout queue)
   559 "
   561 "
   560 
   562 
   561 "
   563 "
   562     pri < TimingPriority ifTrue:[
   564     pri < TimingPriority ifTrue:[
   563 	anyTimeouts ifTrue:[
   565         anyTimeouts ifTrue:[
   564 	    millis := self timeToNextTimeout.
   566             millis := self timeToNextTimeout.
   565 	    millis == 0 ifTrue:[^ self].
   567             millis == 0 ifTrue:[^ self].
   566 	]
   568         ]
   567     ].
   569     ].
   568 "
   570 "
   569 
   571 
   570     "
   572     "
   571      if the process to run has a lower than UserInterruptPriority,
   573      if the process to run has a lower than UserInterruptPriority,
   574      or by installing a poll-interrupt after 50ms (if the OS does not).
   576      or by installing a poll-interrupt after 50ms (if the OS does not).
   575     "
   577     "
   576     pri < UserInterruptPriority ifTrue:[
   578     pri < UserInterruptPriority ifTrue:[
   577     
   579     
   578 "comment out this if above is uncommented"
   580 "comment out this if above is uncommented"
   579 	anyTimeouts ifTrue:[
   581         anyTimeouts ifTrue:[
   580 	    millis := self timeToNextTimeout.
   582             millis := self timeToNextTimeout.
   581 	    millis == 0 ifTrue:[^ self].
   583             millis == 0 ifTrue:[^ self].
   582 	].
   584         ].
   583 "---"
   585 "---"
   584 
   586 
   585 	useIOInterrupts ifTrue:[
   587         useIOInterrupts ifTrue:[
   586 	    readFdArray do:[:fd |
   588             readFdArray do:[:fd |
   587 		fd notNil ifTrue:[
   589                 fd notNil ifTrue:[
   588 		    OperatingSystem enableIOInterruptsOn:fd
   590                     OperatingSystem enableIOInterruptsOn:fd
   589 		].
   591                 ].
   590 	    ].
   592             ].
   591 	] ifFalse:[
   593         ] ifFalse:[
   592 	    millis notNil ifTrue:[
   594             millis notNil ifTrue:[
   593 		millis := millis min:50
   595                 millis := millis min:50
   594 	    ] ifFalse:[
   596             ] ifFalse:[
   595 		millis := 50
   597                 millis := 50
   596 	    ]
   598             ]
   597 	]
   599         ]
   598     ].
   600     ].
   599 
   601 
   600     millis notNil ifTrue:[
   602     millis notNil ifTrue:[
   601 	"schedule a clock interrupt after millis milliseconds"
   603         "schedule a clock interrupt after millis milliseconds"
   602 	OperatingSystem enableTimer:millis rounded.
   604         OperatingSystem enableTimer:millis rounded.
   603     ].
   605     ].
   604 
   606 
   605     "
   607     "
   606      now let the process run - will come back here by reschedule
   608      now let the process run - will come back here by reschedule
   607      from ioInterrupt or timerInterrupt ... (running at max+1)
   609      from ioInterrupt or timerInterrupt ... (running at max+1)
   608     "
   610     "
   609     self threadSwitch:p.
   611     self threadSwitch:p.
   610 
   612 
   611     "... when we arrive here, we are back on stage"
   613     "... when we arrive here, we are back on stage.
       
   614          Either by an ALARM or IO signal, or by a suspend of another process
       
   615     "
   612 
   616 
   613     millis notNil ifTrue:[
   617     millis notNil ifTrue:[
   614 	OperatingSystem disableTimer.
   618         OperatingSystem disableTimer.
   615 	useIOInterrupts ifFalse:[
   619     ].
   616 	    self checkForInputWithTimeout:0.
   620 
   617 	]
   621     "/ check for new input
       
   622 
       
   623     (gotIOInterrupt or:[useIOInterrupts not]) ifTrue:[
       
   624         gotIOInterrupt := false.
       
   625         self checkForInputWithTimeout:0.
   618     ]
   626     ]
   619 
   627 
   620     "Modified: 14.12.1995 / 14:45:13 / stefan"
   628     "Modified: 21.12.1995 / 16:21:54 / stefan"
   621 !
   629 !
   622 
   630 
   623 dispatchLoop
   631 dispatchLoop
   624     "central dispatch loop; the scheduler process is always staying in
   632     "central dispatch loop; the scheduler process is always staying in
   625      this method, looping forever."
   633      this method, looping forever."
   794 
   802 
   795     |nPrios "{ Class: SmallInteger }"
   803     |nPrios "{ Class: SmallInteger }"
   796      l p|
   804      l p|
   797 
   805 
   798     KnownProcesses isNil ifTrue:[
   806     KnownProcesses isNil ifTrue:[
   799 	KnownProcesses := WeakArray new:10.
   807         KnownProcesses := WeakArray new:10.
   800 	KnownProcesses watcher:self class.
   808         KnownProcesses watcher:self class.
   801 	KnownProcessIds := OrderedCollection new.
   809         KnownProcessIds := OrderedCollection new.
   802     ].
   810     ].
   803 
   811 
   804     "
   812     "
   805      create a collection with process lists; accessed using the priority as key
   813      create a collection with process lists; accessed using the priority as key
   806     "
   814     "
   807     nPrios := SchedulingPriority.
   815     nPrios := SchedulingPriority.
   808     quiescentProcessLists := Array new:nPrios.
   816     quiescentProcessLists := Array new:nPrios.
   809     1 to:nPrios do:[:pri |
   817     1 to:nPrios do:[:pri |
   810 	quiescentProcessLists at:pri put:(LinkedList new)
   818         quiescentProcessLists at:pri put:(LinkedList new)
   811     ].
   819     ].
   812 
   820 
   813     readFdArray := Array with:nil.
   821     readFdArray := Array with:nil.
   814     readCheckArray := Array with:nil.
   822     readCheckArray := Array with:nil.
   815     readSemaphoreArray := Array with:nil.
   823     readSemaphoreArray := Array with:nil.
   820     timeoutActionArray := Array with:nil.
   828     timeoutActionArray := Array with:nil.
   821     timeoutProcessArray := Array with:nil.
   829     timeoutProcessArray := Array with:nil.
   822     anyTimeouts := false.
   830     anyTimeouts := false.
   823     dispatching := false.
   831     dispatching := false.
   824     useIOInterrupts := OperatingSystem supportsIOInterrupts.
   832     useIOInterrupts := OperatingSystem supportsIOInterrupts.
       
   833     gotIOInterrupt := false.
   825 
   834 
   826     "
   835     "
   827      handcraft the first (dispatcher-) process - this one will never
   836      handcraft the first (dispatcher-) process - this one will never
   828      block, but go into a select if there is nothing to do.
   837      block, but go into a select if there is nothing to do.
   829      Also, it has a prio of max+1 - thus, it comes first when looking
   838      Also, it has a prio of max+1 - thus, it comes first when looking
   842     "
   851     "
   843      let me handle IO and timer interrupts
   852      let me handle IO and timer interrupts
   844     "
   853     "
   845     ObjectMemory ioInterruptHandler:self.
   854     ObjectMemory ioInterruptHandler:self.
   846     ObjectMemory timerInterruptHandler:self.
   855     ObjectMemory timerInterruptHandler:self.
       
   856 
       
   857     "Modified: 21.12.1995 / 16:18:36 / stefan"
   847 !
   858 !
   848 
   859 
   849 reinitialize
   860 reinitialize
   850     "all previous processes (except those marked as restartable) are made dead 
   861     "all previous processes (except those marked as restartable) are made dead 
   851      - each object should reinstall its process(s) upon restart;
   862      - each object should reinstall its process(s) upon restart;
  1639 
  1650 
  1640 ioInterrupt
  1651 ioInterrupt
  1641     "data arrived while waiting - switch to scheduler process which will decide 
  1652     "data arrived while waiting - switch to scheduler process which will decide 
  1642      what to do now."
  1653      what to do now."
  1643 
  1654 
       
  1655     gotIOInterrupt := true.
  1644     interruptedProcess := activeProcess.
  1656     interruptedProcess := activeProcess.
  1645     self threadSwitch:scheduler
  1657     self threadSwitch:scheduler
       
  1658 
       
  1659     "Modified: 21.12.1995 / 16:17:40 / stefan"
  1646 !
  1660 !
  1647 
  1661 
  1648 schedulerInterrupt
  1662 schedulerInterrupt
  1649     "forced reschedule - switch to scheduler process which will decide
  1663     "forced reschedule - switch to scheduler process which will decide
  1650      what to do now."
  1664      what to do now."
  1759 ! !
  1773 ! !
  1760 
  1774 
  1761 !ProcessorScheduler class methodsFor:'documentation'!
  1775 !ProcessorScheduler class methodsFor:'documentation'!
  1762 
  1776 
  1763 version
  1777 version
  1764     ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.59 1995-12-18 14:18:32 cg Exp $'
  1778     ^ '$Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.60 1995-12-21 16:56:47 stefan Exp $'
  1765 ! !
  1779 ! !
  1766 ProcessorScheduler initialize!
  1780 ProcessorScheduler initialize!