On 08 Jan 2016, at 4:25 , Ben Coman <btc@openInWorld.com> wrote:
On Fri, Jan 8, 2016 at 9:39 PM, Ben Coman <btc@openinworld.com> wrote:On Fri, Jan 8, 2016 at 5:42 PM, stephane ducasse
<stephane.ducasse@gmail.com> wrote:
I have a (stupid) question.
Is the code running without the primitives?
Are the code below the primitives correct?
I asked that because we can have 100 eyes and brains on the smalltalk level and far less on the VM primitive level.
Because:
1. Concurrency bugs can be subtle and the *exact* conditions can be
hard to reproduce for debugging. For example, the solution to a
couple of problems with Delay [1] [2] were solved by moving away from
Semaphore>>critical: to use signalling.
2. The in-image atomicity of determining whether a signal was actually
consumed or not during process suspension/termination is awkward. Its
seems hard to *really* know for sure it right (but I haven't looked in
depth into Denis' latest proposals.)
3. The existing in-image implementation of Semaphore>>critical messes
around in Process>>terminate in a *special* way that is not easy for
those 100 eyes to understand. For example, I personally am not
comfortable with understanding how the special Semaphore handling in
Process>>terminate works, but I can easily follow how
primitiveEnterCriticalSection just looking at the code [3].
Points 2 & 3 might possibly be addressed by having new primitiveWaitReturned
*always* return true, so if the process is terminated while waiting,
the assignment to signalConsumed doesn't occur...
critical: mutuallyExcludedBlock
signalConsumed := false.
[
signalConsumed := self primitiveWaitReturned.
blockValue := mutuallyExcludedBlock value
] ensure: [ signalConsumed ifTrue: [self signal] ].
^blockValue
where primitiveWait (https://git.io/vuDjd) is copied
and (just guessing) the marked line added...
primitiveWaitReturned
| sema excessSignals activeProc inInterpreter |
sema := self stackTop. "rcvr"
"==>>" self pop: argumentCount + 1 thenPush: objectMemory trueObject. "<<=="
excessSignals := self fetchInteger: ExcessSignalsIndex ofObject: sema.
excessSignals > 0
ifTrue:
[self storeInteger: ExcessSignalsIndex
ofObject: sema
withValue: excessSignals - 1]
ifFalse:
inInterpreter := instructionPointer >= objectMemory startOfMemory.
activeProc := self activeProcess.
self addLastLink: activeProc toList: sema.
self transferTo: self wakeHighestPriority from: CSWait.
self
forProcessPrimitiveReturnToExecutivePostContextSwitch: inInterpreter]
which I guess could be added quickly if Esteban could compile the
latest pharo-spur-vm ;)
cheers -ben