Process>>isSusended

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Process>>isSusended

Eliot Miranda-2
Hi All,

   we have a serious misunderstanding in current versions of Squeak's and Pharo's Process>>isSuspended.

Squeak's version reads

isSuspended
^myList isNil

Pharo's reads

isSuspended
^myList isNil or: [ myList isEmpty ]

Process's myList holds the list a process is on when it is not running.  There is only one running process at any one time, Processor activeProcess.  The active process's myList is always nil, so Squeak's and Pharo's are both wrong for the active process.

Processor activeProcess isSuspended => true (!!!)

A process may be runnable, but not running (which follows form there being only one running process, the active process, at any one time).  If it is runnable but not running its list is one of the runnable process lists in the scheduler, e.g.

Processor waitingProcessesAt: Processor activePriority => a LinkedList()
Processor waitingProcessesAt: Processor lowestPriority => a LinkedList(a Process in ProcessorScheduler class>>idleProcess)

Here's a couple of illustrative examples:

[Semaphore new wait] fork suspendingList
=> a LinkedList(a Process in [] in BlockClosure>>newProcess)

([Semaphore new wait] forkAt: Processor activePriority + 1) suspendingList
=> a Semaphore(a Process in [] in UndefinedObject>>DoIt)

In the first example above the new process isn't running yet.  It's runnable but hasn't got a chance to run because the active process that created it is still running.  So the process's list is Processor waitingProcessesAt: Processor activePriority.  In the second example the process has got to run, because, having higher priority, it has preempted the active process that created it.  So it suspends waiting on the semaphore.


So in fact, isSuspended should read something like

isSuspended
| myRunList |
myRunList := Processor waitingProcessesAt: priority.
^myList notNil and: [myList ~~ myRunList]

except that this isn't atomic. But it isn't the complete nonsense we have at the moment. Here's an atomic version that answers the truth at the point that the question was asked:

isSuspended
| myPriority |
myPriority := priority.
^myList
ifNil: [false]
ifNotNil: [:list| list ~~ (Processor waitingProcessesAt: myPriority)]

We need tests like

self deny: Processor activeProcess isSuspended.
    self deny: ([Semaphore new wait] forkAt: Processor activePriority) isSuspended.
self assert: ([Semaphore new wait] forkAt: Processor activePriority + 1) isSuspended.

_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Process>>isSusended

marcel.taeumel
Hi, Eliot.

Now there are no suspended processes anymore. :-/ I just grabbed a debugger and took its interruptedProcess. #isSuspended still returned false.

Best,
Marcel
Reply | Threaded
Open this post in threaded view
|

Re: Process>>isSusended

Eliot Miranda-2
Hi Marcel,

On Thu, Feb 18, 2016 at 1:30 PM, marcel.taeumel <[hidden email]> wrote:
Hi, Eliot.

Now there are no suspended processes anymore. :-/ I just grabbed a debugger
and took its interruptedProcess. #isSuspended still returned false.

If isSuspended means is waiting on some process list other than the runnable process lists then this is what you'd expect.  For example, the background process is not suspended.  If what yu want to test for is "runnable but not running" then you need something like

isRunnable
"A process is runnable if it is the active process or is on one of the runnable process lists."
| myPriority |
"Grab my priority now.  Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
myPriority := priority.
^myList
ifNil: [^self == Processor activeProcess]
ifNotNil: [:list| list == (Processor waitingProcessesAt: myPriority)]

In my image I have all of isRunnable, isSuspended and neither (terminated) processes

| procs |
procs := Process allInstances.
procs size -> (procs select: [:p| p isRunnable]) size -> (procs select: [:p| p isSuspended]) size -> (procs reject: [:p| p isRunnable or: [p isSuspended]]) size 19->4->6->9


So I think your issue is that you a) have no isSusoended processes; create some by e.g. opening lots of browsers so that there are background shout processes waiting on semaphores, b) collect some processes that compute something that doesn't take too long, so you've got terminated processes, and then try again.

So let's have a look at those processes above


