Hi Lou,<br><br><div class="gmail_quote">On Tue, Mar 5, 2013 at 2:38 PM, Louis LaBrunda <span dir="ltr"><<a href="mailto:Lou@keystone-software.com" target="_blank">Lou@keystone-software.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
I will bow to your knowledge of Squeak but take a look at the code below<br>
from VA Smalltalk.<br>
<br>
Pay special attention to #resume: which looks to me like it puts the new<br>
process at the top of the queue (there are 7 queues, one for each priority)<br>
and puts the current (activeProcess) at the bottom of the same queue and<br>
then switches to the highestPriorityProcess. Which can be another process<br>
or the new process just put in front of the current process.<br></blockquote><div><br></div><div>thanks, that's interesting, and good to know.</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Don't ask my why it works this way. As I said, I added #forkReady which it<br>
seems works more like Squeak. Most of the time I think it doesn't matter<br>
but sometimes it does.<br>
<br>
Lou<br>
<br>
fork<br>
"Create a new Process which is scheduled by the<br>
ProcessScheduler. The new process executes the receiver by<br>
sending it the message value. The new process is created<br>
with the same prority as the activeProcess. Answer the<br>
receiver."<br>
<br>
^self newProcess resume<br>
<br>
resume<br>
"Tell the process scheduler to add the process to the ready<br>
to run queue."<br>
<br>
self isResumable ifFalse: [^self error: (NlsCatKRN indexedMsg: 2)].<br>
"$NLS$ process cannot be resumed"<br>
Processor resume: self.<br>
^ self<br>
<br>
resume: aProcess<br>
<br>
| state |<br>
state := self enableAsyncMessages: false.<br>
(aProcess == self activeProcess or: [aProcess isDead]) ifTrue: [<br>
self enableAsyncMessages: state.<br>
^self "Resuming a dead process or the active process is a nop."].<br>
<br>
aProcess isRunable ifTrue: [<br>
(aProcess processState: ##ready) queue addFirst: aProcess].<br>
<br>
(self activeProcess processState: ##ready) queue addLast: self<br>
activeProcess.<br>
self activeProcess switchTo: self highestPriorityProcess.<br>
self enableAsyncMessages: state<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
<br>
On Tue, 5 Mar 2013 13:46:13 -0800, Eliot Miranda <<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>><br>
wrote:<br>
<div class="HOEnZb"><div class="h5"><br>
>On Tue, Mar 5, 2013 at 1:36 PM, Louis LaBrunda <<a href="mailto:Lou@keystone-software.com">Lou@keystone-software.com</a>>wrote:<br>
><br>
>> Hi Eliot,<br>
>><br>
>> Thanks for all the very valuable information. I think I didn't ask my<br>
>> question properly but with all the answers I was able to accomplish exactly<br>
>> what I wanted.<br>
>><br>
>> I do have a question about one thing you said. See below.<br>
>><br>
>> Lou<br>
>><br>
>> >On Thu, Feb 28, 2013 at 2:30 PM, Bert Freudenberg <<a href="mailto:bert@freudenbergs.de">bert@freudenbergs.de</a><br>
>> >wrote:<br>
>> ><br>
>> >> On 2013-02-28, at 22:38, Louis LaBrunda <Lou@Keystone-Software.com><br>
>> wrote:<br>
>> >><br>
>> >> > If a process is running when an image is saved, is the process<br>
>> stopped at<br>
>> >> > any point in particular?<br>
>> >><br>
>> >> The active process is stopped in the snapshot primitive (a.k.a. "image<br>
>> >> saving") and resumes after it on startup. All other processes are<br>
>> waiting<br>
>> >> on some semaphore anyway.<br>
>> >><br>
>> ><br>
>> >Nope. No processes are stopped. Processes are simply unable to run while<br>
>> >in the snapshot. The key to understanding this is understanding the<br>
>> >scheduler (the Processor global, an instance of ProcessorSheduler). It<br>
>> >maintains an activeProcess and a set of runnable processes, implemented as<br>
>> >an Array of lists of processes at the same priority. A runnable process<br>
>> >(one not sent suspend or not waiting on a semaphore) is either the<br>
>> >activeProcess or on one of the lists. This state is saved to the<br>
>> snapshot.<br>
>> > At any time the scheduler's activeProcess is the first highest priority<br>
>> >process in the set of runnable processes. It will only be deposed as<br>
>> >activeProcess when either another higher-priority process becomes runnable<br>
>> >or it yields or suspends or waits on a semaphore. If it suspends or waits<br>
>> >on a semaphore it is removed from the set of runnable processes. If it<br>
>> >yields it gets sent to the back of its run-queue and the next process in<br>
>> >that queue becomes the runnable process. If it is the only runnable<br>
>> >process at its priority yield is a noop.<br>
>> ><br>
>> >On loading the image the VM activates the activeProcess; the activeProcess<br>
>> >will typically be in a method that has called the snapshot primitive and<br>
>> >the system will continue, with the snapshot primitive answering true. All<br>
>> >the other processes in the run queues are runnable but, just as before the<br>
>> >snapshot, can't be run because the activeProcess is still runnable. But<br>
>> as<br>
>> >soon as the activeProcess suspends, waits or yields, one of these<br>
>> processes<br>
>> >may run.<br>
>> ><br>
>> >Several processes are terminated (terminate is suspend + run unwinds) on<br>
>> >resuming the image. This is done to inform the VM of additional state to<br>
>> >make these processes run. For example, the Delay process needs to tell<br>
>> the<br>
>> >VM what the next delay expiry is on start-up. The delay semaphore (the<br>
>> >semaphore the VM signals when the current active delay expires) is saved<br>
>> in<br>
>> >the image in the specialObjects array, so it persists across a snapshot,<br>
>> >but the VM doesn't persist the current delay expiry time.<br>
>> ><br>
>> >So any long-running process which doesn't need to inform the VM of<br>
>> anything<br>
>> >special at start-up will just keep truckin' along, and nothing need be<br>
>> >done. A snapshot really is like a fermata, a pause. It is not some kind<br>
>> >of shut-down.<br>
>> ><br>
>> >As a side-note what happens if one does<br>
>> ><br>
>> > [Semaphore new wait] fork.<br>
>> > Processor activeProcess yield.<br>
>> ><br>
>> >?<br>
>> ><br>
>> >This creates a new process and adds it to the Processor's run queue. Once<br>
>> >the process has been sent fork the current process doesn't reference it<br>
>> >since it has been popped from the current process's stack, and so the only<br>
>> >reference to the new process is from one of the Processors' run queues,<br>
>> but<br>
>> >it isn't running yet because the activeProcess (the one that sent fork) is<br>
>> >running. When the activeProcess yields the new process gets to run. Once<br>
>> >it has created the new semaphore it sends wait to it. At this point it is<br>
>> >removed from the Processor's run-queue and added to the semaphore's queue.<br>
>> > So now there is a circular reference between the process and the<br>
>> semaphore<br>
>> >and these are the only references to the process and the semaphore, and so<br>
>> >both get garbage collected.<br>
>><br>
>> I think the forked process gets to run before the processor returns to the<br>
>> yield line. This is the way it works in VA Smalltalk and from looking at<br>
>> the implementers of #fork, I think it is the way it works in Squeak. I<br>
>> could be wrong, if so please be kind, I have been following the news group<br>
>> for a while but I'm new to playing with Squeak.<br>
>><br>
><br>
>No. In Smalltalk-80 (VisualWorks, Squeak etc) fork creates a new process<br>
>with the same priority as the current process and then resumes it (resume<br>
>is the primitive that adds the process to the run queue). So the new<br>
>process is effectively behind the activeProcess in the run-queue. e.g.<br>
><br>
>| who |<br>
>who := #me.<br>
>[who := #him. Semaphore new wait] fork.<br>
>who<br>
>=> #me<br>
><br>
><br>
>| who |<br>
>who := #me.<br>
>[who := #him. Semaphore new wait] fork.<br>
>Processor yield.<br>
>who<br>
>=> #him<br>
><br>
>I can't speak for VA, but I doubt you;re right. I expect VA to have the<br>
>same behaviour as the above.<br>
><br>
><br>
><br>
>> There were times when I wanted to create a new fork but didn't want it to<br>
>> run until the method creating it finished. So, I added #forkReady (and<br>
>> friends) that would create the process but not run it right away.<br>
>><br>
><br>
>there's also forkAt: Processor activePriority - 1, or<br>
><br>
>| gate result |<br>
>gate := Semaphore new.<br>
>[gate wait.<br>
> self doStuff] fork.<br>
>result := self getResult.<br>
>gate signal.<br>
>^result<br>
><br>
><br>
>> >><br>
>> >> > If the saved image is started, is there any way the process can tell?<br>
>> >><br>
>> >> Not the process itself. But you surely keep the process in a class<br>
>> >> somewhere, and the class can arrange to get notified on startup by<br>
>> adding<br>
>> >> itself to the startup list. See addToStartUpList:.<br>
>> >><br>
>> ><br>
>> >exactly. one could also e.g. poll OSProcess to get the process ID of the<br>
>> VM<br>
>> >process and see if that changes, but that's a horrible hack, and once in a<br>
>> >blue moon will fail (cuz process ids are not unique and get reused).<br>
>> ><br>
>> >> I'm running a process that keeps running for a look time. It loops<br>
>> with a<br>
>> >> > delay and in the loop gets the date and time. If the date and time<br>
>> were<br>
>> >> > obtained just before the save, they would be old at the time of the<br>
>> image<br>
>> >> > restart and need to be refreshed.<br>
>> >><br>
>> >><br>
>> >> Delays get adjusted after resuming from snapshot. So it should just<br>
>> work.<br>
>> >><br>
>> ><br>
>> >exactly. the snapshot will look just like a long time on the run-queue<br>
>> >whole the process is preempted by higher-priroity processes,<br>
>> ><br>
>> ><br>
>> >> - Bert -<br>
>> >><br>
>> -----------------------------------------------------------<br>
>> Louis LaBrunda<br>
>> Keystone Software Corp.<br>
>> SkypeMe callto://PhotonDemon<br>
>> mailto:<a href="mailto:Lou@Keystone-Software.com">Lou@Keystone-Software.com</a> <a href="http://www.Keystone-Software.com" target="_blank">http://www.Keystone-Software.com</a><br>
>><br>
>><br>
>><br>
-----------------------------------------------------------<br>
Louis LaBrunda<br>
Keystone Software Corp.<br>
SkypeMe callto://PhotonDemon<br>
mailto:<a href="mailto:Lou@Keystone-Software.com">Lou@Keystone-Software.com</a> <a href="http://www.Keystone-Software.com" target="_blank">http://www.Keystone-Software.com</a><br>
<br>
<br>
</div></div></blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>