Bug 12133 – Relaxed read-modify-write for shared lvalues

Status
NEW
Severity
enhancement
Priority
P4
Component
druntime
Product
D
Version
D2
Platform
All
OS
All
Creation time
2014-02-11T15:31:31Z
Last change time
2024-12-07T13:33:24Z
Keywords
pull
Assigned to
No Owner
Creator
Stanislav Blinov
Moved to GitHub: dmd#17128 →

Comments

Comment #0 by stanislav.blinov — 2014-02-11T15:31:31Z
TDPL prohibits using operators on shared variables. I.e. this: shared int i; ++i; is illegal. It is stated that core.atomic should be used instead: shared int i; atomicOp!"+="(i, 1); However, there are cases when this can introduce unnecessary performance loss: e.g. private shared variables that are only ever accessed under a lock. I'm proposing to add two functions to core.atomic to allow for operations on shared variables without atomicOp()'s performance penalties: 1) localOp: performs and acquire-op-release, e.g.: shared int i; auto v = localOp!"+="(i, 1); Useful when there's still need for ordering. Though I don't really like the name "localOp". 2) assumeLocal: converts shared lvalue to a non-shared lvalue, e.g: shared int i; ++assumeLocal(i);
Comment #1 by andrej.mitrovich — 2014-02-11T15:36:23Z
(In reply to comment #0) > 2) assumeLocal: > > converts shared lvalue to a non-shared lvalue, e.g: > > shared int i; > ++assumeLocal(i); shared int i; ++cast()i;
Comment #2 by stanislav.blinov — 2014-02-11T15:39:09Z
(In reply to comment #1) > shared int i; > ++cast()i; cast()i would cast away everything, including const, silently :)
Comment #3 by andrej.mitrovich — 2014-02-11T15:49:51Z
(In reply to comment #2) > (In reply to comment #1) > > > shared int i; > > ++cast()i; > > cast()i would cast away everything, including const, silently :) Oops. Maybe something like: ----- template Unshared(T) { static if (is(T U == shared inout const U)) alias Unshared = U; else static if (is(T U == shared inout U)) alias Unshared = U; else static if (is(T U == shared const U)) alias Unshared = U; else static if (is(T U == shared U)) alias Unshared = U; else alias Unshared = T; } ref unshared(T)(ref T var) { return *cast(Unshared!T*)&var; } void main() { shared int x; ++unshared(x); assert(x == 1); } ----- Unshared code based off of Unqual.
Comment #4 by andrej.mitrovich — 2014-02-11T15:50:29Z
(In reply to comment #3) > template Unshared(T) > { > static if (is(T U == shared inout const U)) alias Unshared = U; > else static if (is(T U == shared inout U)) alias Unshared = U; > else static if (is(T U == shared const U)) alias Unshared = U; > else static if (is(T U == shared U)) alias Unshared = U; > else alias Unshared = T; > } Uhh that should teach me to copy-paste, the RHS should simply strip shared, not strip all the qualifiers.
Comment #5 by andrej.mitrovich — 2014-02-11T15:51:03Z
(In reply to comment #4) > Uhh that should teach me to copy-paste, the RHS should simply strip shared, not > strip all the qualifiers. Fixed: template Unshared(T) { static if (is(T U == shared inout const U)) alias Unshared = inout const U; else static if (is(T U == shared inout U)) alias Unshared = inout U; else static if (is(T U == shared const U)) alias Unshared = const U; else static if (is(T U == shared U)) alias Unshared = U; else alias Unshared = T; }
Comment #6 by stanislav.blinov — 2014-02-11T15:57:16Z
Something a bit less involving :) ref auto assumeLocal(T)(ref shared T var) @trusted pure nothrow { return *cast(T*)&var; } I should've probably noted that I already have implementations for both functions in mind, just not in the state of pull request yet. But comments, suggestions, objections and improvements are key!
Comment #7 by stanislav.blinov — 2014-02-11T16:01:43Z
See also the discussion thread: http://forum.dlang.org/thread/[email protected]
Comment #8 by stanislav.blinov — 2014-02-14T22:15:42Z
Comment #9 by andrei — 2014-03-15T20:38:58Z
localOp should be atomicOpRelaxed
Comment #10 by robert.schadek — 2024-12-07T13:33:24Z
THIS ISSUE HAS BEEN MOVED TO GITHUB https://github.com/dlang/dmd/issues/17128 DO NOT COMMENT HERE ANYMORE, NOBODY WILL SEE IT, THIS ISSUE HAS BEEN MOVED TO GITHUB