| procs full types |
procs := Process allInstances.
types:= {procs select: [:p| p isRunnable]. procs select: [:p| p isSuspended]. procs reject: [:p| p isRunnable or: [p isSuspended]]}.
full := types collect: [:type| type collect: [:ea| ea -> (ea suspendedContext ifNil: ['Active or terminated'] ifNotNil: [:c| c stackOfSize: 5])]].
full 

"isRunnable"
{{  a Process in ProcessorScheduler class>>idleProcess->an OrderedCollection(ProcessorScheduler class>>idleProcess [] in ProcessorScheduler class>>startUp: [] in BlockClosure>>newProcess) .
    a Process in nil->'Active or terminated'} .

"isSuspended"
{a Process in Delay class>>handleTimerEvent->an OrderedCollection(Delay class>>handleTimerEvent Delay class>>runTimerEventLoop [] in Delay class>>startTimerEventLoop [] in BlockClosure>>newProcess) .
a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess) .
a Process in EventSensor>>userInterruptWatcher->an OrderedCollection(EventSensor>>userInterruptWatcher [] in EventSensor>>installInterruptWatcher [] in BlockClosure>>newProcess) .
a Process in [] in Delay>>wait->an OrderedCollection([] in Delay>>wait BlockClosure>>ifCurtailed: Delay>>wait [] in EventSensor>>eventTickler BlockClosure>>on:do:) .
a Process in WeakArray class>>finalizationProcess->an OrderedCollection(WeakArray class>>finalizationProcess [] in WeakArray class>>restartFinalizationProcess [] in BlockClosure>>newProcess) .
a Process in SmalltalkImage>>lowSpaceWatcher->an OrderedCollection(SmalltalkImage>>lowSpaceWatcher [] in SmalltalkImage>>installLowSpaceWatcher [] in BlockClosure>>newProcess) .
"this one is the styler for the pane in which I ran the doit:"
a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess)} .

"neither isRunnable notr isSuspended"
{a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in nil->'Active or terminated' .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess)}}


Hmmm, interesting.  The isRunnable and isSuspended set are exactly as I would expect.  But what are all these spawning processes?  I'll use the pointer finder to track them down.

6 of them are styler processes that have yet to start running, so presumably in browsers I've left open but have never looked at.
One of them was terminated before I could track it down.
One of them is the modalProcess in an MCMergeBrowser.
One of them is the uiProcess in a project.

So as far as I can tell the isSuspended and isRunnable definitions I mention above are fine.  Shall I commit isRunnable?


Best,
Marcel



--
View this message in context: http://forum.world.st/Process-isSusended-tp4878671p4878690.html
Sent from the Squeak - Dev mailing list archive at Nabble.com.




--
_,,,^..^,,,_
best, Eliot


Reply | Threaded
Open this post in threaded view
|

Re: Process>>isSusended

Tobias Pape
Hi,
On 19.02.2016, at 00:06, Eliot Miranda <[hidden email]> wrote:

