Request: Thread Local Storage

It would be very handy if Juce provided a reasonably sized amount of thread-local storage, in the same fashion as boost (but conforming to Juce api standards):

boost::thread Thread Local Storage

Yeah, I’ve thought about doing that too. Good idea.

This is one of the very few remaining dependencies I have on boost

I added a ThreadLocalValue class some time ago!

Wow!!! How’d that slip past me ? Looking it over, it seems that ThreadLocalValue::get() runs in O(N) with N = number of threads? I’m not sure how I feel about that. I was expecting a native implementation…

Yeah, I wanted to start with something that will run on all platforms (including android, where there is no native implementation). I figured that this could be extended in future to take advantage of native calls where possible.

But bear in mind that it’s O(N) where N is the number of threads which use this value, not the total number of threads in the process. If you have so many threads that this becomes a performance issue, you’d probably be better off using a different approach anyway.

(…and also bear in mind that even an OS-provided implementation could have O(N) complexity!)

Actually, does c++11 say anything about thread-locals?

Yeah, I wanted to start with something that will run on all platforms (including android, where there is no native implementation). I figured that this could be extended in future to take advantage of native calls where possible. [/quote]

That sounds quite reasonable. Curious to know what boost does for Android in this case.

Well to support a mostly wait-free thread queue it was necessary to write a special memory allocator to avoid ABA. This allocator gives each thread its own working set of memory, accessed via thread local storage. Is juce::ThreadLocalValue a performance issue? I don’t know yet.

Could, but the Windows implementation reserves a small amount of memory for thread local storage, which is tied to the execution context of the thread and therefore accessible in constant time.

It does: C++11 - Wikipedia

Ah, well if we’re going to get it all done by the compiler in c++11, none of this is really an issue!

Juce still supports some non C++0x11 environments…or am I mistaken?

Oh yes, of course. I just mean that hopefully my class will become redundant pretty soon.

I’m a bit vague on how this would be used? The Boost example mentions errno, but that implies global variables?

If you took a local copy of a value, wouldn’t the two become out of sync, in which case it should be another value anyway? Or is this just a Value that can work on a different thread?

Bruce

Well, I can tell you how I’m using it - I’ve written a lock-free allocator to use with a lock-free thread queue in order to prevent the “ABA problem.” Each thread has its own small working block of memory and I use a thread local value to keep track of it. The problem with the Juce implementation is that it doesn’t destroy the object when the associated thread exits. Sure, Jules could add it but it is non trivial and quite platform specific - boost knows all of windows and mac os dirty secrets (for hooking threads).

1 Like