Merge "Fix LP64 libm for 128-bit long doubles"
diff --git a/libc/bionic/fts.c b/libc/bionic/fts.c
index 177652f..ec0baf7 100644
--- a/libc/bionic/fts.c
+++ b/libc/bionic/fts.c
@@ -51,6 +51,9 @@
 static u_short	 fts_stat(FTS *, FTSENT *, int);
 static int	 fts_safe_changedir(FTS *, FTSENT *, int, char *);
 
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
 #define	ISDOT(a)	(a[0] == '.' && (!a[1] || (a[1] == '.' && !a[2])))
 
 #define	CLR(opt)	(sp->fts_options &= ~(opt))
diff --git a/libc/bionic/libc_logging.cpp b/libc/bionic/libc_logging.cpp
index a4aeced..8e62e40 100644
--- a/libc/bionic/libc_logging.cpp
+++ b/libc/bionic/libc_logging.cpp
@@ -494,24 +494,27 @@
     return __libc_write_stderr(tag, msg);
   }
 
-  iovec vec[5];
+  iovec vec[6];
   char log_id = LOG_ID_MAIN;
   vec[0].iov_base = &log_id;
   vec[0].iov_len = sizeof(log_id);
+  uint16_t tid = gettid();
+  vec[1].iov_base = &tid;
+  vec[1].iov_len = sizeof(tid);
   timespec ts;
   clock_gettime(CLOCK_REALTIME, &ts);
   log_time realtime_ts;
   realtime_ts.tv_sec = ts.tv_sec;
   realtime_ts.tv_nsec = ts.tv_nsec;
-  vec[1].iov_base = &realtime_ts;
-  vec[1].iov_len = sizeof(realtime_ts);
+  vec[2].iov_base = &realtime_ts;
+  vec[2].iov_len = sizeof(realtime_ts);
 
