Le 9/1/16 03:04, Ben Coman a écrit :
I found the blogs by real-time OS guys (RTOS) have more interesting
opinions on the finer points. They are the ones who are down in the
trenches.
Yes I read them too even if I got lost probably :)
cheers -ben
On Sat, Jan 9, 2016 at 4:17 AM, stepharo <[email protected]> wrote:
thanks for the summary.
I think that this is important to update the class comments with the comment
of ben.
I read several blogs of mutex vs semaphore and this is nice to get this
cleared out.
Stef
Le 7/1/16 14:05, Denis Kudriashov a écrit :
Hi.
We got interesting discussion about semaphore and mutex. Here I put summary
of proposed changes.
First we will deprecate Semaphore>>forMutualExclusion and rename it to
Semaphore>>newSignalled. Explanation from Ben Coman:
Semaphore>>forMutualExclusion *encourages* people to believe
semaphores can be used *on*their*own* for mutual exclusion, when they
*shouldn't*. You *must* add ownership. If the mutual exclusion
object doesn’t have ownership then, irrelevant of what it is called,
it is not a mutex!!! [1].
And more:
With an implementation like..
Semaphore>>forMutualExclusion
^self new signal
we don't gain a lot, and its a misleading convenience method since its
doesn't provide the proper facility for mutual exclusion (and I do
conflate mutual exclusion == mutex). Indeed, "Semaphore
forMutualExclusion + roll your ownership management + problems since
you weren't aware you needed to roll your own ownership management" is
not more convenient than "Mutex new"
If you want to keep a convenience method for a pre signalled
Semaphore, then we could provide something like "Semaphore
newSignalled"
It is also explain why we should deprecate Semaphore>>critical: and use
Mutex>>critical: instead. That's second change.
So we want to move 4 Semaphore methods to Mutex:
critical: mutuallyExcludedBlock
It will relies on new Semaphore method waitIfInterrupted: which block is
executed when waiting process terminated at point where lock was not
acquired. Slice for this already in inbox.
critical: mutuallyExcludedBlock ifCurtailed: terminationBlock
critical: mutuallyExcludedBlock ifError: errorBlock
Semantic of this method is like BlockCosure>>ifError:. It culls error
properties to handler block. It will be changed to cull only error instance.
It will touch WeakArray and WeakRegistry. Now they doing this:
ifError:[:msg :rcvr| rcvr error: msg].
No special logic inside handler. So we will just use #critical: message.
critical: mutuallyExcludedBlock ifLocked: alternativeBlock
It purpose looks like "enter critical section without waiting otherwise
alternativeBlock". But implementation not shows that waiting can not be
happens:
critical: mutuallyExcludedBlock ifLocked: alternativeBlock
excessSignals == 0
ifTrue:
[ ^alternativeBlock value ].
^self critical: mutuallyExcludedBlock
When critical message is sent but it method not started interrupt can happen
and other process can lock this semaphore. And when process will be resumed
it will be blocked.
So implementation is not correct to me. It should be changed somehow.
Welcome for suggestions