2015-10-12 16:46 GMT+02:00 Clément Bera <bera.clement@gmail.com>:
2015-10-12 15:33 GMT+02:00 phil@highoctane.be <phil@highoctane.be>:
On Mon, Oct 12, 2015 at 3:20 PM, Thierry Goubier < thierry.goubier@gmail.com> wrote:
Hi Sebastià n,
2015-10-12 13:53 GMT+02:00 Sebastián Krynski <skrynski@gmail.com>:
Hello my name is Sebastián Krynski from Buenos Aires, Argentina. Just writing to let you know that I'm starting to work on adding an atomic swap operator in Pharo , guaranteed not to be interrupted by the VM. The operator will be used this way:
a :=: b
meaning 'swap variable a with variable b'.
Why a cryptic, special syntax? The compiler could inline an explicit message send which would make the intent clear.
See previous discussions about <=> indeed.
a atomicSwapWith: b.
Well, anyway, the compiler has to do something special there.
Could we have something like...
[ | temp | temp := a. a := b. b := a ] atomic
? Would a compiler be able to merge that in a swap instruction? And make another type of processing for a different code inside the block?
We have Mutex>>critical: aBlock etc.
Why not Atomic>>do: aBlock ?
Honestly this block followed by atomic is very confusing IMO. That means that the compiler has to raise an error if it did not succeed to compile the block in a single cpu instruction, i.e., a single bytecode that compiles to a single cpu instruction. For example: [ | temp | temp := a. a := b. b := a. self foo ] atomic has to raise a compilation error as the block cannot be compiled in a single instruction. Overall very few instructions in specific order can be compiled in a such a block.
Oh, Clement, compilers can do a lot more than that ;) This one would be easy to do, even if a bit ad-hoc (it's just a simple refactoring pattern to recognize, after all). Let me see... '[ | `x | `x := `y. `y := `z. `z := `x] atomic' RBParseTreeSearcher treeMatching: '[ | `x | `x := `y. `y := `z. `z := `x]' in: (RBParser parseExpression: '[ | temp | temp := a. a := b. b := temp ] atomic') Note that it fails on all the wrong variants you wrote, which leads me to spend more time if I got my pattern right :( But I was considering that it would be either an atomic swap (if the compiler recognize the sequence ... I usually see test_and_set as the primitive, and nowadays everybody saying transactional memory instructions are the way to go) or a critical if it can't be compiled as an atomic instruction (in short, same semantics? but different speeds... I think the trade-off is acceptable)
Atomic>>#do: can work but the argument block needs to be compiled in a single instruction so the bytecode compiler has to aware of the syntax based on the selector anyway. For example, in: anAtomic do: [ | temp | temp := a. a := b. b := a ] then the compiler has to compile the block specifically to have single instruction, even if the call to anAtomic is done in the runtime.
Same as the atomic case above. Atomic should be a singleton; no need to create instances of Atomic, even conceptually.
On the other hand a new special selector as #atomicSwapWith:, in a similar way to #ifTrue:ifFalse:, is definitely doable and easy to implement. If you think it's more readable then it's the way to go. It does not extend the syntax so I think it can be done like that for the experiment as it is simpler to implement.
I think this is an important point. Marcus, can something special like that be done via a compiler plugin or a MetaLink? This would be really convenient. Thierry
Would indeed be more readable than :=:
Phil
In order to do this I will be modifying the VM and the Compiler .
Good luck. This is an important step.
I'm working under the direction of INRIA and Gabriela Arévalo.
Welcome!
Thierry