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