-  vec[2].iov_base = &priority;
-  vec[2].iov_len = 1;
-  vec[3].iov_base = const_cast<char*>(tag);
-  vec[3].iov_len = strlen(tag) + 1;
-  vec[4].iov_base = const_cast<char*>(msg);
-  vec[4].iov_len = strlen(msg) + 1;
+  vec[3].iov_base = &priority;
+  vec[3].iov_len = 1;
+  vec[4].iov_base = const_cast<char*>(tag);
+  vec[4].iov_len = strlen(tag) + 1;
+  vec[5].iov_base = const_cast<char*>(msg);
+  vec[5].iov_len = strlen(msg) + 1;
 #else
   int main_log_fd = TEMP_FAILURE_RETRY(open("/dev/log/main", O_CLOEXEC | O_WRONLY));
   if (main_log_fd == -1) {
@@ -553,24 +556,27 @@
 
 static int __libc_android_log_event(int32_t tag, char type, const void* payload, size_t len) {
 #ifdef TARGET_USES_LOGD
-  iovec vec[5];
+  iovec vec[6];
   char log_id = LOG_ID_EVENTS;
   vec[0].iov_base = &log_id;
   vec[0].iov_len = sizeof(log_id);
+  uint16_t tid = gettid();
+  vec[1].iov_base = &tid;
+  vec[1].iov_len = sizeof(tid);
   timespec ts;
   clock_gettime(CLOCK_REALTIME, &ts);
   log_time realtime_ts;
   realtime_ts.tv_sec = ts.tv_sec;
   realtime_ts.tv_nsec = ts.tv_nsec;
-  vec[1].iov_base = &realtime_ts;
-  vec[1].iov_len = sizeof(realtime_ts);
+  vec[2].iov_base = &realtime_ts;
+  vec[2].iov_len = sizeof(realtime_ts);
 
-  vec[2].iov_base = &tag;
-  vec[2].iov_len = sizeof(tag);
-  vec[3].iov_base = &type;
-  vec[3].iov_len = sizeof(type);
-  vec[4].iov_base = const_cast<void*>(payload);
-  vec[4].iov_len = len;
+  vec[3].iov_base = &tag;
+  vec[3].iov_len = sizeof(tag);
+  vec[4].iov_base = &type;
+  vec[4].iov_len = sizeof(type);
+  vec[5].iov_base = const_cast<void*>(payload);
+  vec[5].iov_len = len;
 
   int event_log_fd = __libc_open_log_socket();
 #else
diff --git a/libc/bionic/posix_timers.cpp b/libc/bionic/posix_timers.cpp
index ffe213c..e9190b2 100644
--- a/libc/bionic/posix_timers.cpp
+++ b/libc/bionic/posix_timers.cpp
@@ -100,11 +100,14 @@
 static void __timer_thread_stop(PosixTimer* timer) {
   pthread_kill(timer->callback_thread, TIMER_SIGNAL);
 
-  // We can't pthread_join because POSIX says "the threads created in response to a timer
-  // expiration are created detached, or in an unspecified way if the thread attribute's
-  // detachstate is PTHREAD_CREATE_JOINABLE".
-  while (timer->exiting == 0) {
-    __futex_wait(&timer->exiting, 0, NULL);
+  // If this is being called from within the callback thread, do nothing else.
+  if (pthread_self() != timer->callback_thread) {
+    // We can't pthread_join because POSIX says "the threads created in response to a timer
+    // expiration are created detached, or in an unspecified way if the thread attribute's
+    // detachstate is PTHREAD_CREATE_JOINABLE".
+    while (timer->exiting == 0) {
+      __futex_wait(&timer->exiting, 0, NULL);
+    }
   }
 }
 
diff --git a/libc/dns/gethnamaddr.c b/libc/dns/gethnamaddr.c
index 2d2cb71..2234c7c 100644
--- a/libc/dns/gethnamaddr.c
+++ b/libc/dns/gethnamaddr.c
@@ -72,6 +72,9 @@
 #include <syslog.h>
 #include <unistd.h>
 
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
 #ifndef LOG_AUTH
 # define LOG_AUTH 0
 #endif
diff --git a/libc/include/stdio.h b/libc/include/stdio.h
index 6f8f92e..470d377 100644
--- a/libc/include/stdio.h
+++ b/libc/include/stdio.h
@@ -393,8 +393,10 @@
 }
 
 #if defined(__clang__)
-#define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
-#define snprintf(...) __wrap_snprintf(__VA_ARGS__)
+  #if !defined(snprintf)
+    #define __wrap_snprintf(dest, size, ...) __builtin___snprintf_chk(dest, size, 0, __bos(dest), __VA_ARGS__)
+    #define snprintf(...) __wrap_snprintf(__VA_ARGS__)
+  #endif
 #else
 __BIONIC_FORTIFY_INLINE
 __printflike(3, 4)
@@ -406,8 +408,10 @@
 #endif
 
 #if defined(__clang__)
-#define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)
-#define sprintf(...) __wrap_sprintf(__VA_ARGS__)
+  #if !defined(sprintf)
+    #define __wrap_sprintf(dest, ...) __builtin___sprintf_chk(dest, 0, __bos(dest), __VA_ARGS__)
+    #define sprintf(...) __wrap_sprintf(__VA_ARGS__)
+  #endif
 #else
 __BIONIC_FORTIFY_INLINE
 __printflike(2, 3)
diff --git a/libc/include/sys/param.h b/libc/include/sys/param.h
index 37c6427..e64d6ce 100644
--- a/libc/include/sys/param.h
+++ b/libc/include/sys/param.h
@@ -34,16 +34,6 @@
 #define MAXPATHLEN  PATH_MAX
 #define MAXSYMLINKS 8
 
-#if __LP64__
-#define ALIGNBYTES 7
-#else
-#define ALIGNBYTES 3
-#endif
-
-#ifndef ALIGN
-#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
-#endif
-
 /* Macros for counting and rounding. */
 #ifndef howmany
 #define howmany(x, y)   (((x)+((y)-1))/(y))
diff --git a/libc/stdio/findfp.c b/libc/stdio/findfp.c
index 943c90a..926e5a1 100644
--- a/libc/stdio/findfp.c
+++ b/libc/stdio/findfp.c
@@ -41,6 +41,9 @@
 #include "glue.h"
 #include "private/thread_private.h"
 
+#define ALIGNBYTES (sizeof(uintptr_t) - 1)
+#define ALIGN(p) (((uintptr_t)(p) + ALIGNBYTES) &~ ALIGNBYTES)
+
 int	__sdidinit;
 
 #define	NDYNAMIC 10		/* add ten more whenever necessary */
diff --git a/tests/Android.mk b/tests/Android.mk
index 451b3a9..8dffa2f 100644
--- a/tests/Android.mk
+++ b/tests/Android.mk
@@ -248,11 +248,12 @@
 # gtest needs ANDROID_DATA/local/tmp for death test output.
 # Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
 # Use the current target out directory as ANDROID_DATA.
+# BIONIC_TEST_FLAGS is either empty or it comes from the user.
 bionic-unit-tests-glibc-run: bionic-unit-tests-glibc
 	mkdir -p $(TARGET_OUT_DATA)/local/tmp
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_ROOT=$(TARGET_OUT) \
-		$(HOST_OUT_EXECUTABLES)/bionic-unit-tests-glibc
+		$(HOST_OUT_EXECUTABLES)/bionic-unit-tests-glibc $(BIONIC_TEST_FLAGS)
 
 # -----------------------------------------------------------------------------
 # Run the unit tests built against x86 bionic on an x86 host.
@@ -267,6 +268,7 @@
 # gtest needs ANDROID_DATA/local/tmp for death test output.
 # Make sure to create ANDROID_DATA/local/tmp if doesn't exist.
 # bionic itself should always work relative to ANDROID_DATA or ANDROID_ROOT.
+# BIONIC_TEST_FLAGS is either empty or it comes from the user.
 bionic-unit-tests-run-on-host: bionic-unit-tests $(TARGET_OUT_EXECUTABLES)/$(LINKER) $(TARGET_OUT_EXECUTABLES)/sh
 	if [ ! -d /system -o ! -d /system/bin ]; then \
 	  echo "Attempting to create /system/bin"; \
@@ -278,7 +280,7 @@
 	ANDROID_DATA=$(TARGET_OUT_DATA) \
 	ANDROID_ROOT=$(TARGET_OUT) \
 	LD_LIBRARY_PATH=$(TARGET_OUT_SHARED_LIBRARIES) \
-		$(TARGET_OUT_DATA_NATIVE_TESTS)/bionic-unit-tests/bionic-unit-tests
+		$(TARGET_OUT_DATA_NATIVE_TESTS)/bionic-unit-tests/bionic-unit-tests $(BIONIC_TEST_FLAGS)
 endif
 endif
 
diff --git a/tests/time_test.cpp b/tests/time_test.cpp
index af6ae85..26b7775 100644
--- a/tests/time_test.cpp
+++ b/tests/time_test.cpp
@@ -341,3 +341,49 @@
   EXPECT_EQ(1, counter2.value);
   EXPECT_EQ(0, counter3.value);
 }
+
+struct TimerDeleteData {
+  timer_t timer_id;
+  pthread_t thread_id;
+  volatile bool complete;
+};
+
+static void TimerDeleteCallback(sigval_t value) {
+  TimerDeleteData* tdd = reinterpret_cast<TimerDeleteData*>(value.sival_ptr);
+
+  tdd->thread_id = pthread_self();
+  timer_delete(tdd->timer_id);
+  tdd->complete = true;
+}
+
+TEST(time, timer_delete_from_timer_thread) {
+  TimerDeleteData tdd;
+  sigevent_t se;
+
+  memset(&se, 0, sizeof(se));
+  se.sigev_notify = SIGEV_THREAD;
+  se.sigev_notify_function = TimerDeleteCallback;
+  se.sigev_value.sival_ptr = &tdd;
+
+  tdd.complete = false;
+  ASSERT_EQ(0, timer_create(CLOCK_REALTIME, &se, &tdd.timer_id));
+
+  itimerspec ts;
+  ts.it_value.tv_sec = 0;
+  ts.it_value.tv_nsec = 100;
+  ts.it_interval.tv_sec = 0;
+  ts.it_interval.tv_nsec = 0;
+  ASSERT_EQ(0, timer_settime(tdd.timer_id, TIMER_ABSTIME, &ts, NULL));
+
+  time_t cur_time = time(NULL);
+  while (!tdd.complete && (time(NULL) - cur_time) < 5);
+  ASSERT_TRUE(tdd.complete);
+
+#if defined(__BIONIC__)
+  // Since bionic timers are implemented by creating a thread to handle the
+  // callback, verify that the thread actually completes.
+  cur_time = time(NULL);
+  while (pthread_detach(tdd.thread_id) != ESRCH && (time(NULL) - cur_time) < 5);
+  ASSERT_EQ(ESRCH, pthread_detach(tdd.thread_id));
+#endif
+}