Some questions about atomic in cl-gserver
hxzrx opened this issue · comments
Hi,
As I checked some codes of cl-gserver
, there're several files use atomic operation.
atomic.lisp
, which definesatomic-cas
, in this method definition,(when cas-result (setf ....)
is really redundant,cas
can make sure it's been set ifcas
succeeds. Furthermore, thesetf
aftercas
may be dangerous, this is usually a trap and is hard to debug.router.lisp
, which definesmake-round-robin-strategy
, this function returns a lambda which always returns thenew
value, however, thecas
operation may fail and leave theatomic-integer
not changed, this might make the returned value not what you want.actor-context.lisp
, in the definition of%add-actor
,cas
can make sure that a new actor will be successfully added in a loop. And finally, in the definition of%remove-actor
, a singlecas
can not make sure it's removed successfully without a loop.
Since I just grepped the lisp file with atomic, and you may have some codes in other files which make sure all these are OK. But if you can confirm that these functions should get enhancement, I'm glad to make a patch.
Hi.
Those are valid points.
For 1., are you sure the cas operation sets the value to the place (slot-value ref 'cell)
even though a dynamic variable is used?
Generally there are no formal proves that the cas operations are OK. They are 'only' empirically tested. But this is of course not exhaustive.
So yes, please make a patch.
I would think though that using cas
should be as simple as possible and the nitty-gritty bits should be abstracted away.
So, i.e. the functions %add-actor
, %remove-actor
preferably don't deal with loops.
Hi. Those are valid points.
For 1., are you sure the cas operation sets the value to the place
(slot-value ref 'cell)
even though a dynamic variable is used?Generally there are no formal proves that the cas operations are OK. They are 'only' empirically tested. But this is of course not exhaustive.
So yes, please make a patch.
Yes, for dynamic variables. cas
is rather low level, in fact, it will expand to the actual place of the lower level swap object of the higher level variable, so, it's only depends on what the actual object the variable currently binds to.
I would think though that using
cas
should be as simple as possible and the nitty-gritty bits should be abstracted away. So, i.e. the functions%add-actor
,%remove-actor
preferably don't deal with loops.
I believe so, atomic operations in %add-actor
, %remove-actor
just do something like enqueue or dequeue, %add-actor
and %remove-actor
themselves should keep simple. Furthermore, either add-actor
or remove-actor
will hardly be the bottleneck, using a lock will make the code more concise, I think, but this is another style.
For this issue, I will make an PR for make-round-robin-strategy
and atomic-cas
as soon as possible.
Furthermore, either add-actor or remove-actor will hardly be the bottleneck, using a lock will make the code more concise, I think, but this is another style.
I wouldn't care if locks are used, however not directly in actor-context package. If you'd wrap an array in a separate package and put locking code around it, like a 'concurrent-array' primitive, that would be fine as well.
Maybe there is something out there already.
Before I create a PR for atomic-cas
, I must make sure how the special variable *the-ref*
is designed.
The special variables cas
's logic is different from that directly using the cas-place such as (slot-value ref 'cell)
.
In the definition of atomic-cas
, *the-ref*
binds to the VALUE of the value of the cell
slot first. In ccl, for example, conditional-store
will invoke ccl::%symbol-binding-address
with the symbol of *the-ref*
to get the address, which has nothing to do with the original cell
place, and thus the cell
's value will not be modified. That's why you have to setf
the slot value when cas
succeeds.
Since *the-ref*
is only used in atomic.lisp
, I don't know if it's Ok if I remove this special variable and directly use the cell's place in atomic-cas
.
It's ok to remove it if not really needed, considering the 'atomics' cas works consistently across the implementations.
Can this be closed with the PR?
Can this be closed with the PR?
Yeah, please close this.
Fixed with 8bac870