Jump to page: 1 2
Thread overview
[Issue 4419] New: __gshared static in class has no effect
Jul 03, 2010
torhu@yahoo.com
Feb 23, 2011
Trass3r
Feb 23, 2011
Trass3r
Feb 23, 2011
Trass3r
Oct 04, 2012
Fawzi Mohamed
Dec 20, 2012
Andrej Mitrovic
Jul 28, 2013
yebblies
Aug 24, 2013
Puneet Goel
Sep 13, 2013
Rory
Sep 13, 2013
Andrej Mitrovic
Sep 13, 2013
Rory
Sep 13, 2013
Andrej Mitrovic
July 03, 2010
http://d.puremagic.com/issues/show_bug.cgi?id=4419

           Summary: __gshared static in class has no effect
           Product: D
           Version: D2
          Platform: x86
        OS/Version: Windows
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DMD
        AssignedTo: nobody@puremagic.com
        ReportedBy: torhu@yahoo.com


--- Comment #0 from torhu@yahoo.com 2010-07-03 04:11:02 PDT ---
DMD 2.047.

Putting __gshared in front of static has no effect.  Putting it after works.

This example prints "0", instead of the expected "1":

---
import core.thread;
import std.stdio;

class A { __gshared static int x; }


void main()
{
    A.x = 1;
    Thread t = new Thread({ writeln(A.x); });
    t.start();
}
---

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 23, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4419


Trass3r <mrmocool@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |mrmocool@gmx.de
           Severity|normal                      |major


--- Comment #1 from Trass3r <mrmocool@gmx.de> 2011-02-23 02:51:16 PST ---
This isn't restricted to classes:

__gshared static int a;
static __gshared int b;

> dmd -c -vtls foo.d
foo(1): a is thread local

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 23, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4419


Trass3r <mrmocool@gmx.de> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Platform|x86                         |All
         OS/Version|Windows                     |All


--- Comment #2 from Trass3r <mrmocool@gmx.de> 2011-02-23 06:13:36 PST ---
Ok, part of the magic happens in StorageClassDeclaration::semantic() in
attrib.c (which btw duplicates setScope!):

StorageClass scstc = sc->stc;

/* These sets of storage classes are mutually exclusive,
 * so choose the innermost or most recent one.
 */
if (stc & (STCauto | STCscope | STCstatic | STCextern | STCmanifest))
    scstc &= ~(STCauto | STCscope | STCstatic | STCextern | STCmanifest);
if (stc & (STCauto | STCscope | STCstatic | STCtls | STCmanifest | STCgshared))
    scstc &= ~(STCauto | STCscope | STCstatic | STCtls | STCmanifest |
STCgshared);
...
scstc |= stc;

In b's case sc->stc is 0, thus nothing gets truncated and scstc = stc, which is ok cause stc correctly was set to STCstatic | STCgshared before.

In a's case however sc->stc == STCgshared, so it gets cut out by the second if statement. Then scstc is set to stc which is equal to STCstatic.


So there are in fact 4 issues here:
1) Why is static and __gshared mutually exclusive, doesn't __gshared imply
static?
2) Why isn't shared handled in that list?
3) Why the difference regarding to the scopes? According to my debug view they
are perfectly identical except for the storage class.
4) Why the difference in stc?

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
February 23, 2011
http://d.puremagic.com/issues/show_bug.cgi?id=4419



--- Comment #3 from Trass3r <mrmocool@gmx.de> 2011-02-23 06:50:26 PST ---
Ok 3 and 4 are caused by Parser::parseDeclDefs' layout.

If static comes first "case TOKstatic" is reached, TOKstatic is added and at label Lstc2 TOKgshared is added. Then a single StorageClassDeclaration is constructed with STCstatic|STCgshared.

If gshared comes first a chain of StorageClassDeclarations is constructed:
StorageClassDeclaration(gshared, StorageClassDeclaration(static, int a))

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
October 04, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=4419


Fawzi Mohamed <fawzi@gmx.ch> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |fawzi@gmx.ch


