www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Ensuring allocation isn't thread-local?

reply Jaime <benjamin.i.mccann gmail.com> writes:
Howdy.

How do I make sure data isn't allocated thread-local, if I also 
want to immediately use it in a thread-local way, because, for 
instance, I happen to already possess its intended mutex, which 
was allocated before it?

Is this sufficient? Also, is it even something to worry about?

```d
// for classes
cast(T) new shared(T)(...)
// otherwise
cast(T*) new shared(T)(...)
```

For example, this is the full relevant excerpt of my WIP, 
untested code so far:

```d
private struct Message {
     ulong sender;
     Variant payload;
}

private struct MessageQueue {
     DList!Message* data;
     Mutex mutex;
     Condition enqueued; // <-- Should fire on insertion.
}

// A queue for each recipient thread.
private shared(MessageQueue[ulong]) messageTable;
private Mutex tableMutex; // <-- Protects messageTable.

/*
This function should only be called by a thread holding 
tableMutex.
We don't acquire tableMutex in the function itself
because maybe the caller wants to do something else with it too.
*/
private ref MessageQueue getQueue(ulong recipient) {
     auto nsMessageTable = cast(MessageTable[ulong]*) 
&messageTable;
     MessageQueue* qptr = recipient in *nsMessageTable;
     if (qptr is null) {
         auto newMutex = cast(Mutex) new shared(Mutex);
         qptr = &((*nsMessageTable)[recipient] = MessageQueue(
             /*
             This is the part where I instantiate stuff as shared
             and then immediately cast away sharing
             because we're already holding tableMutex.
             */
             cast(DList!Message*) new shared(DList!Message),
             newMutex,
             cast(Condition) new shared(Condition)(newMutex)
         ));
     }
     return *qptr;
}
```

(I know it's probably not a good idea to try to implement an 
alternative to std.concurrency, and I should just use 
std.concurrency instead, but I have a good reason, and that 
reason is hands-on learning.)

Anyway, yeah, to reiterate: do I have the right idea here? That 
is:
A) Do I need to worry about data being / not being in 
thread-local storage?
B) If so, how do I make sure it's not there? Will my approach so 
far suffice?
C) If not, what's a better way?

Thanks in advance for any guidance.
Jan 22 2022
parent reply Adam D Ruppe <destructionator gmail.com> writes:
On Saturday, 22 January 2022 at 18:55:30 UTC, Jaime wrote:
 A) Do I need to worry about data being / not being in 
 thread-local storage?
No. Anything allocated with `new` is not thread local... and even if it was, you can send the pointer to other threads anyway. The only things in thread local storage are the direct values in the non-shared global variables. What they actually point to is just generally on the main heap just like anything else.
Jan 22 2022
parent Jaime <benjamin.i.mccann gmail.com> writes:
On Saturday, 22 January 2022 at 19:06:38 UTC, Adam D Ruppe wrote:
 No. Anything allocated with `new` is not thread local... and 
 even if it was, you can send the pointer to other threads 
 anyway.

 The only things in thread local storage are the direct values 
 in the non-shared global variables. What they actually point to 
 is just generally on the main heap just like anything else.
Thanks for the response. Good to know.
Jan 22 2022