<br><br><div class="gmail_quote">On Tue, Oct 12, 2010 at 8:28 AM, Tom Rushworth <span dir="ltr"><<a href="mailto:tom_rushworth@mac.com">tom_rushworth@mac.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
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.<br></blockquote><div><br></div>
<div>+1.</div><div><br></div><div>I want, e.g.</div><div><br></div><div> (var ?== expr : match) evaluates to true and var == expr if var == prev before the statement, and false and var unchanged if var ~~ match</div>
<div><br></div><div>var ?= expr : match is more difficult to implement since = is not necessarily primitive.</div><div><br></div><div>So one could write e.g.</div><div><br></div><div>LinkedList subclass: #Semaphore</div><div>
instanceVariableNames: 'signals locked'</div><div><br></div><div>Semaphore>>signal</div><div> [locked ?== true : false] whileFalse.</div><div> self isEmpty</div><div> ifTrue: [signals := signals + 1]</div>
<div> ifFalse: [self removeFirst resume].</div><div> locked := false</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
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):<br>
<br>
(variable == oldValue) ifTrue: [variable := newValue. ^true].<br>
" variable not the same as oldValue, no swap performed "<br>
^false<br>
<div><div></div><div class="h5"><br>
On 2010-Oct-12, at 06:58, Igor Stasenko wrote:<br>
<br>
> On 12 October 2010 16:51, Levente Uzonyi <<a href="mailto:leves@elte.hu">leves@elte.hu</a>> wrote:<br>
>> On Tue, 12 Oct 2010, Igor Stasenko wrote:<br>
>><br>
>>> Hello, i just thought, that it would be cool to have a special bytecode,<br>
>>> which guarantees atomicity for swapping values between two variables.<br>
>>><br>
>>> To swap two values, you usually do:<br>
>>><br>
>>> | var1 var2 temp |<br>
>>><br>
>>> temp := var1.<br>
>>> var1 := var2.<br>
>>> var2 := temp.<br>
>>><br>
>>> But since its non-atomic, a process can be interrupted and such operation<br>
>>> is not thread-safe.<br>
>>><br>
>>> In order to make it thread safe, you must add even more boilerplate:<br>
>>><br>
>>> | var1 var2 temp |<br>
>>><br>
>>> semaphore critical: [<br>
>>> temp := var1.<br>
>>> var1 := var2.<br>
>>> var2 := temp.<br>
>>> ]<br>
>><br>
>> An alternative solution:<br>
>><br>
>> | a b |<br>
>> a := 1.<br>
>> b := 2.<br>
>> [<br>
>> | tmp |<br>
>> tmp := a.<br>
>> a := b.<br>
>> b := tmp ] valueUnpreemptively<br>
>><br>
><br>
> Yeah, another boilerplate under the hood, also highly dependent from<br>
> scheduling nuances :)<br>
><br>
> valueUnpreemptively<br>
> "Evaluate the receiver (block), without the possibility of preemption<br>
> by higher priority processes. Use this facility VERY sparingly!"<br>
> "Think about using Block>>valueUninterruptably first, and think about<br>
> using Semaphore>>critical: before that, and think about redesigning<br>
> your application even before that!<br>
> After you've done all that thinking, go right ahead and use it..."<br>
> | activeProcess oldPriority result |<br>
> activeProcess := Processor activeProcess.<br>
> oldPriority := activeProcess priority.<br>
> activeProcess priority: Processor highestPriority.<br>
> result := self ensure: [activeProcess priority: oldPriority].<br>
> "Yield after restoring priority to give the preempted processes a<br>
> chance to run"<br>
> Processor yield.<br>
> ^result<br>
>><br>
>> Levente<br>
>><br>
><br>
><br>
><br>
> --<br>
> Best regards,<br>
> Igor Stasenko AKA sig.<br>
><br>
<br>
</div></div>--<br>
<font color="#888888">Tom Rushworth<br>
<br>
<br>
<br>
<br>
</font></blockquote></div><br>