<br><br><div class="gmail_quote">On Wed, Oct 13, 2010 at 11:37 AM, Igor Stasenko <span dir="ltr">&lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt;</span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5">On 13 October 2010 21:06, Eliot Miranda &lt;<a href="mailto:eliot.miranda@gmail.com">eliot.miranda@gmail.com</a>&gt; wrote:<br>
&gt;<br>
&gt;<br>
&gt; On Wed, Oct 13, 2010 at 9:41 AM, Tom Rushworth &lt;<a href="mailto:tom_rushworth@mac.com">tom_rushworth@mac.com</a>&gt;<br>
&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; Hi Igor, Eliot,<br>
&gt;&gt;<br>
&gt;&gt; Eliot, I&#39;m not sure I understood your comment:<br>
&gt;&gt;<br>
&gt;&gt; On 2010-Oct-13, at 08:55, Eliot Miranda wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; Right.  And because Smalltak can&#39;t reify variables and CAS is an<br>
&gt;&gt; &gt; operation on a variable CAS can&#39;t be implemented as a primitive on<br>
&gt;&gt; &gt; variables.  There&#39;s no way to express &quot;pass a variable to a primitive&quot;,<br>
&gt;&gt; &gt; only &quot;pass an expression (which may be the value of a variable)&quot; to a<br>
&gt;&gt; &gt; primitive&quot;.  One could do it with a primitive on an object, e.g.<br>
&gt;&gt; &gt; thisContext at: tempIndex compareWith: match andSetTo: expr, or anObject<br>
&gt;&gt; &gt; instVarAt: varIndex compareWith: match andSetTo: expr but that&#39;s soooo<br>
&gt;&gt; &gt; ugly.  Hence I think it is better done using a special assignment<br>
&gt;&gt; &gt; operator.<br>
&gt;<br>
&gt; I mean one can&#39;t write<br>
&gt;     | t |<br>
&gt;     self compare: t andSwap: expr<br>
&gt; because in the above the rvalue of t is passed, not it&#39;s lvalue, and cas<br>
&gt; needs to operate on an lvalue (rvalue == read value, or value of a variable;<br>
&gt; lvalue = location value, or address of a variable).  Clearly cas needs to<br>
&gt; apply to a variable, not the value in the variable.  The variable&#39;s value is<br>
&gt; compared and the variable is set to a new value if it matches.  Look at<br>
&gt; Igor&#39;s example and you&#39;ll see his primitive on Arrays passes an lvalue since<br>
&gt; the primitive takes the index of an array element.<br>
&gt; e.g. if you implemented CAS in C using functions instead of macros you&#39;d<br>
&gt; know that you couldn&#39;t do it with int cas(int var, int match, int new) but<br>
&gt; you&#39;d know that you can do it with int cas(int *var, int match, int new) and<br>
&gt; ... int v; ... cas(&amp;v, match, new)<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; Doesn&#39;t this apply to Igor&#39;s proposed atomic swap as well?  The target in<br>
&gt;&gt; Igor&#39;s example was a variable &quot;locked&quot; which was clearly meant to be visible<br>
&gt;&gt; to other threads.<br>
&gt;<br>
&gt; Yes.  First time I read Igor&#39;s post I on;y saw the initial<br>
&gt; &quot;| var1 var2 temp |<br>
&gt; temp := var1.<br>
&gt; var1 := var2.<br>
&gt; var2 := temp.&quot;<br>
&gt; which I rejected and didn&#39;t read further.  Now I see the :=:.  I don&#39;t like<br>
&gt; this because it doesn&#39;t map as nicely to CAS which I like using.  I like the<br>
&gt; boolean result one gets fro CAS that says the assignment either happened or<br>
&gt; it didn&#39;t.  Atomic swap is more low-level.  I then have to inspect the value<br>
&gt; the variable used to have and undo the swap if it wasn&#39;t what was expected.<br>
&gt;  So<br>
&gt;         | var |<br>
&gt;         var ?= expr : match<br>
&gt; is equivalent to<br>
&gt;         [| var scratch |<br>
&gt;         scratch := expr.<br>
&gt;         var :=: scratch.<br>
&gt;         scratch == match<br>
&gt;             ifTrue: [true]<br>
&gt;             ifFalse: [var :=: scratch. false]] valueUninterruptibly<br>
&gt; Hence I think :=: is too low-level.<br>
&gt;<br>
<br>
</div></div>well, once you start using valueUninterruptibly, there is no much<br>
reason to use/introduce atomic swap nor cas :)<br></blockquote><div><br></div><div>Right :)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
moreover, i see no trivial way to implement CAS using atomic swap,<br>
while reverse is trivial.<br></blockquote><div><br></div><div>Is it, or does it also rely on uninterruptbility?  Is this right?</div><div><br></div><div>    v1 :=: v2</div><div><br></div><div>is equivalent to</div><div><br>
</div><div>    [ | scratch |</div><div>     scratch := v1.</div><div>     v1 ?= v2 : scratch] whileFalse.</div><div>     v2 := scratch.</div><div><br></div><div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">

