Where to get Monitor implementation based on primitives?

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

Re: Where to get Monitor implementation based on primitives?

KenDickey
 
On Wed, 20 Jan 2016 22:37:07 +0800
Ben Coman <[hidden email]> wrote:

>  
> On Tue, Jan 19, 2016 at 12:06 AM, KenD <[hidden email]> wrote:
..
> > Perhaps better to think of an "access permission" than a "lock"
> >
> > uniqueAccess acquire

> Maybe.  Except when I think of uniqueXXX  what comes to mind is the
> Singleton pattern.

Well, a semaphore is not a "lock".  One does not have to use it.

Given that the intended usage is a unique semaphore per resource, one wishes to acquire a unique access permission to the resource.

resourceGuardAccessPermission seems a bit long to me.

Perhaps a unique spelling:
  uniqAccess acquire
?

For clarity, what are your suggestions?

--
-KenD
-KenD
Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

KenDickey
 
On Thu, 21 Jan 2016 08:07:06 +0800
Ben Coman <[hidden email]> wrote:

> Intended usage is not a semaphore. Intended usage is a mutual
> exclusion primitive (i.e. a lock)

exclusiveAccess acquire

$0.02,
-KenD
-KenD
Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

Denis Kudriashov
 
I update slice with renames to OwnedLock.
We discussed names at Sprint

2016-01-21 2:12 GMT+01:00 KenD <[hidden email]>:

On Thu, 21 Jan 2016 08:07:06 +0800
Ben Coman <[hidden email]> wrote:

> Intended usage is not a semaphore. Intended usage is a mutual
> exclusion primitive (i.e. a lock)

exclusiveAccess acquire

$0.02,
-KenD

Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

Ben Coman
 
cool. I'll take another look.
cheers -ben

On Fri, Jan 29, 2016 at 9:52 PM, Denis Kudriashov <[hidden email]> wrote:

>
> I update slice with renames to OwnedLock.
> We discussed names at Sprint
>
> 2016-01-21 2:12 GMT+01:00 KenD <[hidden email]>:
>>
>>
>> On Thu, 21 Jan 2016 08:07:06 +0800
>> Ben Coman <[hidden email]> wrote:
>>
>> > Intended usage is not a semaphore. Intended usage is a mutual
>> > exclusion primitive (i.e. a lock)
>>
>> exclusiveAccess acquire
>>
>> $0.02,
>> -KenD
>
>
>
Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

Ben Coman
In reply to this post by Ben Coman
 
On Fri, Jan 8, 2016 at 9:39 PM, Ben Coman <[hidden email]> 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.
Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

Ben Coman
In reply to this post by Denis Kudriashov
 

> 2016-01-11 14:58 GMT+01:00 Denis Kudriashov <[hidden email]>:
>>
>> Eliot I found that there are no methods for simulation code (if it right name for it). So stepping over new primitives failed (which is infinite recursion for Pharo case)
>>
>> Context>>doPrimitive: primitiveIndex method: meth receiver: aReceiver args: arguments
>> ...
>> "Mutex>>primitiveEnterCriticalSection
>> Mutex>>primitiveTestAndSetOwnershipOfCriticalSection"
>> (primitiveIndex = 186 or: [primitiveIndex = 187]) ifTrue:
>> [| active effective |
>> active := Processor activeProcess.
>> effective := active effectiveProcess.
>> "active == effective"
>> value := primitiveIndex = 186
>> ifTrue: [aReceiver primitiveEnterCriticalSectionOnBehalfOf: effective]
>> ifFalse: [aReceiver primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: effective].
>> ^(self isPrimFailToken: value)
>> ifTrue: [value]
>> ifFalse: [self push: value]].
>>
>> How this methods should be implemented?

On Mon, Jan 11, 2016 at 10:54 PM, Denis Kudriashov <[hidden email]> wrote:

>
> I write it such way:
>
> primitiveEnterCriticalSectionOnBehalfOf: activeProcess
> [owningProcess ifNil:
> [owningProcess := activeProcess.
> ^false].
>  owningProcess = activeProcess ifTrue:
> [^true].
>  self addLast: Processor activeProcess.
> activeProcess suspend] valueUnpreemptively
>
> primitiveTestAndSetOwnershipOfCriticalSectionOnBehalfOf: activeProcess
> [owningProcess ifNil:
> [owningProcess := activeProcess.
> ^false].
>  owningProcess = activeProcess ifTrue: [^true].
>  ^nil] valueUnpreemptively

@Dennis, Why not...
    primitiveEnterCriticalSectionOnBehalfOf: activeProcess
         <primitive: 186>
         self primitiveFailed

I had been meaning to ask what this code at the top of the primitive was for...
    argumentCount > 0
        ifTrue:
            [criticalSection := self stackValue: 1.  "rcvr"
             activeProc := self stackTop]
        ifFalse:
            [criticalSection := self stackTop.  "rcvr"
             activeProc := self activeProcess].

but took a wild guess its to support onBehalfOf type calls.
So I tried...

    | cs p1 p2 p3 |
    cs := CriticalSection new.
    p1 := [ cs critical: [ Transcript crShow: 1 ] ] newProcess priority: 41.
    p2 := [ cs critical: [ Transcript crShow: 2 ] ] newProcess priority: 41.
    p3 := [ cs critical: [ Transcript crShow: 3 ] ] newProcess priority: 41.
    cs primitiveEnterCriticalSectionOnBehalfOf: p3.
    p1 resume. p2 resume. p3 resume.
    cs primitiveExitCriticalSection.

and indeed the result is...
3
1
2

cheers -ben
Reply | Threaded
Open this post in threaded view
|

Re: Where to get Monitor implementation based on primitives?

Denis Kudriashov
 

2016-02-06 8:16 GMT+01:00 Ben Coman <[hidden email]>:
@Dennis, Why not...
    primitiveEnterCriticalSectionOnBehalfOf: activeProcess
         <primitive: 186>
         self primitiveFailed

I had been meaning to ask what this code at the top of the primitive was for...
    argumentCount > 0
        ifTrue:
            [criticalSection := self stackValue: 1.  "rcvr"
             activeProc := self stackTop]
        ifFalse:
            [criticalSection := self stackTop.  "rcvr"
             activeProc := self activeProcess].

but took a wild guess its to support onBehalfOf type calls.

Nice. What about tryAcquire (187)? Does it implemented same way?

 
123