Improve pthread_create failure handling.

Return EAGAIN rather than aborting if we fail to set up the TLS for a new
thread.

Add a test that uses all the VMAs so we can properly test these edge cases.

Add an explicit test for pthread_attr_setdetachstate, which we use in the
previous test, but other than that has no tests.

Remove support for ro.logd.timestamp/persist.logd.timestamp, which doesn't
seem to be used, and which prevents us from logging failures in cases where
mmap fails (because we need to mmap in the system property implementation).

Bug: http://b/65608572
Test: ran tests
Change-Id: I9009f06546e1c2cc55eff996d08b55eff3482343
diff --git a/libc/async_safe/async_safe_log.cpp b/libc/async_safe/async_safe_log.cpp
index d81ef34..78f62bd 100644
--- a/libc/async_safe/async_safe_log.cpp
+++ b/libc/async_safe/async_safe_log.cpp
@@ -468,19 +468,6 @@
   return log_fd;
 }
 
-static clockid_t log_clockid() {
-  static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
-  ScopedPthreadMutexLocker locker(&mutex);
-
-  static CachedProperty ro_logd_timestamp("ro.logd.timestamp");
-  static CachedProperty persist_logd_timestamp("persist.logd.timestamp");
-
-  char ch = persist_logd_timestamp.Get()[0];
-  if (ch == '\0') ch = ro_logd_timestamp.Get()[0];
-
-  return (tolower(ch) == 'm') ? CLOCK_MONOTONIC : CLOCK_REALTIME;
-}
-
 struct log_time {  // Wire format
   uint32_t tv_sec;
   uint32_t tv_nsec;
@@ -501,7 +488,7 @@
   vec[1].iov_base = &tid;
   vec[1].iov_len = sizeof(tid);
   timespec ts;
-  clock_gettime(log_clockid(), &ts);
+  clock_gettime(CLOCK_REALTIME, &ts);
   log_time realtime_ts;
   realtime_ts.tv_sec = ts.tv_sec;
   realtime_ts.tv_nsec = ts.tv_nsec;
diff --git a/libc/bionic/__libc_init_main_thread.cpp b/libc/bionic/__libc_init_main_thread.cpp
index f3dbfa5..9cbff11 100644
--- a/libc/bionic/__libc_init_main_thread.cpp
+++ b/libc/bionic/__libc_init_main_thread.cpp
@@ -70,7 +70,7 @@
   // set up before we call any function that might get a stack check inserted.
   // TLS also needs to be set up before errno (and therefore syscalls) can be used.
   __set_tls(main_thread.tls);
-  __init_tls(&main_thread);
+  if (!__init_tls(&main_thread)) async_safe_fatal("failed to initialize TLS: %s", strerror(errno));
 
   // Tell the kernel to clear our tid field when we exit, so we're like any other pthread.
   // As a side-effect, this tells us our pid (which is the same as the main thread's tid).
diff --git a/libc/bionic/pthread_create.cpp b/libc/bionic/pthread_create.cpp
index 09ae16c..65ab92c 100644
--- a/libc/bionic/pthread_create.cpp
+++ b/libc/bionic/pthread_create.cpp
@@ -50,7 +50,7 @@
 #endif
 
 // This code is used both by each new pthread and the code that initializes the main thread.
-void __init_tls(pthread_internal_t* thread) {
+bool __init_tls(pthread_internal_t* thread) {
   // Slot 0 must point to itself. The x86 Linux kernel reads the TLS from %fs:0.
   thread->tls[TLS_SLOT_SELF] = thread->tls;
   thread->tls[TLS_SLOT_THREAD_ID] = thread;
@@ -59,16 +59,25 @@
   size_t allocation_size = BIONIC_TLS_SIZE + (2 * PTHREAD_GUARD_SIZE);
   void* allocation = mmap(nullptr, allocation_size, PROT_NONE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
   if (allocation == MAP_FAILED) {
-    async_safe_fatal("failed to allocate TLS: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                          "pthread_create failed: couldn't allocate TLS: %s", strerror(errno));
+    return false;
   }
+
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, allocation, allocation_size, "bionic TLS guard");
 
+  // Carve out the writable TLS section.
   thread->bionic_tls = reinterpret_cast<bionic_tls*>(static_cast<char*>(allocation) +
                                                      PTHREAD_GUARD_SIZE);
   if (mprotect(thread->bionic_tls, BIONIC_TLS_SIZE, PROT_READ | PROT_WRITE) != 0) {
-    async_safe_fatal("failed to mprotect TLS: %s", strerror(errno));
+    async_safe_format_log(ANDROID_LOG_WARN, "libc",
+                          "pthread_create failed: couldn't mprotect TLS: %s", strerror(errno));
+    munmap(allocation, allocation_size);
+    return false;
   }
+
   prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, thread->bionic_tls, BIONIC_TLS_SIZE, "bionic TLS");
+  return true;
 }
 
 void __init_thread_stack_guard(pthread_internal_t* thread) {
@@ -194,7 +203,10 @@
 
   thread->mmap_size = mmap_size;
   thread->attr = *attr;
-  __init_tls(thread);
+  if (!__init_tls(thread)) {
+    if (thread->mmap_size != 0) munmap(thread->attr.stack_base, thread->mmap_size);
+    return EAGAIN;
+  }
   __init_thread_stack_guard(thread);
 
   *threadp = thread;
diff --git a/libc/bionic/pthread_internal.h b/libc/bionic/pthread_internal.h
index 77bdd85..ad8be66 100644
--- a/libc/bionic/pthread_internal.h
+++ b/libc/bionic/pthread_internal.h
@@ -115,7 +115,7 @@
 };
 
 __LIBC_HIDDEN__ int __init_thread(pthread_internal_t* thread);
-__LIBC_HIDDEN__ void __init_tls(pthread_internal_t* thread);
+__LIBC_HIDDEN__ bool __init_tls(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_thread_stack_guard(pthread_internal_t* thread);
 __LIBC_HIDDEN__ void __init_alternate_signal_stack(pthread_internal_t*);