Merge pull request #466 from apple/kwt-ubuntu1804-clang-workaround

Workaround for Ubuntu 18.04 clang crashes in swift-corelibs-libdispath
diff --git a/cmake/modules/SwiftSupport.cmake b/cmake/modules/SwiftSupport.cmake
index 60f8b45..adcf42f 100644
--- a/cmake/modules/SwiftSupport.cmake
+++ b/cmake/modules/SwiftSupport.cmake
@@ -153,8 +153,12 @@
     add_library(${target}-static STATIC ${objs})
     add_dependencies(${target}-static ${AST_DEPENDS})
     get_filename_component(ast_output_bn ${AST_OUTPUT} NAME)
-    string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}" "" ast_output_bn ${ast_output_bn})
-    string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}$" "" ast_output_bn ${ast_output_bn})
+    if(NOT CMAKE_STATIC_LIBRARY_PREFIX STREQUAL "")
+      string(REGEX REPLACE "^${CMAKE_STATIC_LIBRARY_PREFIX}" "" ast_output_bn ${ast_output_bn})
+    endif()
+    if(NOT CMAKE_STATIC_LIBRARY_SUFFIX STREQUAL "")
+      string(REGEX REPLACE "${CMAKE_STATIC_LIBRARY_SUFFIX}$" "" ast_output_bn ${ast_output_bn})
+    endif()
     get_filename_component(ast_output_dn ${AST_OUTPUT} DIRECTORY)
     set_target_properties(${target}-static
                           PROPERTIES
diff --git a/src/internal.h b/src/internal.h
index 9bc7b51..3cc16fc 100644
--- a/src/internal.h
+++ b/src/internal.h
@@ -269,12 +269,12 @@
 #if defined(_WIN32)
 #include <time.h>
 #else
-#include <sys/queue.h>
 #include <sys/mount.h>
 #ifdef __ANDROID__
 #include <linux/sysctl.h>
 #else
 #include <sys/sysctl.h>
+#include <sys/queue.h>
 #endif /* __ANDROID__ */
 #include <sys/socket.h>
 #include <sys/time.h>
diff --git a/src/queue.c b/src/queue.c
index 6332c6b..90f3cfa 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -7296,32 +7296,30 @@
 #include <sys/syscall.h>
 #endif
 
-#ifndef __ANDROID__
 #ifdef SYS_gettid
 DISPATCH_ALWAYS_INLINE
 static inline pid_t
-gettid(void)
+_gettid(void)
 {
 	return (pid_t)syscall(SYS_gettid);
 }
 #elif defined(__FreeBSD__)
 DISPATCH_ALWAYS_INLINE
 static inline pid_t
-gettid(void)
+_gettid(void)
 {
 	return (pid_t)pthread_getthreadid_np();
 }
 #elif defined(_WIN32)
 DISPATCH_ALWAYS_INLINE
 static inline DWORD
-gettid(void)
+_gettid(void)
 {
 	return GetCurrentThreadId();
 }
 #else
 #error "SYS_gettid unavailable on this system"
 #endif /* SYS_gettid */
-#endif /* ! __ANDROID__ */
 
 #define _tsd_call_cleanup(k, f)  do { \
 		if ((f) && tsd->k) ((void(*)(void*))(f))(tsd->k); \
@@ -7331,7 +7329,7 @@
 static void (*_dispatch_thread_detach_callback)(void);
 
 void
-_dispatch_install_thread_detach_callback(dispatch_function_t cb)
+_dispatch_install_thread_detach_callback(void (*cb)(void))
 {
 	if (os_atomic_xchg(&_dispatch_thread_detach_callback, cb, relaxed)) {
 		DISPATCH_CLIENT_CRASH(0, "Installing a thread detach callback twice");
@@ -7429,7 +7427,7 @@
 #else
 	FlsSetValue(__dispatch_tsd_key, &__dispatch_tsd);
 #endif // defined(_WIN32)
-	__dispatch_tsd.tid = gettid();
+	__dispatch_tsd.tid = _gettid();
 }
 #endif
 
diff --git a/src/semaphore.c b/src/semaphore.c
index 610f728..bc96051 100644
--- a/src/semaphore.c
+++ b/src/semaphore.c
@@ -76,7 +76,7 @@
 			dsema->dsema_sema);
 #endif
 	offset += dsnprintf(&buf[offset], bufsiz - offset,
-			"value = %ld, orig = %" PRIdPTR " }", dsema->dsema_value, dsema->dsema_orig);
+			"value = %" PRIdPTR ", orig = %" PRIdPTR " }", dsema->dsema_value, dsema->dsema_orig);
 	return offset;
 }
 
diff --git a/src/shims.h b/src/shims.h
index ea5e098..22aa486 100644
--- a/src/shims.h
+++ b/src/shims.h
@@ -31,9 +31,12 @@
 #include <pthread.h>
 #else // defined(_WIN32)
 #include "shims/generic_win_stubs.h"
-#include "shims/generic_sys_queue.h"
 #endif // defined(_WIN32)
 
+#if defined(_WIN32) || defined(__ANDROID__)
+#include "shims/generic_sys_queue.h"
+#endif
+
 #ifdef __ANDROID__
 #include "shims/android_stubs.h"
 #endif // __ANDROID__
diff --git a/src/shims/generic_sys_queue.h b/src/shims/generic_sys_queue.h
index c6c6587..fd4ac1d 100644
--- a/src/shims/generic_sys_queue.h
+++ b/src/shims/generic_sys_queue.h
@@ -110,6 +110,8 @@
 		struct type *le_prev; \
 	}
 
+#define	LIST_EMPTY(head) ((head)->lh_first == NULL)
+
 #define LIST_FIRST(head) ((head)->lh_first)
 
 #define LIST_FOREACH(var, head, field) \
@@ -117,6 +119,15 @@
 		(var); \
 		(var) = LIST_NEXT((var), field))
 
+#define	LIST_FOREACH_SAFE(var, head, field, tvar) \
+	for ((var) = LIST_FIRST((head)); \
+		(var) && ((tvar) = LIST_NEXT((var), field), 1); \
+		(var) = (tvar))
+
+#define	LIST_INIT(head) do { \
+	LIST_FIRST((head)) = NULL; \
+} while (0)
+
 #define LIST_NEXT(elm, field) ((elm)->field.le_next)
 
 #define LIST_REMOVE(elm, field) do { \
diff --git a/src/shims/yield.h b/src/shims/yield.h
index 7e599cb..53eb800 100644
--- a/src/shims/yield.h
+++ b/src/shims/yield.h
@@ -156,9 +156,9 @@
 #elif defined(_WIN32)
 #define _dispatch_preemption_yield(n) { (void)n; Sleep(0); }
 #define _dispatch_preemption_yield_to(th, n) { (void)n; Sleep(0); }
-#else 
-#define _dispatch_preemption_yield(n) { (void)n; pthread_yield(); }
-#define _dispatch_preemption_yield_to(th, n) { (void)n; pthread_yield(); }
+#else
+#define _dispatch_preemption_yield(n) { (void)n; sched_yield(); }
+#define _dispatch_preemption_yield_to(th, n) { (void)n; sched_yield(); }
 #endif // HAVE_MACH
 
 #pragma mark -