--- Comment #4 from Fawzi Mohamed <fawzi@gmx.ch> 2012-10-04 15:11:55 PDT ---
I just fell in this bug, I find it *very* ugly, initially I though __gshared was fully broken, and one had to use shared (that works).

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
December 20, 2012
http://d.puremagic.com/issues/show_bug.cgi?id=4419


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

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


--- Comment #5 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2012-12-20 14:37:29 PST ---
> 1) Why is static and __gshared mutually exclusive, doesn't __gshared imply
static?

It implies the field is a property of the type, not the instance. It's *like* static, but static == TLS, __gshared == global. I think maybe the OP thought __gshared was a modifier you can apply to static, but it's not, __gshared can be (and should be) used alone.

Both "static __gshared" and "__gshared static" should be rejected, because you can't ask the compiler "make this field thread-local *and* global, and make it a property of the type". It's either TSL or global, not both.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
July 28, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4419


yebblies <yebblies@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |yebblies@gmail.com


--- Comment #6 from yebblies <yebblies@gmail.com> 2013-07-28 15:28:04 EST ---
I agree that __gshared should imply static.  I was very surprised to find this was not how it works.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
August 24, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4419


Puneet Goel <puneet@coverify.org> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |puneet@coverify.org


--- Comment #7 from Puneet Goel <puneet@coverify.org> 2013-08-24 07:37:52 PDT ---
(In reply to comment #5)
> > 1) Why is static and __gshared mutually exclusive, doesn't __gshared imply
> static?
> 
> It implies the field is a property of the type, not the instance. It's *like* static, but static == TLS, __gshared == global. I think maybe the OP thought __gshared was a modifier you can apply to static, but it's not, __gshared can be (and should be) used alone.
> 
> Both "static __gshared" and "__gshared static" should be rejected, because you can't ask the compiler "make this field thread-local *and* global, and make it a property of the type". It's either TSL or global, not both.

But I see both "static __gshared" and "__gshared static" used in phobos as well as druntime. Many of this usages I believe should be buggy!

See....

$ find . -type f -exec grep -nH -e "__gshared static" {} +
./phobos/std/parallelism.d:1039:    __gshared static size_t nextInstanceIndex =
1;
./phobos/std/parallelism.d:3271:    __gshared static TaskPool pool;
./druntime/src/core/thread.d:3862:            __gshared static fp_t
finalHandler = null;

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 13, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4419


Rory <rjmcguire@gmail.com> changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |rjmcguire@gmail.com


--- Comment #8 from Rory <rjmcguire@gmail.com> 2013-09-13 03:34:04 PDT ---
(In reply to comment #6)
> I agree that __gshared should imply static.  I was very surprised to find this was not how it works.

There is no way that shared and static are the same. is __gshared so different from shared?

sometimes I need to make a class member shared so that any thread can read/write to it, but I need the class to have multiple instances.

The exact example is a class that contains a threadsafe queue which multiple threads wait for new tasks by reading and multiple threads add new tasks. I'd hate to have to always make these static.

Whats interesting about dmd.2.063.2 is that the below makes a shared instance
per class:
class MyClass {
    shared chan!bool ready;
    this() {
        ready = makeChan!bool(1);
    }
}
BUT:
class MyClass {
    shared chan!bool ready = makeChan!bool(1);
}

creates a static instance which is shared amoungst all classes and sub classes.

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
September 13, 2013
http://d.puremagic.com/issues/show_bug.cgi?id=4419



--- Comment #9 from Andrej Mitrovic <andrej.mitrovich@gmail.com> 2013-09-13 06:44:41 PDT ---
(In reply to comment #8)
> class MyClass {
>     shared chan!bool ready = makeChan!bool(1);
> }
> 
> creates a static instance which is shared among all classes and sub classes.

I can't reproduce this, can you paste what 'chan' is, or just paste the full example? E.g.:

-----
class C
{
    shared bool ready = false;
    static shared bool statReady = false;
}

void main()
{
    auto a = new C;
    auto b = new C;
    a.ready = true;
    assert(b.ready == false);
    assert(&a.ready !is &b.ready);

    a.statReady = true;
    assert(b.statReady == true);
    assert(&a.statReady is &b.statReady);
}
-----

-- 
Configure issuemail: http://d.puremagic.com/issues/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
« First   ‹ Prev
1 2