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
This is not the definition of suspended that the fallback code in Process
#suspend uses.
By its definition, when suspended, a Process is removed from all running queues, and there's no chance it will run again before being explicitly resume'd. Does the primitive work differently?
If not, is there a simple way to check if list is nil because we are (the actual, not effective) activeProcess, nor because we have been #suspend'ed, or do we need a #trueActiveProcess as well?
Cheers, Henry
P.S. after the change to use effectiveProcess, Processor activeProcess should actually answer true when being debugged, no?
On Thu, Feb 18, 2016 at 10:22 PM, Eliot Miranda eliot.miranda@gmail.com 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 (!!!)
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
Answering myself, no, that makes no sense. If isSuspended is being evaluated on behalf of a suspended process, they are not suspended.
On Fri, Feb 19, 2016 at 1:04 AM, Henrik Sperre Johansen < henrik.s.johansen@veloxit.no> wrote:
P.S. after the change to use effectiveProcess, Processor activeProcess should actually answer true when being debugged, no?
Hi
2016-02-19 1:04 GMT+01:00 Henrik Sperre Johansen < henrik.s.johansen@veloxit.no>:
This is not the definition of suspended that the fallback code in Process
#suspend uses.
By its definition, when suspended, a Process is removed from all running queues, and there's no chance it will run again before being explicitly resume'd. Does the primitive work differently?
This is what I think about too. But
Processor activeProcess isSuspended => true (!!!)
is completely wrong
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
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
Hi David,
On Feb 18, 2016, at 8:09 PM, David T. Lewis lewis@mail.msen.com wrote:
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?
As far as myList maintenance Cig merely preserves the semantics in Andres' Interpreter VM fork at Qwaq, so credit for the improvements go to him. I'll try to remember to compare the VMMaker.oscog and VMMaker Interpreter and move the fixes across.
Dave
_,,,^..^,,,_ (phone)
vm-dev@lists.squeakfoundation.org