www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - [Issue 12133] New: Relaxed read-modify-write for shared lvalues

reply d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133

           Summary: Relaxed read-modify-write for shared lvalues
           Product: D
           Version: D2
          Platform: All
        OS/Version: All
            Status: NEW
          Severity: enhancement
          Priority: P2
         Component: druntime
        AssignedTo: nobody puremagic.com
        ReportedBy: stanislav.blinov gmail.com


--- Comment #0 from Stanislav Blinov <stanislav.blinov gmail.com> 2014-02-11
15:31:31 PST ---
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);

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 11 2014
next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133


Andrej Mitrovic <andrej.mitrovich gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrej.mitrovich gmail.com


--- Comment #1 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-02-11
15:36:23 PST ---
(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; -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #2 from Stanislav Blinov <stanislav.blinov gmail.com> 2014-02-11
15:39:09 PST ---
(In reply to comment #1)

 shared int i;
 ++cast()i;

cast()i would cast away everything, including const, silently :) -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #3 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-02-11
15:49:51 PST ---
(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. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #4 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-02-11
15:50:29 PST ---
(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. -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #5 from Andrej Mitrovic <andrej.mitrovich gmail.com> 2014-02-11
15:51:03 PST ---
(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; } -- Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email ------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #6 from Stanislav Blinov <stanislav.blinov gmail.com> 2014-02-11
15:57:16 PST ---
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!

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133



--- Comment #7 from Stanislav Blinov <stanislav.blinov gmail.com> 2014-02-11
16:01:43 PST ---
See also the discussion thread:

http://forum.dlang.org/thread/moyyibrpnnmrrovylkui forum.dlang.org

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 11 2014
prev sibling next sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133


Stanislav Blinov <stanislav.blinov gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Keywords|                            |pull


--- Comment #8 from Stanislav Blinov <stanislav.blinov gmail.com> 2014-02-14
22:15:42 PST ---
Pull request for assumeLocal():
https://github.com/D-Programming-Language/druntime/pull/724

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Feb 14 2014
prev sibling parent d-bugmail puremagic.com writes:
https://d.puremagic.com/issues/show_bug.cgi?id=12133


Andrei Alexandrescu <andrei erdani.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |andrei erdani.com


--- Comment #9 from Andrei Alexandrescu <andrei erdani.com> 2014-03-15 20:38:58
PDT ---
localOp should be atomicOpRelaxed

-- 
Configure issuemail: https://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
Mar 15 2014