<div dir="ltr">Hi Sven,<div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 2, 2014 at 3:11 PM, Sven Van Caekenberghe <span dir="ltr">&lt;<a href="mailto:sven@stfx.eu" target="_blank">sven@stfx.eu</a>&gt;</span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">Hi,<br>
<br>
Is it possible to have a simple lock-free atomic counter in Pharo 3.0 ?<br>
<br>
nextId<br>
  ^ idCounter := idCounter + 1<br>
<br>
Or is it still possible that two process entering this code can mess things up ?<br></blockquote><div><br></div><div>OK, but it&#39;s a real hack ;-).</div><div><br></div><div>In the current Interpreter, Stack and Cog VMs this will work fine up to 63-bits because non-failing primitives are not suspension points in the VM /except/ for the Semaphore primitives.  </div>
<div><br></div><div>If the counter is initialized to 0, at first, there won&#39;t even be a send since either the interpreter will evaluate special selector #+ on SmallInteger without performing a send, or machine code will evaluate the inlined code for SmallInteger #+ without doing a send.</div>
<div><br></div><div>Once the counter overflows into LargePositveInteger but is within 63-bits, there will be sends but these will always be of primitive 21 (LargePositiveInteger&gt;&gt;#+ uses primitive 21, which does 64-bit /signed/ arithmetic but nothing larger, hence works up to 63-bit LargePositiveIntegers).</div>
<div><br></div><div>Once beyond 63 bits the primitive will fail and there will be a suspension point in LargePositiveInteger&gt;&gt;#+ before it calls Integer&gt;&gt;#+, which will call digitAdd:.</div><div><br></div><div>
You should be able to test this.  Try evaluating this one:</div><div><br></div><div>| counter proc |</div><div>counter := 0.</div><div>proc := [[counter := counter + 1. true] whileTrue] newProcess.</div><div>proc priority: Processor activePriority - 1.</div>
<div>proc resume.</div><div>[(Delay forSeconds: 1) wait.</div><div> proc suspendedContext method ~~ thisContext method ifTrue: [proc suspend. self halt]] repeat</div><div><br></div><div><br></div><div>Now try and evaluate this one:</div>
<div><div>| counter proc |</div><div>counter := 1 bitShift: 64.</div><div>proc := [[counter := counter + 1. true] whileTrue] newProcess.</div><div>proc priority: Processor activePriority - 1.</div><div>proc resume.</div><div>
[(Delay forSeconds: 1) wait.</div><div> proc suspendedContext method ~~ thisContext method ifTrue: [proc suspend. self halt]] repeat</div></div><div><br></div><div>The second one halts almost immediately.  You can fix this by changing LargePositiveInteger&gt;&gt;#+ to use the primitive frm the large integer arithmetic plugin, which will not fail until it runs out of memory.</div>
<div><br></div><div>So if you really /must/ go this route you /can/ get away with it.  But on your own head be it ;-)</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">

<br>
I vaguely remember a discussion about that long ago...<br>
<br>
TIA,<br>
<br>
Sven<br>
</blockquote></div><br><br clear="all"><div><br></div>-- <br>best,<div>Eliot</div>
</div></div>