On 04 Apr 2014, at 19:29, Igor Stasenko <siguctua@gmail.com> wrote:
On 4 April 2014 18:31, Sven Van Caekenberghe <sven@stfx.eu> wrote: Just for the sake of discussion, you try to prevent interruptions by using assignments, right ? But you still need #== which seems like a (potential) message send, which brings us back to the other arguments in this thread. Furthermore, the dummy value must be different for each of the processes/threads entering, no ?
dummy is placeholder used solely to detect that counter is 'locked' via #== comparison.. can be any object not really matters if you share it among processes or not, since it carries no state.
#== , whileTrue: .. as well as any other message sends potentially is subject of being interrupted.. but there's nothing wrong with it, as long as two assignments (in a row) don't have chance to be interrupted.
All this is quite interesting (and makes my head hurt), maybe we should implement this as a helper class in the image, along side the other lock free stuff ?
On 03 Apr 2014, at 01:34, Igor Stasenko <siguctua@gmail.com> wrote:
so, lock-free counter can be something like:
atomicIncr | oldValue |
[ oldValue := self atomicSwapCounterWithDummy. oldValue == dummy ] whileTrue: [ Processor yield ].
^ counter := oldValue + 1
atomicSwapCounterWithDummy | old | old := counter. counter := dummy. ^ old
so you use dummy to block anyone from setting the new value unless you set it. dummy can be any object (not a number in your care), and lastly, once you assign a new value, you effectively release a "lock" :)
Processor yield is mainly attempt to avoid busy-waiting.
On 3 April 2014 01:28, Igor Stasenko <siguctua@gmail.com> wrote:
On 3 April 2014 00:11, Sven Van Caekenberghe <sven@stfx.eu> wrote: Hi,
Is it possible to have a simple lock-free atomic counter in Pharo 3.0 ?
nextId ^ idCounter := idCounter + 1
Or is it still possible that two process entering this code can mess things up ?
#+ is a message send. So technically, if you will be interrupted at the point of returning a result from it, then somebody else could run #nextId without notice, as result you will get 2 processes returning same value from #nextId. (and increasing numbers of concurrent processes will produce even more surprising results :)
I vaguely remember a discussion about that long ago...
assignment is atomic.. the one which i use in atomic queue impl., but it is hidden, undocumented VM implementation detail :) e.g.:
oldA := a. a := newA. .. actually can be any series of it, as long as nothing else there (no message sends)
x:= a. y:=b. z := c. w := e.
will be performed atomically.
TIA,
Sven
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.
-- Best regards, Igor Stasenko.