[squeak-dev] Re: [Pharo-project] How about atomic value-swap bytecode?

Eliot Miranda eliot.miranda at gmail.com
Tue Oct 12 17:46:05 UTC 2010


On Tue, Oct 12, 2010 at 8:28 AM, Tom Rushworth <tom_rushworth at mac.com>wrote:

> If you're going for atomic swap as a primitive, why not go for
> Compare-And-Swap?  That way all the various lock-free algorithms that use
> the CAS machine instruction will translate easily.
>

+1.

I want, e.g.

       (var ?== expr : match) evaluates to true and var == expr if var ==
prev before the statement, and false and var unchanged if var ~~ match

var ?= expr : match is more difficult to implement since = is not
necessarily primitive.

So one could write e.g.

LinkedList subclass: #Semaphore
    instanceVariableNames: 'signals locked'

Semaphore>>signal
    [locked ?== true : false] whileFalse.
    self isEmpty
        ifTrue: [signals := signals + 1]
        ifFalse: [self removeFirst resume].
    locked := false


> CAS(variable,oldValue,newValue) is an atomic operation which returns a
> boolean value (my ST syntax is rusty at the moment, too much Objective-C):
>
> (variable == oldValue) ifTrue: [variable := newValue. ^true].
> " variable not the same as oldValue, no swap performed "
> ^false
>
> On 2010-Oct-12, at 06:58, Igor Stasenko wrote:
>
> > On 12 October 2010 16:51, Levente Uzonyi <leves at elte.hu> wrote:
> >> On Tue, 12 Oct 2010, Igor Stasenko wrote:
> >>
> >>> Hello, i just thought, that it would be cool to have a special
> bytecode,
> >>> which guarantees atomicity for swapping values between two variables.
> >>>
> >>> To swap two values, you usually do:
> >>>
> >>> | var1 var2 temp |
> >>>
> >>> temp := var1.
> >>> var1 := var2.
> >>> var2 := temp.
> >>>
> >>> But since its non-atomic, a process can be interrupted and such
> operation
> >>> is not thread-safe.
> >>>
> >>> In order to make it thread safe, you must add even more boilerplate:
> >>>
> >>> | var1 var2 temp |
> >>>
> >>> semaphore critical: [
> >>>  temp := var1.
> >>>  var1 := var2.
> >>>  var2 := temp.
> >>> ]
> >>
> >> An alternative solution:
> >>
> >> | a b |
> >> a := 1.
> >> b := 2.
> >> [
> >>        | tmp |
> >>        tmp := a.
> >>        a := b.
> >>        b := tmp ] valueUnpreemptively
> >>
> >
> > Yeah, another boilerplate under the hood, also highly dependent from
> > scheduling nuances :)
> >
> > valueUnpreemptively
> >       "Evaluate the receiver (block), without the possibility of
> preemption
> > by higher priority processes. Use this facility VERY sparingly!"
> >       "Think about using Block>>valueUninterruptably first, and think
> about
> > using Semaphore>>critical: before that, and think about redesigning
> > your application even before that!
> >       After you've done all that thinking, go right ahead and use it..."
> >       | activeProcess oldPriority result |
> >       activeProcess := Processor activeProcess.
> >       oldPriority := activeProcess priority.
> >       activeProcess priority: Processor highestPriority.
> >       result := self ensure: [activeProcess priority: oldPriority].
> >       "Yield after restoring priority to give the preempted processes a
> > chance to run"
> >       Processor yield.
> >       ^result
> >>
> >> Levente
> >>
> >
> >
> >
> > --
> > Best regards,
> > Igor Stasenko AKA sig.
> >
>
> --
> Tom Rushworth
>
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20101012/c645b3a7/attachment.htm


More information about the Squeak-dev mailing list