www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Thread-local Member Variables?

reply dsimcha <dsimcha yahoo.com> writes:
Should there be a way, in D, to create a variable that's local to both a
thread and a class instance?  For example:

class Foo {
    __thread uint num;
}

num would basically be a reference to thread-local storage, with a new one
created for every instance of Foo.  Is there a (non-hacky) way to do this
already?
Jan 13 2010
next sibling parent Jason House <jason.james.house gmail.com> writes:
dsimcha Wrote:

 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:
 
 class Foo {
     __thread uint num;
 }
 
 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this
already?

D1 or D2? For D2, this would only matter for shared and __gshared variables. For shared variables, it makes about as much sense as logical const. I'm going to guess that logical shared won't make it into D2. I have no idea about __gshared, but I'm going to guess that functionality won't grow beyond its current state. For some reason, I think D had __thread at one time...
Jan 13 2010
prev sibling next sibling parent Sean Kelly <sean invisibleduck.org> writes:
dsimcha Wrote:

 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:
 
 class Foo {
     __thread uint num;
 }
 
 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this
already?

I'd think that static member variables already work this way. I can't see this working for class instance variables though--the amount of storage required would vary based on the number of executing threads.
Jan 13 2010
prev sibling next sibling parent reply "Nick Sabalausky" <a a.a> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:hikj7a$18lq$1 digitalmars.com...
 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
    __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this 
 already?

How would that be different from doing this in D2?: class Foo { uint num; } 'num' isn't declared as static, so a new one is created for every instance of Foo, and 'shared' isn't used so it's thread local. Am I missing something?
Jan 13 2010
next sibling parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Nick Sabalausky (a a.a)'s article
 "dsimcha" <dsimcha yahoo.com> wrote in message
 news:hikj7a$18lq$1 digitalmars.com...
 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
    __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this
 already?

class Foo { uint num; } 'num' isn't declared as static, so a new one is created for every instance of Foo, and 'shared' isn't used so it's thread local. Am I missing something?

No, the thread-local by default thing only applies to globals and statics.
Jan 13 2010
prev sibling parent Jason House <jason.james.house gmail.com> writes:
Nick Sabalausky Wrote:

 "dsimcha" <dsimcha yahoo.com> wrote in message 
 news:hikj7a$18lq$1 digitalmars.com...
 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
    __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this 
 already?

How would that be different from doing this in D2?: class Foo { uint num; } 'num' isn't declared as static, so a new one is created for every instance of Foo, and 'shared' isn't used so it's thread local. Am I missing something?

Yes :( Only globals and statics are explicitly thread local. Everything else is really just a side effect of the type system. Except for statics and globals, everything else is allocated/accessed in the same way. If an instance is thread local, then its (unadorned) members must also be. Both shared and immutable can be passed between threads. Those modifiers are transitive, so the free sharing applies to both the instance and its members.
Jan 13 2010
prev sibling next sibling parent reply "Craig Black" <craigblack2 cox.net> writes:
"dsimcha" <dsimcha yahoo.com> wrote in message 
news:hikj7a$18lq$1 digitalmars.com...
 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
    __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this 
 already?

I need the same feature, but I don't really see an efficient way to do this in the language itself. It is probably better relegated to a template. Also, rather than giving all threads access, I would limit access to each "thread-local" variable to a thread pool of constant size. In other words, only threads in a particular thread pool could access this variable. This way, the variable can be represented as an array that never needs resizing, where each thread in the pool has an index to an element in the array. -Craig
Jan 13 2010
parent dsimcha <dsimcha yahoo.com> writes:
== Quote from Craig Black (craigblack2 cox.net)'s article
 "dsimcha" <dsimcha yahoo.com> wrote in message
 news:hikj7a$18lq$1 digitalmars.com...
 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
    __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new one
 created for every instance of Foo.  Is there a (non-hacky) way to do this
 already?

in the language itself. It is probably better relegated to a template. Also, rather than giving all threads access, I would limit access to each "thread-local" variable to a thread pool of constant size. In other words, only threads in a particular thread pool could access this variable. This way, the variable can be represented as an array that never needs resizing, where each thread in the pool has an index to an element in the array. -Craig

Yea, this is probably something that should be implemented in a library, not the core language. I've been thinking about it, but I don't see any way to do it **efficiently**. Some obvious but flawed ways: 1. In each class instance, have a hash table of variable[thread ID]. Problem: Requires synchronization when adding a thread. 2. In each class declaration have a static thread-local hash table of variable[class instance]. The problem with this is that this creates a reference to the class instance, which never gets GC'd. Even with weak references, the hash table entries would eventually need to be cleaned up.
Jan 13 2010
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 13 Jan 2010 08:52:42 -0500, dsimcha <dsimcha yahoo.com> wrote:

 Should there be a way, in D, to create a variable that's local to both a
 thread and a class instance?  For example:

 class Foo {
     __thread uint num;
 }

 num would basically be a reference to thread-local storage, with a new  
 one
 created for every instance of Foo.  Is there a (non-hacky) way to do  
 this already?

Reading all the responses, it looks like what you want this to apply only when Foo is marked as shared? Because without the __thread denotation (and without having a shared(Foo) instance), num is already thread local and one-per-instance. Do you have a use case for something like this? Maybe there's another way. I don't see any reason to have language support for this since it's not simply a fight with the type system, as logical const is. You're looking at least at adding a hash-table per thread. The GC will also have to be involved to clean up the hash table when instances go away. -Steve
Jan 14 2010