diff --git a/ABI-bugs.txt b/ABI-bugs.txt index 83ee95200..51da9f07b 100644 --- a/ABI-bugs.txt +++ b/ABI-bugs.txt @@ -8,8 +8,5 @@ KNOWN ABI BUGS sigset_t is too small on ARM and x86 (but correct on MIPS), so support for real-time signals is broken. http://b/5828899 - Too few TLS slots mean we can't allocate 128 pthread_key_t instances, - which POSIX says should be the minimum. - atexit(3) handlers registered by a shared library aren't called on dlclose(3); this only affects ARM. http://b/4998315 diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h index ff13fdb32..a42a8abed 100644 --- a/libc/private/bionic_tls.h +++ b/libc/private/bionic_tls.h @@ -30,6 +30,7 @@ #define __BIONIC_PRIVATE_BIONIC_TLS_H_ #include +#include #include "__get_tls.h" __BEGIN_DECLS @@ -74,21 +75,21 @@ enum { }; /* - * Maximum number of elements in the TLS array. - * POSIX says this must be at least 128, but Android has traditionally had only 64, minus those - * ones used internally by bionic itself. * There are two kinds of slot used internally by bionic --- there are the well-known slots * enumerated above, and then there are those that are allocated during startup by calls to * pthread_key_create; grep for GLOBAL_INIT_THREAD_LOCAL_BUFFER to find those. We need to manually * maintain that second number, but pthread_test will fail if we forget. */ #define GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT 4 -/* - * This is PTHREAD_KEYS_MAX + TLS_SLOT_FIRST_USER_SLOT + GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT - * rounded up to maintain stack alignment. - */ + #define BIONIC_ALIGN(x, a) (((x) + (a - 1)) & ~(a - 1)) -#define BIONIC_TLS_SLOTS BIONIC_ALIGN(128 + TLS_SLOT_FIRST_USER_SLOT + GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT, 4) + +/* + * Maximum number of elements in the TLS array. + * This includes space for pthread keys and our own internal slots. + * We need to round up to maintain stack alignment. + */ +#define BIONIC_TLS_SLOTS BIONIC_ALIGN(PTHREAD_KEYS_MAX + TLS_SLOT_FIRST_USER_SLOT + GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT, 4) __END_DECLS diff --git a/tests/pthread_test.cpp b/tests/pthread_test.cpp index 480e455dd..e7a952aa2 100644 --- a/tests/pthread_test.cpp +++ b/tests/pthread_test.cpp @@ -33,6 +33,11 @@ TEST(pthread, pthread_key_create) { #if !defined(__GLIBC__) // glibc uses keys internally that its sysconf value doesn't account for. TEST(pthread, pthread_key_create_lots) { + // POSIX says PTHREAD_KEYS_MAX should be at least 128. + ASSERT_GE(PTHREAD_KEYS_MAX, 128); + // sysconf shouldn't return a smaller value. + ASSERT_GE(sysconf(_SC_THREAD_KEYS_MAX), PTHREAD_KEYS_MAX); + // We can allocate _SC_THREAD_KEYS_MAX keys. std::vector keys; for (int i = 0; i < sysconf(_SC_THREAD_KEYS_MAX); ++i) {