ProcessorScheduler.st
changeset 375 e5019c22f40e
parent 374 7eb5bedfaa1c
child 379 5b5a130ccd09
equal deleted inserted replaced
374:7eb5bedfaa1c 375:e5019c22f40e
    33 
    33 
    34 ProcessorScheduler comment:'
    34 ProcessorScheduler comment:'
    35 COPYRIGHT (c) 1993 by Claus Gittinger
    35 COPYRIGHT (c) 1993 by Claus Gittinger
    36 	     All Rights Reserved
    36 	     All Rights Reserved
    37 
    37 
    38 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.44 1995-08-05 14:05:36 claus Exp $
    38 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.45 1995-08-08 00:48:18 claus Exp $
    39 '!
    39 '!
    40 
    40 
    41 Smalltalk at:#Processor put:nil!
    41 Smalltalk at:#Processor put:nil!
    42 
    42 
    43 !ProcessorScheduler class methodsFor:'documentation'!
    43 !ProcessorScheduler class methodsFor:'documentation'!
    56 "
    56 "
    57 !
    57 !
    58 
    58 
    59 version
    59 version
    60 "
    60 "
    61 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.44 1995-08-05 14:05:36 claus Exp $
    61 $Header: /cvs/stx/stx/libbasic/ProcessorScheduler.st,v 1.45 1995-08-08 00:48:18 claus Exp $
    62 "
    62 "
    63 !
    63 !
    64 
    64 
    65 documentation
    65 documentation
    66 "
    66 "
   493 !ProcessorScheduler methodsFor:'private initializing'!
   493 !ProcessorScheduler methodsFor:'private initializing'!
   494 
   494 
   495 initialize
   495 initialize
   496     "initialize the one-and-only ProcessorScheduler"
   496     "initialize the one-and-only ProcessorScheduler"
   497 
   497 
   498     |nPrios l p|
   498     |nPrios "{ Class: SmallInteger }"
       
   499      l p|
   499 
   500 
   500     KnownProcesses isNil ifTrue:[
   501     KnownProcesses isNil ifTrue:[
   501 	KnownProcesses := WeakArray new:10.
   502 	KnownProcesses := WeakArray new:10.
   502 	KnownProcesses watcher:self class.
   503 	KnownProcesses watcher:self class.
   503 	KnownProcessIds := OrderedCollection new.
   504 	KnownProcessIds := OrderedCollection new.
   506     "
   507     "
   507      create a collection with process lists; accessed using the priority as key
   508      create a collection with process lists; accessed using the priority as key
   508     "
   509     "
   509     nPrios := SchedulingPriority.
   510     nPrios := SchedulingPriority.
   510     quiescentProcessLists := Array new:nPrios.
   511     quiescentProcessLists := Array new:nPrios.
       
   512     1 to:nPrios do:[:pri |
       
   513 	quiescentProcessLists at:pri put:(LinkedList new)
       
   514     ].
   511 
   515 
   512     readFdArray := Array with:nil.
   516     readFdArray := Array with:nil.
   513     readCheckArray := Array with:nil.
   517     readCheckArray := Array with:nil.
   514     readSemaphoreArray := Array with:nil.
   518     readSemaphoreArray := Array with:nil.
   515     writeFdArray := Array with:nil.
   519     writeFdArray := Array with:nil.
   532     p := Process new.
   536     p := Process new.
   533     p setId:0 state:#run.
   537     p setId:0 state:#run.
   534     p setPriority:currentPriority.
   538     p setPriority:currentPriority.
   535     p name:'scheduler'.
   539     p name:'scheduler'.
   536 
   540 
   537     l := LinkedList new.
       
   538     l add:p.
       
   539     scheduler := activeProcess := p.
   541     scheduler := activeProcess := p.
   540 
   542 
   541     quiescentProcessLists at:currentPriority put:l.
   543     (quiescentProcessLists at:currentPriority) add:p.
   542 
   544 
   543     "
   545     "
   544      let me handle IO and timer interrupts
   546      let me handle IO and timer interrupts
   545     "
   547     "
   546     ObjectMemory ioInterruptHandler:self.
   548     ObjectMemory ioInterruptHandler:self.
   713     l := quiescentProcessLists at:currentPriority.
   715     l := quiescentProcessLists at:currentPriority.
   714 
   716 
   715     "
   717     "
   716      debugging consistency checks - will be removed later
   718      debugging consistency checks - will be removed later
   717     "
   719     "
   718     l isNil ifTrue:[
       
   719 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
       
   720 	'oops - nil runnable list' errorPrintNL.
       
   721 	^ self
       
   722     ].
       
   723     l isEmpty ifTrue:[
   720     l isEmpty ifTrue:[
   724 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   721 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   725 	'oops - empty runnable list' errorPrintNL.
   722 	'oops - empty runnable list' errorPrintNL.
   726 	^ self
   723 	^ self
   727     ].
   724     ].
   771     wasBlocked := OperatingSystem blockInterrupts.
   768     wasBlocked := OperatingSystem blockInterrupts.
   772 
   769 
   773     pri := aProcess priority.
   770     pri := aProcess priority.
   774     l := quiescentProcessLists at:pri.
   771     l := quiescentProcessLists at:pri.
   775 
   772 
   776     "
       
   777      debugging consisteny checks - will be removed later
       
   778     "
       
   779     l isNil ifTrue:[
       
   780 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
       
   781 
       
   782 	'bad suspend: empty run list' errorPrintNL.
       
   783 	"/ MiniDebugger enterWithMessage:'bad suspend: empty run list'.
       
   784 	self threadSwitch:scheduler.
       
   785 	^ self
       
   786     ].
       
   787 
       
   788     "notice: this is slightly faster than putting the if-code into
   773     "notice: this is slightly faster than putting the if-code into
   789      the ifAbsent block, because [] is a shared cheap block
   774      the ifAbsent block, because [] is a shared cheap block
   790     "
   775     "
   791     (l remove:aProcess ifAbsent:[]) isNil ifTrue:[
   776     (l remove:aProcess ifAbsent:[]) isNil ifTrue:[
   792 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   777 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   794 	"/ MiniDebugger enterWithMessage:'bad suspend: not on run list'.
   779 	"/ MiniDebugger enterWithMessage:'bad suspend: not on run list'.
   795 	self threadSwitch:scheduler.
   780 	self threadSwitch:scheduler.
   796 	^ self
   781 	^ self
   797     ].
   782     ].
   798 
   783 
   799     l isEmpty ifTrue:[
       
   800 	quiescentProcessLists at:pri put:nil.
       
   801 	l := nil
       
   802     ].
       
   803     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   784     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   804 
   785 
   805     "
   786     "
   806      this is a bit of a kludge: allow someone else to
   787      this is a bit of a kludge: allow someone else to
   807      set the state to something like #ioWait etc.
   788      set the state to something like #ioWait etc.
   810     "
   791     "
   811     aProcess setStateTo:#suspended if:#active or:#run.
   792     aProcess setStateTo:#suspended if:#active or:#run.
   812 
   793 
   813     (aProcess == activeProcess) ifTrue:[
   794     (aProcess == activeProcess) ifTrue:[
   814 	"we can immediately switch sometimes"
   795 	"we can immediately switch sometimes"
   815 	l notNil ifTrue:[
   796 	l notEmpty ifTrue:[
   816 	    p := l first
   797 	    p := l first
   817 	] ifFalse:[
   798 	] ifFalse:[
   818 	    p := scheduler
   799 	    p := scheduler
   819 	].
   800 	].
   820 	self threadSwitch:p 
   801 	self threadSwitch:p 
   835     wasBlocked := OperatingSystem blockInterrupts.
   816     wasBlocked := OperatingSystem blockInterrupts.
   836 
   817 
   837     pri := aProcess priority.
   818     pri := aProcess priority.
   838 
   819 
   839     l := quiescentProcessLists at:pri.
   820     l := quiescentProcessLists at:pri.
   840     l isNil ifTrue:[
   821     "if already running, ignore"
   841 	l := LinkedList new.
   822     (l identityIndexOf:aProcess) ~~ 0 ifTrue:[
   842 	quiescentProcessLists at:pri put:l
   823 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   843     ] ifFalse:[
   824 	^ self
   844 	"if already running, ignore"
       
   845 	(l identityIndexOf:aProcess) ~~ 0 ifTrue:[
       
   846 	    wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
       
   847 	    ^ self
       
   848 	]
       
   849     ].
   825     ].
   850     l addLast:aProcess.
   826     l addLast:aProcess.
   851     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   827     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   852 
   828 
   853     (pri > currentPriority) ifTrue:[
   829     (pri > currentPriority) ifTrue:[
   894 
   870 
   895     "remove the process from the runnable list"
   871     "remove the process from the runnable list"
   896 
   872 
   897     pri := aProcess priority.
   873     pri := aProcess priority.
   898     l := quiescentProcessLists at:pri.
   874     l := quiescentProcessLists at:pri.
   899     (l notNil and:[(l identityIndexOf:aProcess) ~~ 0]) ifTrue:[
   875     (l identityIndexOf:aProcess) ~~ 0 ifTrue:[
   900 	l remove:aProcess.
   876 	l remove:aProcess.
   901 	l isEmpty ifTrue:[quiescentProcessLists at:pri put:nil].
       
   902     ].
   877     ].
   903     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   878     wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   904 
   879 
   905     aProcess == activeProcess ifTrue:[
   880     aProcess == activeProcess ifTrue:[
   906 	"
   881 	"
   984     wasBlocked := OperatingSystem blockInterrupts.
   959     wasBlocked := OperatingSystem blockInterrupts.
   985 
   960 
   986     aProcess setPriority:newPrio.
   961     aProcess setPriority:newPrio.
   987 
   962 
   988     oldList := quiescentProcessLists at:oldPrio.
   963     oldList := quiescentProcessLists at:oldPrio.
   989     (oldList isNil or:[(oldList identityIndexOf:aProcess) ==0]) ifTrue:[
   964     (oldList identityIndexOf:aProcess) == 0 ifTrue:[
   990 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   965 	wasBlocked ifFalse:[OperatingSystem unblockInterrupts].
   991 	^ self
   966 	^ self
   992     ].
   967     ].
   993 
   968 
   994     oldList remove:aProcess.
   969     oldList remove:aProcess.
   995     oldList isEmpty ifTrue:[quiescentProcessLists at:oldPrio put:nil].
       
   996 
   970 
   997     newList := quiescentProcessLists at:newPrio.
   971     newList := quiescentProcessLists at:newPrio.
   998     newList isNil ifTrue:[
       
   999 	newList := LinkedList new.
       
  1000 	quiescentProcessLists at:newPrio put:newList
       
  1001     ].
       
  1002     newList addLast:aProcess.
   972     newList addLast:aProcess.
  1003 
   973 
  1004     "if its the current process lowering its prio 
   974     "if its the current process lowering its prio 
  1005      or another one raising, we have to reschedule"
   975      or another one raising, we have to reschedule"
  1006 
   976 
  1057 
  1027 
  1058     prio := HighestPriority.
  1028     prio := HighestPriority.
  1059     listArray := quiescentProcessLists.
  1029     listArray := quiescentProcessLists.
  1060     [prio >= 1] whileTrue:[
  1030     [prio >= 1] whileTrue:[
  1061 	l := listArray at:prio.
  1031 	l := listArray at:prio.
  1062 	l notNil ifTrue:[
  1032 	l notEmpty ifTrue:[
  1063 	    l isEmpty ifTrue:[
  1033 	    p := l first.
  1064 		"
  1034 	    "
  1065 		 on the fly clear out empty lists
  1035 	     if it got corrupted somehow ...
  1066 		"
  1036 	    "
  1067 		listArray at:prio put:nil
  1037 	    p id isNil ifTrue:[
  1068 	    ] ifFalse:[    
  1038 		'process with nil id removed' errorPrintNL.
  1069 		p := l first.
  1039 		l removeFirst.
  1070 		"
  1040 		^ nil.
  1071 		 if it got corrupted somehow ...
       
  1072 		"
       
  1073 		p id isNil ifTrue:[
       
  1074 		    'process with nil id removed' errorPrintNL.
       
  1075 		    l removeFirst.
       
  1076 		    ^ nil.
       
  1077 		].
       
  1078 		^ p
       
  1079 	    ].
  1041 	    ].
       
  1042 	    ^ p
  1080 	].
  1043 	].
  1081 	prio := prio - 1
  1044 	prio := prio - 1
  1082     ].
  1045     ].
  1083     ^ nil
  1046     ^ nil
  1084 !
  1047 !