Path: utzoo!news-server.csri.toronto.edu!rutgers!dimacs.rutgers.edu!seismo!uunet!math.fu-berlin.de!uniol!unido!laura!nermal!huba From: huba@ls5.informatik.uni-dortmund.de (Hubert Baumeister) Newsgroups: comp.lang.smalltalk Subject: Re: anyone using time-sliced scheduling w/st80? Message-ID: <3095@laura.UUCP> Date: 13 Mar 91 16:32:01 GMT References: <4861@ns-mx.uiowa.edu> Sender: news@laura.UUCP Reply-To: huba@ls5.informatik.uni-dortmund.de (Hubert Baumeister) Organization: University of Dortmund, Germany Lines: 112 In article <4861@ns-mx.uiowa.edu>, csq031@umaxc.weeg.uiowa.edu writes: |> You can implement your own scheduler on top of (or beside, as it were) of |> the regular scheduler. All you have to do is to install a tick handler |> that runs at highest priority. When it resumes, check to see if the currently |> running process is one of the ones you're scheduling. If it is, and its tick |> has expired then you can suspend it and put it on your ready queue, and |> resume the process you think should run next. |> |> Better yet, study the scheduler code with the browser. You might be able |> to just wade in there and make what you want to happen happen. Be advised |> that you are guaranteed to hose the system with great frequency if you |> muck around with the scheduler very much! |> |> |> -- |> Kent Williams --- williams@umaxc.weeg.uiowa.edu |> "'Is this heaven?' --- 'No, this is Iowa'" - from the movie "Field of Dreams" |> "This isn't heaven, ... this is Cleveland" - Harry Allard, in "The Stupids Die" I have hacked a short example how time slicing could be done is the spirit of the above message. The basics is a high priority process that wakes up every few milliseconds and regroups the processes in the waiting queue of the highest priority that has more than one process. To see how it works evaluate first | queue | ProcessorScheduler stopTimeSlicing. queue := SharedQueue new. [100 timesRepeat: [queue nextPut: 1]] fork. [100 timesRepeat: [queue nextPut: 2]] fork. queue inspect In the contents of queue you will find first all the 1's and then all the 2's. If you then evaluate | queue | ProcessorScheduler startTimeSlicing. queue := SharedQueue new. [100 timesRepeat: [queue nextPut: 1]] fork. [100 timesRepeat: [queue nextPut: 2]] fork. queue inspect then the 1's and 2's are mixed. But notice that time slicing is dangerous in the current implementation of the Smalltalk user interface as shows following example: ProcessorScheduler startTimeSlicing. [100 timesRepeat: [Transcript show: 'Process 1';cr]] fork. [100 timesRepeat: [Transcript show: 'Process 2';cr]] fork. This will hang up Smalltalk because some recources are not protected against multiple access. (This is why the example above uses a SharedQueue instead of a WriteStream) The following example was written using Smalltalk Release 4.0 but it should also work on previous releases. ---------------------------- cut here --------------------------------- ProcessorScheduler class instanceVariableNames: ''! ProcessorScheduler class organization changeFromString: '(''class initialization'' #initialize) (''instance creation'' #new #new:with:) (''background process'' #background:) (''time slice process'' #example #startTimeSlicing #stopTimeSlicing) '! !ProcessorScheduler methodsFor: 'process state change'! slice "Give other Processes at the current priority a chance to run." | i list | i := self highestPriority. [i>0 and: [(quiescentProcessLists at: i) size <= 1]] whileTrue: [i := i-1]. i = 0 ifTrue: [^self]. list := (quiescentProcessLists at: i). list addLast: list removeFirst.! ! !ProcessorScheduler class methodsFor: 'time slice process'! startTimeSlicing "self startTimeSlicing" TimeSliceProcess notNil ifTrue: [^self]. TimeSliceProcess := [[true] whileTrue: [(Delay forMilliseconds: 5) wait. Processor slice]] newProcess. TimeSliceProcess priority: (Processor highestPriority). TimeSliceProcess resume.! ! !ProcessorScheduler class methodsFor: 'time slice process'! stopTimeSlicing "self stopTimeSlicing" TimeSliceProcess notNil ifTrue: [TimeSliceProcess terminate. TimeSliceProcess := nil]! ! !ProcessorScheduler class methodsFor: 'time slice process'! example "self stopTimeSlicing. self example inspect" "self startTimeSlicing. self example inspect" | queue | queue := SharedQueue new. [100 timesRepeat: [queue nextPut: 1]] fork. [100 timesRepeat: [queue nextPut: 2]] fork. ^queue! !