> Hi Marcel,
>
> On Thu, Feb 18, 2016 at 1:30 PM, marcel.taeumel <[hidden email]> wrote:
> Hi, Eliot.
>
> Now there are no suspended processes anymore. :-/ I just grabbed a debugger
> and took its interruptedProcess. #isSuspended still returned false.
>
> If isSuspended means is waiting on some process list other than the runnable process lists then this is what you'd expect.  For example, the background process is not suspended.  If what yu want to test for is "runnable but not running" then you need something like
>
> isRunnable
> "A process is runnable if it is the active process or is on one of the runnable process lists."
> | myPriority |
> "Grab my priority now.  Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
> myPriority := priority.
> ^myList
> ifNil: [^self == Processor activeProcess]
> ifNotNil: [:list| list == (Processor waitingProcessesAt: myPriority)]
>
> In my image I have all of isRunnable, isSuspended and neither (terminated) processes
>
> | procs |
> procs := Process allInstances.
> procs size -> (procs select: [:p| p isRunnable]) size -> (procs select: [:p| p isSuspended]) size -> (procs reject: [:p| p isRunnable or: [p isSuspended]]) size 19->4->6->9
>
>
> So I think your issue is that you a) have no isSusoended processes; create some by e.g. opening lots of browsers so that there are background shout processes waiting on semaphores, b) collect some processes that compute something that doesn't take too long, so you've got terminated processes, and then try again.
>
> So let's have a look at those processes above
>
>
> | procs full types |
> procs := Process allInstances.
> types:= {procs select: [:p| p isRunnable]. procs select: [:p| p isSuspended]. procs reject: [:p| p isRunnable or: [p isSuspended]]}.
> full := types collect: [:type| type collect: [:ea| ea -> (ea suspendedContext ifNil: ['Active or terminated'] ifNotNil: [:c| c stackOfSize: 5])]].
> full
>
> "isRunnable"
> {{  a Process in ProcessorScheduler class>>idleProcess->an OrderedCollection(ProcessorScheduler class>>idleProcess [] in ProcessorScheduler class>>startUp: [] in BlockClosure>>newProcess) .
>     a Process in nil->'Active or terminated'} .
>
> "isSuspended"
> {a Process in Delay class>>handleTimerEvent->an OrderedCollection(Delay class>>handleTimerEvent Delay class>>runTimerEventLoop [] in Delay class>>startTimerEventLoop [] in BlockClosure>>newProcess) .
> a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess) .
> a Process in EventSensor>>userInterruptWatcher->an OrderedCollection(EventSensor>>userInterruptWatcher [] in EventSensor>>installInterruptWatcher [] in BlockClosure>>newProcess) .
> a Process in [] in Delay>>wait->an OrderedCollection([] in Delay>>wait BlockClosure>>ifCurtailed: Delay>>wait [] in EventSensor>>eventTickler BlockClosure>>on:do:) .
> a Process in WeakArray class>>finalizationProcess->an OrderedCollection(WeakArray class>>finalizationProcess [] in WeakArray class>>restartFinalizationProcess [] in BlockClosure>>newProcess) .
> a Process in SmalltalkImage>>lowSpaceWatcher->an OrderedCollection(SmalltalkImage>>lowSpaceWatcher [] in SmalltalkImage>>installLowSpaceWatcher [] in BlockClosure>>newProcess) .
> "this one is the styler for the pane in which I ran the doit:"
> a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess)} .
>
> "neither isRunnable notr isSuspended"
> {a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in nil->'Active or terminated' .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess)}}
>
>
> Hmmm, interesting.  The isRunnable and isSuspended set are exactly as I would expect.  But what are all these spawning processes?  I'll use the pointer finder to track them down.
>
> 6 of them are styler processes that have yet to start running, so presumably in browsers I've left open but have never looked at.
> One of them was terminated before I could track it down.
> One of them is the modalProcess in an MCMergeBrowser.
> One of them is the uiProcess in a project.
>
> So as far as I can tell the isSuspended and isRunnable definitions I mention above are fine.  Shall I commit isRunnable?

Just one thing:
I thought of 'isSuspended' meaning: 'this thing is not running, but it could eventually' not 'this thing cannot run because it is actively waiting for something'.
You see, if I call 'Processor yield' I'd expect the current process to be 'suspended', which wouldn't match your definition, as it is merely runnable…

what about isSuspended and isBlocked…?
best regards
        -tobias

>
>
> Best,
> Marcel
>
>
>
> --
> View this message in context: http://forum.world.st/Process-isSusended-tp4878671p4878690.html
> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>
>
>
>
> --
> _,,,^..^,,,_
> best, Eliot
>


Reply | Threaded
Open this post in threaded view
|

Re: Process>>isSusended

David T. Lewis
In reply to this post by Eliot Miranda-2
On Thu, Feb 18, 2016 at 01:22:28PM -0800, Eliot Miranda wrote:

