I was recently made aware that thread local storage is limited on some platforms. For example, the docs for the C++ library boost::thread read:
"Note: There is an implementation specific limit to the number of thread specific storage objects that can be created, and this limit may be small."
I've been searching to try and find out the limits for different platforms, but I haven't been able to find an authoritative table. This is an important question if you're writing a crossplatform app that uses TLS. Linux was the only platform I found information for, in the form of a patch Ingo Monar sent in 2002 to the kernel list adding TLS support, where he mentions, "The number of TLS areas is unlimited, and there is no additional allocation overhead associated with TLS support." Which if still true in 2009 (is it?) is pretty nifty.
But what about Linux today? OS X? Windows? Solaris? Embedded OSes? For OS's that run on multiple architectures does it vary across architectures?
Edit: If you're curious why there might be a limit, consider that the space for thread local storage will be preallocated, so you'll be paying a cost for it on every single thread. Even a small amount in the face of lots of threads can be a problem.
On Linux, if you are using __thread
TLS data, the only limit is set by your available address space, as this data is simply allocated as regular RAM referenced by the gs
(on x86) or fs
(on x86-64) segment descriptors. Note that, in some cases, allocation of TLS data used by dynamically loaded libraries can be elided in threads that do not use that TLS data.
TLS allocated by pthread_key_create
and friends, however, is limited to PTHREAD_KEYS_MAX
slots (this applies to all conforming pthreads implementations).
For more information on the TLS implemenetation on Linux, see ELF Handling For Thread-Local Storage and The Native POSIX Thread Library for Linux.
That said, if you need portability, your best bet is to minimize TLS use - put a single pointer in TLS, and put everything you need in a data structure hung off that pointer.