<br><br><div class="gmail_quote">On Wed, Oct 13, 2010 at 12:58 PM, 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:56, 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 11:37 AM, Igor Stasenko &lt;<a href="mailto:siguctua@gmail.com">siguctua@gmail.com</a>&gt; wrote:<br>
&gt;&gt;<br>
&gt;&gt; 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;&gt; &gt;<br>
&gt;&gt; &gt;<br>
&gt;&gt; &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;&gt; &gt; wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Hi Igor, Eliot,<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Eliot, I&#39;m not sure I understood your comment:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; On 2010-Oct-13, at 08:55, Eliot Miranda wrote:<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; &gt; Right.  And because Smalltak can&#39;t reify variables and CAS is an<br>
&gt;&gt; &gt;&gt; &gt; operation on a variable CAS can&#39;t be implemented as a primitive on<br>
&gt;&gt; &gt;&gt; &gt; variables.  There&#39;s no way to express &quot;pass a variable to a<br>
&gt;&gt; &gt;&gt; &gt; primitive&quot;,<br>
&gt;&gt; &gt;&gt; &gt; only &quot;pass an expression (which may be the value of a variable)&quot; to a<br>
&gt;&gt; &gt;&gt; &gt; primitive&quot;.  One could do it with a primitive on an object, e.g.<br>
&gt;&gt; &gt;&gt; &gt; thisContext at: tempIndex compareWith: match andSetTo: expr, or<br>
&gt;&gt; &gt;&gt; &gt; anObject<br>
&gt;&gt; &gt;&gt; &gt; instVarAt: varIndex compareWith: match andSetTo: expr but that&#39;s<br>
&gt;&gt; &gt;&gt; &gt; soooo<br>
&gt;&gt; &gt;&gt; &gt; ugly.  Hence I think it is better done using a special assignment<br>
&gt;&gt; &gt;&gt; &gt; operator.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; I mean one can&#39;t write<br>
&gt;&gt; &gt;     | t |<br>
&gt;&gt; &gt;     self compare: t andSwap: expr<br>
&gt;&gt; &gt; because in the above the rvalue of t is passed, not it&#39;s lvalue, and cas<br>
&gt;&gt; &gt; needs to operate on an lvalue (rvalue == read value, or value of a<br>
&gt;&gt; &gt; variable;<br>
&gt;&gt; &gt; lvalue = location value, or address of a variable).  Clearly cas needs<br>
&gt;&gt; &gt; to<br>
&gt;&gt; &gt; apply to a variable, not the value in the variable.  The variable&#39;s<br>
&gt;&gt; &gt; value is<br>
&gt;&gt; &gt; compared and the variable is set to a new value if it matches.  Look at<br>
&gt;&gt; &gt; Igor&#39;s example and you&#39;ll see his primitive on Arrays passes an lvalue<br>
&gt;&gt; &gt; since<br>
&gt;&gt; &gt; the primitive takes the index of an array element.<br>
&gt;&gt; &gt; e.g. if you implemented CAS in C using functions instead of macros you&#39;d<br>
&gt;&gt; &gt; know that you couldn&#39;t do it with int cas(int var, int match, int new)<br>
&gt;&gt; &gt; but<br>
&gt;&gt; &gt; you&#39;d know that you can do it with int cas(int *var, int match, int new)<br>
&gt;&gt; &gt; and<br>
&gt;&gt; &gt; ... int v; ... cas(&amp;v, match, new)<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; Doesn&#39;t this apply to Igor&#39;s proposed atomic swap as well?  The target<br>
&gt;&gt; &gt;&gt; in<br>
&gt;&gt; &gt;&gt; Igor&#39;s example was a variable &quot;locked&quot; which was clearly meant to be<br>
&gt;&gt; &gt;&gt; visible<br>
&gt;&gt; &gt;&gt; to other threads.<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Yes.  First time I read Igor&#39;s post I on;y saw the initial<br>
&gt;&gt; &gt; &quot;| var1 var2 temp |<br>
&gt;&gt; &gt; temp := var1.<br>
&gt;&gt; &gt; var1 := var2.<br>
&gt;&gt; &gt; var2 := temp.&quot;<br>
&gt;&gt; &gt; which I rejected and didn&#39;t read further.  Now I see the :=:.  I don&#39;t<br>
&gt;&gt; &gt; like<br>
&gt;&gt; &gt; this because it doesn&#39;t map as nicely to CAS which I like using.  I like<br>
&gt;&gt; &gt; the<br>
&gt;&gt; &gt; boolean result one gets fro CAS that says the assignment either happened<br>
&gt;&gt; &gt; or<br>
&gt;&gt; &gt; it didn&#39;t.  Atomic swap is more low-level.  I then have to inspect the<br>
&gt;&gt; &gt; value<br>
&gt;&gt; &gt; the variable used to have and undo the swap if it wasn&#39;t what was<br>
&gt;&gt; &gt; expected.<br>
&gt;&gt; &gt;  So<br>
&gt;&gt; &gt;         | var |<br>
&gt;&gt; &gt;         var ?= expr : match<br>
&gt;&gt; &gt; is equivalent to<br>
&gt;&gt; &gt;         [| var scratch |<br>
&gt;&gt; &gt;         scratch := expr.<br>
&gt;&gt; &gt;         var :=: scratch.<br>
&gt;&gt; &gt;         scratch == match<br>
&gt;&gt; &gt;             ifTrue: [true]<br>
&gt;&gt; &gt;             ifFalse: [var :=: scratch. false]] valueUninterruptibly<br>
&gt;&gt; &gt; Hence I think :=: is too low-level.<br>
&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;&gt; well, once you start using valueUninterruptibly, there is no much<br>
&gt;&gt; reason to use/introduce atomic swap nor cas :)<br>
&gt;<br>
&gt; Right :)<br>
&gt;<br>
&gt;&gt;<br>
&gt;&gt; moreover, i see no trivial way to implement CAS using atomic swap,<br>
&gt;&gt; while reverse is trivial.<br>
&gt;<br>
&gt; Is it, or does it also rely on uninterruptbility?  Is this right?<br>
&gt;     v1 :=: v2<br>
&gt; is equivalent to<br>
&gt;     [ | scratch |<br>
&gt;      scratch := v1.<br>
&gt;      v1 ?= v2 : scratch] whileFalse.<br>
&gt;      v2 := scratch.<br>
&gt;<br>
<br>
</div></div>Nope! Not in all cases.<br>
<br>
If v1 and v2 having equal significance in algorithm, not just v1,<br>
then it won&#39;t work.<br>
I mean, if the above will be interrupted after leaving the loop but<br>
before you assign to v2 (v2 := scratch)<br>
and your code expects that not only v1 swapped correctly, but v2 as well,<br>
then you&#39;re in trouble.<br>
<br>
Swap is symmetric, i.e. v1 :=: v2 should be semantically equal to v2 :=: v1.<br>
But its not achievable unless its also atomic.<br>
<br>
So, i must confess (again), that CAS cannot serve as a complete<br>
replacement for atomic swap.<br>
<div class="im"><br>
<br>
&gt;<br>
&gt;&gt; &gt;From this point of view, CAS is better.<br>
&gt;&gt;<br>
&gt;&gt; &gt;&gt;<br>
&gt;&gt; &gt;&gt; If that&#39;s the case, then they both need to be implemented with a<br>
&gt;&gt; &gt;&gt; special<br>
&gt;&gt; &gt;&gt; assignment operator, and Igor and I can get back to arguing the merits<br>
&gt;&gt; &gt;&gt; of<br>
&gt;&gt; &gt;&gt; the atomic swap versus the atomic compare and swap :).  If not, then<br>
&gt;&gt; &gt;&gt; Igor&#39;s<br>
&gt;&gt; &gt;&gt; swap has a clear advantage and I guess you can both ignore the rest of<br>
&gt;&gt; &gt;&gt; this<br>
&gt;&gt; &gt;&gt; email...<br>
&gt;&gt; &gt;<br>
&gt;&gt; &gt; Um, mine /does/ use a special assignment operator, &quot;?= :&quot; :)<br>
&gt;&gt; &gt;<br>
&gt;&gt;<br>
&gt;&gt; var ?= match : expression<br>
&gt;&gt;<br>
&gt;&gt; could mean a lot of hacking in compiler. how about:<br>
&gt;&gt;<br>
&gt;&gt; var ?= { match . expression }<br>
&gt;&gt;<br>
&gt;&gt; so, you just need to introduce a new binary operator ?= &quot;CAS<br>
&gt;&gt; assignment&quot; or &quot;conditional assignment&quot;<br>
&gt;&gt; which is much simpler to hack comparing to trinary one.<br>
&gt;<br>
&gt; That&#39;s a good suggestion, bit let&#39;s see.  Personally I find  var ?= { match<br>
&gt; . expression } ok but a little flowery :)<br>
&gt;<br>
<br>
</div>Yes. But it looks more conformant to traditional ST syntax.  :)<br>
<div><div></div><div class="h5"><br>
&gt;&gt; And you can also force compiler to expect only &#39;{&#39; after ?=, so no<br>
&gt;&gt;<br>
&gt;&gt; var ?= foo<br>
&gt;&gt; var ?= #( foo )<br>
&gt;&gt; var ?= self bar<br>
&gt;&gt;<br>
&gt;&gt; will be allowed.<br>
&gt;<br>
&gt; But ?= : is no more difficult than parsing expressions within keywords.  I<br>
&gt; guess it&#39;ll look something like<br>
&gt;     conditionalAssignment: varNode<br>
&gt; &quot; var &#39;?=&#39; expression &#39;:&#39; match =&gt; ConditionalAssignmentNode.&quot;<br>
&gt; | loc start valueNode |<br>
&gt; (loc := varNode assignmentCheck: encoder at: prevMark + requestorOffset) &gt;=<br>
&gt; 0 ifTrue:<br>
&gt; [^self notify: &#39;Cannot store into&#39; at: loc].<br>
&gt; start := self startOfNextToken.<br>
&gt; self advance.<br>
&gt; self expression ifFalse: [^self expected: &#39;Expression&#39;].<br>
&gt; newValueNode := parseNode.<br>
&gt; (self match: #colon) ifFalse: [^self expected: &#39;colon&#39;].<br>
&gt; self advance.<br>
&gt; self expression ifFalse: [^self expected: &#39;Expression&#39;].<br>
&gt; parseNode := ConditionAssignmentNode new<br>
&gt; variable: varNode<br>
&gt; value: valueNode<br>
&gt; match: valueNode<br>
&gt; from: encoder<br>
&gt; sourceRange: (start to: self endOfLastToken).<br>
&gt; varNode nowHasDef.<br>
&gt; ^true<br>
<br>
</div></div>Okay, if you think its easy. No problem.<br>
But i am a bit worrying about parsing &amp; clearly reading following:<br>
<br>
boo ?= #foo:bar: : #baz: .<br>
<br>
colon seems not a good choice here.<br></blockquote><div><br></div><div>OK, how about</div><div>    boo ?= #foo:bar: ? #baz</div><div>?</div><div><br></div><div><br></div><div>The main problem we have now is finding space in the bytecode.  At least for me, the remaining bytecodes have all been taken by Newspeak (and I&#39;m eager to get Newspeak running on Cog).  So my plan is new object representation, new bytecode set, then cas.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">
<br>
&gt;&gt;<br>
&gt;&gt;<br>
&gt;&gt; &gt;&gt;<br>
<font color="#888888"><br>
<br>
--<br>
</font><div><div></div><div class="h5">Best regards,<br>
Igor Stasenko AKA sig.<br>
<br>
</div></div></blockquote></div><br>