[Vm-dev] Where to get Monitor implementation based on primitives?
Ben Coman
btc at openinworld.com
Sat Feb 6 03:56:57 UTC 2016
On Fri, Jan 8, 2016 at 9:39 PM, Ben Coman <btc at openinworld.com> wrote:
>
> btw, Looking at the following...
> CriticalSection>>critical: aBlock
> ^self primitiveEnterCriticalSection
> ifTrue: [aBlock value]
> ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]
>
> without intimate VM knowledge but seeing Eliot recently say
> "invocations of methods with primitives [...] are not suspension
> points, unless their primitives fail" -- I'm paranoid that since
> #ensure: primitive 198 always fail, there might be some some small
> window for a race where a process might be terminated before
> #primitiveExitCriticalSection can be executed. I'll take a refutation
> of this to improve the method comment.
>
> The following instils more confidence...
>
> CriticalSection2>>critical: aBlock
> | reEntered |
> reEntered := false.
> [ reEntered := self primitiveEnterCriticalSection.
> aBlock value ] ensure:
> [ reEntered ifFalse: [ self primitiveExitCriticalSection] ]
Having spent more time considering this, I found I was off track here.
If a process waiting at #primitiveEnterCriticalSection is terminated,
then #primitiveExitCriticalSection is erroneously executed.
And it will be the same problem with the proposal for Case17373 based
on OwnedLock>>acquire
Mutex>>critical: aBlock
| lockAcquiredNotHere |
<lockAt: #lock tracksStateAt: 1>
lockAcquiredNotHere := true.
^[
lockAcquiredNotHere := false.
lockAcquiredNotHere := lock acquire.
aBlock value
] ensure: [lockAcquiredNotHere ifFalse: [lock release]].
So now I believe the original #critical: proposed by Eliot is optimal.
* If #primitiveEnterCriticalSection is terminated while waiting, then
the #ifFalse: is never executed.
* When #primitiveEnterCriticalSection returns, the inlined
#ifTrue:ifFalse cant be interrupted.
* #ensure is a primitive which can't be interrupted. By the time it
has done its usual "fail", which I raised concern over, actually it
has already done its job to make sure #primitiveExitCriticalSection is
executed.
More information about the Vm-dev
mailing list