> Hi All,
>
>    we have a serious misunderstanding in current versions of Squeak's and
> Pharo's Process>>isSuspended.
>
> Squeak's version reads
>
> isSuspended
> ^myList isNil
>
> Pharo's reads
>
> isSuspended
> ^myList isNil or: [ myList isEmpty ]
>
> Process's myList holds the list a process is on when it is not running.
> There is only one running process at any one time, Processor
> activeProcess.  The active process's myList is always nil, so Squeak's and
> Pharo's are both wrong for the active process.
>
> Processor activeProcess isSuspended => true (!!!)

This was working correctly as of Squeak4.6, but not in Squeak5.0.15113.image.

Dave


Reply | Threaded
Open this post in threaded view
|

Re: [Pharo-dev] [squeak-dev] Process>>isSusended

David T. Lewis
On Thu, Feb 18, 2016 at 10:03:47PM -0500, David T. Lewis wrote:

> On Thu, Feb 18, 2016 at 01:22:28PM -0800, Eliot Miranda wrote:
> > Hi All,
> >
> >    we have a serious misunderstanding in current versions of Squeak's and
> > Pharo's Process>>isSuspended.
> >
> > Squeak's version reads
> >
> > isSuspended
> > ^myList isNil
> >
> > Pharo's reads
> >
> > isSuspended
> > ^myList isNil or: [ myList isEmpty ]
> >
> > Process's myList holds the list a process is on when it is not running.
> > There is only one running process at any one time, Processor
> > activeProcess.  The active process's myList is always nil, so Squeak's and
> > Pharo's are both wrong for the active process.
> >
> > Processor activeProcess isSuspended => true (!!!)
>
> This was working correctly as of Squeak4.6, but not in Squeak5.0.15113.image.

Correcting myself, the difference in behavior is related to the VM. Using
a Squeak 4.6 image and comparing Cog versus interpreter VM:

Processor activeProcess isSuspended ==> true "Cog"
Processor activeProcess isSuspended ==> false "interpreter VM"

I think there were some process scheduling improvements introduced in Cog, and
maybe the image needs to be adjusted accordingly?

Dave

Reply | Threaded
Open this post in threaded view
|

Re: Process>>isSusended

Eliot Miranda-2
In reply to this post by Tobias Pape
Hi Tobias,