&gt;From this point of view, CAS is better.<br>
<div class="im"><br>
&gt;&gt;<br>
&gt;&gt; If that&#39;s the case, then they both need to be implemented with a special<br>
&gt;&gt; assignment operator, and Igor and I can get back to arguing the merits of<br>
&gt;&gt; the atomic swap versus the atomic compare and swap :).  If not, then Igor&#39;s<br>
&gt;&gt; swap has a clear advantage and I guess you can both ignore the rest of this<br>
&gt;&gt; email...<br>
&gt;<br>
&gt; Um, mine /does/ use a special assignment operator, &quot;?= :&quot; :)<br>
&gt;<br>
<br>
</div>var ?= match : expression<br>
<br>
could mean a lot of hacking in compiler. how about:<br>
<br>
var ?= { match . expression }<br>
<br>
so, you just need to introduce a new binary operator ?= &quot;CAS<br>
assignment&quot; or &quot;conditional assignment&quot;<br>
which is much simpler to hack comparing to trinary one.<br></blockquote><div><br></div><div>That&#39;s a good suggestion, bit let&#39;s see.  Personally I find  var ?= { match . expression } ok but a little flowery :)</div>
<div><br></div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
And you can also force compiler to expect only &#39;{&#39; after ?=, so no<br>
<br>
var ?= foo<br>
var ?= #( foo )<br>
var ?= self bar<br>
<br>
will be allowed.<br></blockquote><div><br></div><div>But ?= : is no more difficult than parsing expressions within keywords.  I guess it&#39;ll look something like</div><div><br></div><div>    conditionalAssignment: varNode</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>&quot; var &#39;?=&#39; expression &#39;:&#39; match =&gt; ConditionalAssignmentNode.&quot;</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>| loc start valueNode |</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>(loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) &gt;= 0 ifTrue:</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span><span class="Apple-tab-span" style="white-space: pre; ">        </span>[^self notify: &#39;Cannot store into&#39; at: loc].</div>
<div><span class="Apple-tab-span" style="white-space: pre; "></span></div><div><span class="Apple-tab-span" style="white-space:pre">        </span>start := self startOfNextToken.</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>self advance.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>self expression ifFalse: [^self expected: &#39;Expression&#39;].</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>newValueNode := parseNode.</div>
<div><span class="Apple-tab-span" style="white-space: pre; ">        </span>(self match: #colon) ifFalse: [^self expected: &#39;colon&#39;].</div><div><span class="Apple-tab-span" style="white-space: pre; ">        </span>self advance.</div>
<div><span class="Apple-tab-span" style="white-space: pre; ">        </span>self expression ifFalse: [^self expected: &#39;Expression&#39;].</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>parseNode := ConditionAssignmentNode new</div>
<div><span class="Apple-tab-span" style="white-space:pre">                                </span>variable: varNode</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>value: valueNode</div><span class="Apple-tab-span" style="white-space: pre; ">                                </span>match: valueNode<div>
<span class="Apple-tab-span" style="white-space:pre">                                </span>from: encoder</div><div><span class="Apple-tab-span" style="white-space:pre">                                </span>sourceRange: (start to: self endOfLastToken).</div><div><span class="Apple-tab-span" style="white-space:pre">        </span>varNode nowHasDef.</div>
<div><span class="Apple-tab-span" style="white-space:pre">        </span>^true</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<div><div></div><div class="h5"><br>
<br>
&gt;&gt;<br>
&gt;&gt; On 2010-Oct-13, at 08:33, Igor Stasenko wrote:<br>
&gt;&gt;<br>
&gt;&gt; &gt; On 13 October 2010 18:07, Tom Rushworth &lt;<a href="mailto:tom_rushworth@mac.com">tom_rushworth@mac.com</a>&gt; wrote:<br>
&gt;&gt; &gt;&gt; Hi all,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Take a look through the literature for the &quot;strength&quot; of the various<br>
&gt;&gt; &gt;&gt; types of atomic operations with respect to doing various synchronization<br>
&gt;&gt; &gt;&gt; tasks.  CAS is &quot;universal&quot; in the sense that it can simulate all of the<br>
&gt;&gt; &gt;&gt; others.  (The simulation is wretched, O(N**3), so it isn&#39;t practical,<br>
&gt;&gt; &gt;&gt; but...)<br>
&gt;&gt; &gt;&gt; I doubt that your atomic swap is as strong.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Who said i gonna use it for synchronizations tasks?<br>
&gt;&gt; &gt; We got a plenty of other stuff in smalltalk for synchronization.<br>
&gt;&gt;<br>
&gt;&gt; I&#39;m using &quot;synchronization&quot; in the sense of safe access to data in a<br>
&gt;&gt; multi-threaded context.  There is no point at all to atomic ops unless you<br>
&gt;&gt; are doing that kind of &quot;synchronization&quot;.  In particular, your example was<br>
&gt;&gt; for implementing a lock, which I took to be a mutex style lock from looking<br>
&gt;&gt; at your code.  Your example is in fact implementing a CAS spinloop for a<br>
&gt;&gt; boolean value.  My counter example just used CAS explicitly :).  You can use<br>
&gt;&gt; an unconditional swap for boolean values because there are only two possible<br>
&gt;&gt; values, so that setting the &#39;locked&#39; variable to true unconditionally<br>
&gt;&gt; doesn&#39;t hurt anything since either it was already true and you didn&#39;t change<br>
&gt;&gt; anything visible to another thread, or it was the desired previous value<br>
&gt;&gt; (false) and you did  change things visible to another thread is a planned,<br>
&gt;&gt; predictable way.  If the variable in question was a pointer this would not<br>
&gt;&gt; be a safe operation, because you have no way to predict what the value of<br>
&gt;&gt; temp should be.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Pretty well every current HW architecture actually has the CAS<br>
&gt;&gt; &gt;&gt; instruction (or some minor variation) implemented as a single instruction,<br>
&gt;&gt; &gt;&gt; so making it a primitive should be relatively easy. It seems a terrible<br>
&gt;&gt; &gt;&gt; waste to pick a weak synchronization primitive when a much better one could<br>
&gt;&gt; &gt;&gt; be had for very little more work.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I feel that you are mixing hardware and language-side atomicity.<br>
&gt;&gt; &gt; I don&#39;t care about hardware , i care that at language side i have a<br>
&gt;&gt; &gt; simple atomic operation, which can&#39;t be interrupted by scheduler.<br>
&gt;&gt; &gt; Hardware CAS is completely irrelevant to this, since VM can support<br>
&gt;&gt; &gt; atomicity for language side without any specific requirements from the<br>
&gt;&gt; &gt; hardware it runs on.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On 2010-Oct-12, at 12:04, Igor Stasenko wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; CAS? Perhaps. If you wish to add it too, no problem.<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; I want at minimum swap, because with it i can easily implement<br>
&gt;&gt; &gt;&gt;&gt; lock-free waiting:<br>
&gt;&gt; &gt;&gt;&gt;<br>
&gt;&gt; &gt;&gt;&gt; [ | temp |<br>
&gt;&gt; &gt;&gt;&gt;  [ locked ] whileTrue.<br>
&gt;&gt; &gt;&gt;&gt;    temp := true.<br>
&gt;&gt; &gt;&gt;&gt;    locked :=: temp.<br>
&gt;&gt; &gt;&gt;&gt;    temp<br>
&gt;&gt; &gt;&gt;&gt; ] whileTrue.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; I think this is simpler (using Eliot&#39;s notation):<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;  [locked ?:= true : false] whileFalse.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;   ... locked here ...<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt;   locked := false.<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; No temp needed, single block. well understood atomic op :).<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Yeah? Then try and implement a unconditional atomic swap using CAS.<br>
&gt;&gt;<br>
&gt;&gt; I&#39;ll look up the paper in a short while, but for now, how about:<br>
&gt;&gt;<br>
&gt;&gt;    [ | oldVal | oldVal := var. var ?:= newVal : oldVal ] whileFalse.<br>
&gt;&gt;<br>
&gt;&gt; Yes, this makes the retry loop explicit, but the retry loop exists in<br>
&gt;&gt; _any_ atomic op at some level.  It may be buried in the HW where the<br>
&gt;&gt; microcode does the retry if there is memory cache line contention or some<br>
&gt;&gt; such but it is always there.  &quot;Atomic&quot; implies blocking other threads, so<br>
&gt;&gt; that the other (blocked) threads have to retry.  In the case of the atomic<br>
&gt;&gt; op being a VM level primitive the retry loop is implicit in the scheduler,<br>
&gt;&gt; in the sense that the scheduler cannot schedule other threads for the<br>
&gt;&gt; duration of the primitive.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Again, who said, that i going to use atomic swap for loops like above?<br>
&gt;&gt;<br>
&gt;&gt; Um, your example said it? :)  Sorry if I misunderstood, but email doesn&#39;t<br>
&gt;&gt; give much context, and the loop you gave was the only context I had, so I<br>
&gt;&gt; assumed that was what you wanted to do.<br>
&gt;&gt;<br>
&gt;&gt; &gt; I simply need a guarantee from VM , that swap operation will be<br>
&gt;&gt; &gt; atomic. No less, no more.<br>
&gt;&gt; &gt; Compare-And-Swap and swap is different operations.<br>
&gt;&gt;<br>
&gt;&gt; I guess that depends on how you look at it.  I see CAS as a simple<br>
&gt;&gt; generalization of atomic swap that is _much_ more useful for implementing<br>
&gt;&gt; many different kinds of safe multi-threaded data access.  Unconditional swap<br>
&gt;&gt; works safely for booleans, but if you use it for something more complicated,<br>
&gt;&gt; like numbers, you end up in all sorts of complications.  The unconditional<br>
&gt;&gt; swap ends up &quot;leaking&quot; information into the variable that is visible to<br>
&gt;&gt; other threads in a way that is very difficult to cope with for the other<br>
&gt;&gt; threads.  Try doing a thread safe numeric increment with unconditional<br>
&gt;&gt; swap....<br>
&gt;<br>
&gt; +1.  I&#39;ve used CAS quite a bit in Cog (e.g. reimplementing<br>
&gt; signalExternalSemaphore) ad it&#39;s concise and easy-to-use.<br>
&gt;<br>
<br>
<br>
<br>
</div></div>--<br>
<div><div></div><div class="h5">Best regards,<br>
Igor Stasenko AKA sig.<br>
<br>
</div></div></blockquote></div><br>