Merge "Define PTHREAD_KEYS_MAX and _POSIX_THREAD_KEYS_MAX in a POSIX-compliant way."
diff --git a/libc/bionic/sysconf.cpp b/libc/bionic/sysconf.cpp
index 9ab2007..e945fbf 100644
--- a/libc/bionic/sysconf.cpp
+++ b/libc/bionic/sysconf.cpp
@@ -33,6 +33,7 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <limits.h>
+#include <pthread.h>
 #include <stdio.h>  // For FOPEN_MAX.
 #include <string.h>
 #include <sys/sysconf.h>
@@ -57,7 +58,6 @@
 
 /* the following depends on our implementation */
 #define  SYSTEM_ATEXIT_MAX          65536    /* our implementation is unlimited */
-#define  SYSTEM_THREAD_STACK_MIN    32768    /* lower values may be possible, but be conservative */
 #define  SYSTEM_THREAD_THREADS_MAX  2048     /* really unlimited */
 
 #define  SYSTEM_2_C_BIND     _POSIX_VERSION  /* Posix C binding version */
@@ -309,7 +309,7 @@
     case _SC_THREAD_KEYS_MAX:
       return (BIONIC_TLS_SLOTS - TLS_SLOT_FIRST_USER_SLOT - GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT);
 
-    case _SC_THREAD_STACK_MIN:    return SYSTEM_THREAD_STACK_MIN;
+    case _SC_THREAD_STACK_MIN:    return PTHREAD_STACK_MIN;
     case _SC_THREAD_THREADS_MAX:  return SYSTEM_THREAD_THREADS_MAX;
     case _SC_TTY_NAME_MAX:        return SYSTEM_TTY_NAME_MAX;
 #ifdef _POSIX_THREADS
diff --git a/libc/include/sys/limits.h b/libc/include/sys/limits.h
index 2d0d11e..f1080fe 100644
--- a/libc/include/sys/limits.h
+++ b/libc/include/sys/limits.h
@@ -176,9 +176,9 @@
 #define  _POSIX_JOB_CONTROL         1    /* job control is a Linux feature */
 
 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS 4 /* the minimum mandated by POSIX */
-#define PTHREAD_DESTRUCTOR_ITERATIONS 4
+#define PTHREAD_DESTRUCTOR_ITERATIONS _POSIX_THREAD_DESTRUCTOR_ITERATIONS
 #define _POSIX_THREAD_KEYS_MAX 128            /* the minimum mandated by POSIX */
-/* TODO: our PTHREAD_KEYS_MAX is currently too low to be posix compliant! */
+#define PTHREAD_KEYS_MAX _POSIX_THREAD_KEYS_MAX
 #define _POSIX_THREAD_THREADS_MAX 64          /* the minimum mandated by POSIX */
 #define PTHREAD_THREADS_MAX                   /* bionic has no specific limit */
 
diff --git a/libc/private/bionic_tls.h b/libc/private/bionic_tls.h
index 22b7806..d15b1ca 100644
--- a/libc/private/bionic_tls.h
+++ b/libc/private/bionic_tls.h
@@ -76,7 +76,12 @@
  * maintain that second number, but pthread_test will fail if we forget.
  */
 #define GLOBAL_INIT_THREAD_LOCAL_BUFFER_COUNT 4
-#define BIONIC_TLS_SLOTS 128
+/*
+ * 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)
 
 /* syscall only, do not call directly */
 extern int __set_tls(void* ptr);