> On Feb 18, 2016, at 3:10 PM, Tobias Pape <[hidden email]> wrote:
>
> Hi,
>> On 19.02.2016, at 00:06, Eliot Miranda <[hidden email]> wrote:
>>
>> Hi Marcel,
>>
>> On Thu, Feb 18, 2016 at 1:30 PM, marcel.taeumel <[hidden email]> wrote:
>> Hi, Eliot.
>>
>> Now there are no suspended processes anymore. :-/ I just grabbed a debugger
>> and took its interruptedProcess. #isSuspended still returned false.
>>
>> If isSuspended means is waiting on some process list other than the runnable process lists then this is what you'd expect.  For example, the background process is not suspended.  If what yu want to test for is "runnable but not running" then you need something like
>>
>> isRunnable
>>    "A process is runnable if it is the active process or is on one of the runnable process lists."
>>    | myPriority |
>>    "Grab my priority now.  Even though evaluation is strictly right-to-left, accessing Processor could involve a send."
>>    myPriority := priority.
>>    ^myList
>>        ifNil: [^self == Processor activeProcess]
>>        ifNotNil: [:list| list == (Processor waitingProcessesAt: myPriority)]
>>
>> In my image I have all of isRunnable, isSuspended and neither (terminated) processes
>>
>> | procs |
>> procs := Process allInstances.
>> procs size -> (procs select: [:p| p isRunnable]) size -> (procs select: [:p| p isSuspended]) size -> (procs reject: [:p| p isRunnable or: [p isSuspended]]) size 19->4->6->9
>>
>>
>> So I think your issue is that you a) have no isSusoended processes; create some by e.g. opening lots of browsers so that there are background shout processes waiting on semaphores, b) collect some processes that compute something that doesn't take too long, so you've got terminated processes, and then try again.
>>
>> So let's have a look at those processes above
>>
>>
>> | procs full types |
>> procs := Process allInstances.
>> types:= {procs select: [:p| p isRunnable]. procs select: [:p| p isSuspended]. procs reject: [:p| p isRunnable or: [p isSuspended]]}.
>> full := types collect: [:type| type collect: [:ea| ea -> (ea suspendedContext ifNil: ['Active or terminated'] ifNotNil: [:c| c stackOfSize: 5])]].
>> full
>>
>> "isRunnable"
>> {{  a Process in ProcessorScheduler class>>idleProcess->an OrderedCollection(ProcessorScheduler class>>idleProcess [] in ProcessorScheduler class>>startUp: [] in BlockClosure>>newProcess) .
>>    a Process in nil->'Active or terminated'} .
>>
>> "isSuspended"
>> {a Process in Delay class>>handleTimerEvent->an OrderedCollection(Delay class>>handleTimerEvent Delay class>>runTimerEventLoop [] in Delay class>>startTimerEventLoop [] in BlockClosure>>newProcess) .
>> a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess) .
>> a Process in EventSensor>>userInterruptWatcher->an OrderedCollection(EventSensor>>userInterruptWatcher [] in EventSensor>>installInterruptWatcher [] in BlockClosure>>newProcess) .
>> a Process in [] in Delay>>wait->an OrderedCollection([] in Delay>>wait BlockClosure>>ifCurtailed: Delay>>wait [] in EventSensor>>eventTickler BlockClosure>>on:do:) .
>> a Process in WeakArray class>>finalizationProcess->an OrderedCollection(WeakArray class>>finalizationProcess [] in WeakArray class>>restartFinalizationProcess [] in BlockClosure>>newProcess) .
>> a Process in SmalltalkImage>>lowSpaceWatcher->an OrderedCollection(SmalltalkImage>>lowSpaceWatcher [] in SmalltalkImage>>installLowSpaceWatcher [] in BlockClosure>>newProcess) .
>> "this one is the styler for the pane in which I ran the doit:"
>> a Process in [] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess:->an OrderedCollection([] in [] in SHTextStylerST80(SHTextStyler)>>styleInBackgroundProcess: [] in BlockClosure>>newProcess)} .
>>
>> "neither isRunnable notr isSuspended"
>> {a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in nil->'Active or terminated' .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess) .
>> a Process in [] in BlockClosure>>newProcess->an OrderedCollection([] in BlockClosure>>newProcess)}}
>>
>>
>> Hmmm, interesting.  The isRunnable and isSuspended set are exactly as I would expect.  But what are all these spawning processes?  I'll use the pointer finder to track them down.
>>
>> 6 of them are styler processes that have yet to start running, so presumably in browsers I've left open but have never looked at.
>> One of them was terminated before I could track it down.
>> One of them is the modalProcess in an MCMergeBrowser.
>> One of them is the uiProcess in a project.
>>
>> So as far as I can tell the isSuspended and isRunnable definitions I mention above are fine.  Shall I commit isRunnable?
>
> Just one thing:
> I thought of 'isSuspended' meaning: 'this thing is not running, but it could eventually' not 'this thing cannot run because it is actively waiting for something'.
> You see, if I call 'Processor yield' I'd expect the current process to be 'suspended', which wouldn't match your definition, as it is merely runnable…
>
> what about isSuspended and isBlocked…?

Ah right!  So I am confused about isSuspended.  It's definition was correct (I'll restore it tomorrow) but it needs a comment.  My isRunnable is correct but my isSuspended should be called isBlocked.  Thank you.


> best regards
>    -tobias

_,,,^..^,,,_ (phone)


>>
>>
>> Best,
>> Marcel
>>
>>
>>
>> --
>> View this message in context: http://forum.world.st/Process-isSusended-tp4878671p4878690.html
>> Sent from the Squeak - Dev mailing list archive at Nabble.com.
>>
>>
>>
>>
>> --
>> _,,,^..^,,,_
>> best, Eliot
>
>