Addresses of Thread Local Storage Variables

C++ - Where are thread_local variables stored?

1. As I understand, both threads will get their own copy of this variable, correct?
Yes. Each thread gets its own copy of the thread_local variable.

2. Where exactly is the thread local variable stored in memory? If data segment, how exactly does the right variable gets picked up during execution?
thread_local is the implementation of the Thread Local Storage concept. TLS is implemented as a table of slots withing each thread object. Each thread having its own copy of the table. For e.g in Windows implementation of TLS this table is within the Thread Information Block of a thread. When a global/static variable is declared as thread_local, it would get associated with a table slot of each thread at the same offset. When the thread_local variable is accessed by a thread then using the current thread context, the thread's own copy of the variable associated with the table slot within this thread object is accessed. Please check this link for more detail on TLS implementation. https://en.wikipedia.org/wiki/Thread-local_storage

Access thread-local from another thread

I was unfortunately never able to find a way to do this.

Without some kind of thread init hook there just doesn't appear to be a way to get at that pointer (short of ASM hacks that would be platform dependent).

Setting all TLS (thread local storage) variables to a new, single value in C++

Here is a light weighted implementation of "Plan A" with C++11 Standard atomic variable and thread_local-specifier. (If your compiler doesn't support them, please replace to vendor specific facilities.)

#include <atomic>

struct Foo {
static std::atomic<unsigned> s_TokenGeneration;
static thread_local unsigned s_LocalToken;
static thread_local bool s_LocalState;

// for central thread
void signalResetIsAllAboutThatBass() {
++s_TokenGeneration;
}

// accessor for other threads
void setIsAllAboutThatBass(bool b) {
unsigned currToken = s_TokenGeneration;
s_LocalToken = currToken;
s_LocalState = b;
}
bool getIsAllAboutThatBass() const {
unsigned currToken = s_TokenGeneration;
if (s_LocalToken < currToken) {
// reset thread-local token & state
s_LocalToken = currToken;
s_LocalState = true;
}
return s_LocalState;
}
};

std::atomic<unsigned> Foo::s_TokenGeneration;
thread_local unsigned Foo::s_LocalToken = 0u;
thread_local bool Foo::s_LocalState = true;

Thread local storage processes

The TLS slots - the ones in your diagram - are a fixed-size array of LPVOID-sized variables in the thread's information block. Typically they're used to store pointers. The memory pointed to by a pointer stored here is not local to the thread but allocated normally. However since the thread stores the pointer in a TLS slot, which is local to the thread, the memory is effectively private to the thread.

If you're talking about the raw Windows API and not compiler-assisted thread local storage, it is not a requirement that the data stored in TLS be pointers, it can be plain numeric values (cast to and from LPVOID) if that makes sense for your scenario.

Static Variables and Thread-Local Storage

It appears that this problem was caused by a bug in tz.cpp which has since been fixed.

The bug was that there was a namespace scope variable whose initialization was not guaranteed in the proper order. This was fixed by turning that variable into a function-local-static to ensure the proper initialization order.

My apologies to all who might have been impacted by this bug. And my thanks to all those who have reported it.

Is it allowed to leak pointers of thread local variable?

It's precisely the same as any other local object. All threads share the same view of memory and a function or thread can pass a pointer to a local object to another thread or function if it wants to. If you do this, it's you responsibility to ensure there are no race conditions and an object isn't accessed outside of its lifetime.

I disagree that anything is "inadvertently" changed here. Threads have the same view of memory, so a pointer to an object in one thread will point to the very same object in another thread during that object's lifetime.

The situation is the same with objects on a thread's stack. They are local in the sense that each thread has its own stack. But it is perfectly legal for one thread to give another thread a pointer or reference to an object on its stack. Thread safety and lifetime issues are, as always, your responsbility.



Related Topics



Leave a reply



Submit