[Vm-dev] Where to get Monitor implementation based on primitives?

Eliot Miranda eliot.miranda at gmail.com
Thu Jan 7 18:51:03 UTC 2016


Hi Ben,

On Thu, Jan 7, 2016 at 10:39 AM, Ben Coman <btc at openinworld.com> wrote:

>
> On Fri, Jan 8, 2016 at 1:20 AM, Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
> >
> > and here's a version with a better class comment
> >
> > On Thu, Jan 7, 2016 at 9:12 AM, Eliot Miranda <eliot.miranda at gmail.com>
> wrote:
> >>
> >> Hi Denis, Hi Clément,  Hi Frank,
> >>
> >> On Thu, Jan 7, 2016 at 5:34 AM, Clément Bera <bera.clement at gmail.com>
> wrote:
> >>>
> >>> Hello,
> >>>
> >>> Eliot, please, you told me you had the code and Denis is interested.
> >>>
> >>> It uses 3 primitives for performance.
> >>
> >>
> >> Forgive the delay.  I thought it proper to ask permission since the
> code was written while I was at Qwaq. I'm attaching the code in a fairly
> raw state, see the attached.  The code is MIT, but copyright 3DICC.
> >>
> >> It is a plugin replacement for Squeak's Mutex, and with a little
> ingenuity could be a replacement for Squeak's Monitor.  It is quicker
> because it uses three new primitives to manage entering a critical section
> and setting the owner, exiting the critical section and releasing the
> owner, and testing if a critical section, entering if the section is
> unowned.  The use of the primitives means fewer block activations and
> ensure: blocks in entering and exiting the critical section, and that's the
> actual cause of the speed-up.
> >>
> >> You can benchmark the code as is.  Here are some results on 32-bit
> Spur, on my 2.2GHz Core i7
> >>
> >> {Mutex new. Monitor new. CriticalSection new} collect:
> >> [:cs| | n |
> >> n := 0.
> >> [cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n
> := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1].
> >> cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n
> := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1].
> >> n ] bench]
> >>
> >> {Mutex new. Monitor new. CriticalSection new} collect:
> >> [:cs| | n |
> >> n := 0.
> >> cs class name, ' -> ',
> >> [cs critical: [n := n + 1]. cs critical: [n := n + 1]. cs critical: [n
> := n + 1]. cs critical: [n := n + 1]. cs critical: [n := n + 1].
> >> cs critical: [n := n - 1]. cs critical: [n := n - 1]. cs critical: [n
> := n - 1]. cs critical: [n := n - 1]. cs critical: [n := n - 1].
> >> n ] bench]
> >>
> >> #( 'Mutex -> 440,000 per second. 2.27 microseconds per run.'
> >> 'Monitor -> 688,000 per second. 1.45 microseconds per run.'
> >> 'CriticalSection -> 1,110,000 per second. 900 nanoseconds per run.')
> >>
>
> This is great Eliot. Thank you and 3DICC.  After loading the changeset
> into Pharo-50515 (32 bit Spur) I get the following results on my
> laptop i5-2520M @ 2.50GHz
>
> #('Mutex -> 254,047 per second'
>  'Monitor -> 450,442 per second'
>  'CriticalSection -> 683,393 per second')
>
> In a fresh Image "Mutex allInstances basicInspect" lists just two
> mutexes...
> 1. NetNameResolver-->ResolverMutex
> 2. ThreadSafeTranscript-->accessSemaphore
>

I hate myself for getting distracted but I'm finding this is un.  One can
migrate to the new representation using normal Monticello loads by

In the first version redefine Mutex and Monitor to subclass LinkedList and
have their owner/ownerProcess inst var first (actually third after
firstLink & lastLink), and add the primitives.

In the next version check that all Mutex and Monitor instanes are unowned
and then redefine to discard excess inst vars

Let me test this before committing, and see that all tests are ok.


> cheers -ben
>
> >> Replacement is probably trivial; rename Mutex to OldMutex, rename
> CriticalSection to Mutex, recompile.  But there are lots of mutexes in the
> system and these are potentially owned.  Transforming unowned ones is
> trivial, but transforming owned ones is, I think, impossible.  But at least
> in my system there are no owned mutexes or monitors.
> >>
> >> Frank (or anyone else), would you be interested in creating a
> replacement for Squeak's Monitor based on CriticalSection?
> >>
> >>
> >> Here are the two business methods:
> >> CriticalSection methods for mutual exclusion
> >> critical: aBlock
> >> "Evaluate aBlock protected by the receiver."
> >> ^self primitiveEnterCriticalSection
> >> ifTrue: [aBlock value]
> >> ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]
> >>
> >> critical: aBlock ifLocked: lockedBlock
> >> "Answer the evaluation of aBlock protected by the receiver.  If it is
> already in a critical
> >> section on behalf of some other process answer the evaluation of
> lockedBlock."
> >> ^self primitiveTestAndSetOwnershipOfCriticalSection
> >> ifNil: [lockedBlock value]
> >> ifNotNil:[:alreadyOwner|
> >> alreadyOwner
> >> ifTrue: [aBlock value]
> >> ifFalse: [aBlock ensure: [self primitiveExitCriticalSection]]]
> >>
> >> and the primitives:
> >> CriticalSection methods for private-primitives
> >> primitiveEnterCriticalSection
> >> "Primitive. The receiver must be unowned or owned by the current
> process to proceed.
> >> Answer if the process is owned by the current process."
> >> <primitive: 186>
> >> self primitiveFailed
> >> "In the spirit of the following"
> >> "[owner ifNil:
> >> [owner := Processor activeProcess.
> >> ^false].
> >>  owner = Processor activeProcess ifTrue:
> >> [^true].
> >>  self addLast: Processor activeProcess.
> >>  Processor activeProcess suspend] valueUnpreemptively"
> >>
> >> primitiveExitCriticalSection
> >> "Primitive. Set te receiver to unowned and if any processes are waiting
> on
> >> the receiver then proceed the first one, indicating that the receiver
> is unowned."
> >> <primitive: 185>
> >> self primitiveFailed
> >> "In the spirit of the following"
> >> "[owner := nil.
> >>  self isEmpty ifFalse:
> >> [process := self removeFirst.
> >> process resume]] valueUnpreemptively"
> >>
> >> primitiveTestAndSetOwnershipOfCriticalSection
> >> "Primitive. Attempt to set the ownership of the receiver.
> >> If the receiver is unowned set its owningProcess to the
> >> activeProcess and answer false.  If the receiver is owned
> >> by the activeProcess answer true.  If the receiver is owned
> >> by some other process answer nil."
> >> <primitive: 187>
> >> self primitiveFail
> >> "In the spirit of the following"
> >> "[owner ifNil:
> >> [owningProcess := Processor activeProcess.
> >> ^false].
> >>  owner = Processor activeProcess ifTrue: [^true].
> >>  ^nil] valueUnpreemptively"
> >>
> >>> 2016-01-07 13:24 GMT+01:00 Denis Kudriashov <dionisiydk at gmail.com>:
> >>>>
> >>>>
> >>>> Hello.
> >>>>
> >>>> I hear about new Monitor implementation based on new primitives.
> >>>> Where to get it?
> >>
> >>
> >> _,,,^..^,,,_
> >> best, Eliot
> >
> >
> >
> >
> > --
> > _,,,^..^,,,_
> > best, Eliot
> >
>



-- 
_,,,^..^,,,_
best, Eliot
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/vm-dev/attachments/20160107/fa73f829/attachment.htm


More information about the Vm-dev mailing list