[runtime] Use pthread_cond_timedwait_relative_np () function on osx if available...
authorZoltan Varga <vargaz@gmail.com>
Fri, 30 Jun 2017 03:05:00 +0000 (23:05 -0400)
committerGitHub <noreply@github.com>
Fri, 30 Jun 2017 03:05:00 +0000 (23:05 -0400)
configure.ac
mono/utils/Makefile.am
mono/utils/mono-os-mutex.c [new file with mode: 0644]
mono/utils/mono-os-mutex.h
msvc/libmonoutils.vcxproj

index a61341e306fb827cd252af0fb6c72bca98d4adb6..b14ee03463ca4ae4dee7aba63fe7d58846d91a2c 100644 (file)
@@ -1956,7 +1956,7 @@ if test x$host_win32 = xno; then
        AC_CHECK_HEADERS(pthread.h)
        AC_CHECK_HEADERS(pthread_np.h)
        AC_CHECK_FUNCS(pthread_mutex_timedlock)
-       AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_get_np pthread_setname_np)
+       AC_CHECK_FUNCS(pthread_getattr_np pthread_attr_get_np pthread_setname_np pthread_cond_timedwait_relative_np)
        AC_CHECK_FUNCS(pthread_kill)
        AC_MSG_CHECKING(for PTHREAD_MUTEX_RECURSIVE)
        AC_TRY_COMPILE([ #include <pthread.h>], [
index f85393101e474b8c86a2545c34790090bfac48a2..e16931a28881757afdbc91db5950eb92841fda37 100644 (file)
@@ -59,6 +59,7 @@ monoutils_sources = \
        mono-mmap-internals.h   \
        mono-mmap-windows-internals.h   \
        mono-os-mutex.h         \
+       mono-os-mutex.c         \
        mono-coop-mutex.h               \
        mono-once.h             \
        mono-lazy-init.h                \
diff --git a/mono/utils/mono-os-mutex.c b/mono/utils/mono-os-mutex.c
new file mode 100644 (file)
index 0000000..aea54c4
--- /dev/null
@@ -0,0 +1,84 @@
+/**
+ * \file
+ * Portability wrappers around POSIX Mutexes
+ *
+ * Authors: Jeffrey Stedfast <fejj@ximian.com>
+ *
+ * Copyright 2002 Ximian, Inc. (www.ximian.com)
+ *
+ * Licensed under the MIT license. See LICENSE file in the project root for full license information.
+ *
+ */
+
+#include <config.h>
+
+#if !defined(HOST_WIN32)
+
+#if defined(TARGET_OSX)
+/* So we can use the declaration of pthread_cond_timedwait_relative_np () */
+#undef _XOPEN_SOURCE
+#endif
+#include <pthread.h>
+
+#include "mono-os-mutex.h"
+
+int
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
+{
+       struct timespec ts;
+       int res;
+
+       if (timeout_ms == MONO_INFINITE_WAIT) {
+               mono_os_cond_wait (cond, mutex);
+               return 0;
+       }
+
+       /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
+
+       /* This function only seems to be available on 64bit osx */
+#if defined(HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP) && defined(TARGET_OSX)
+       memset (&ts, 0, sizeof (struct timespec));
+       ts.tv_sec = timeout_ms / 1000;
+       ts.tv_nsec = (timeout_ms % 1000) * 1000 * 1000;
+
+       res = pthread_cond_timedwait_relative_np (cond, mutex, &ts);
+       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) {
+               g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex);
+               g_error ("%s: pthread_cond_timedwait_relative_np failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms);
+       }
+       return res != 0 ? -1 : 0;
+#else
+#ifdef BROKEN_CLOCK_SOURCE
+       struct timeval tv;
+
+       /* clock_gettime is not supported in MAC OS x */
+       res = gettimeofday (&tv, NULL);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+
+       ts.tv_sec = tv.tv_sec;
+       ts.tv_nsec = tv.tv_usec * 1000;
+#else
+       /* cond is using CLOCK_MONOTONIC as time source */
+       res = clock_gettime (CLOCK_MONOTONIC, &ts);
+       if (G_UNLIKELY (res != 0))
+               g_error ("%s: clock_gettime failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
+#endif
+
+       ts.tv_sec += timeout_ms / 1000;
+       ts.tv_nsec += (timeout_ms % 1000) * 1000 * 1000;
+       if (ts.tv_nsec >= 1000 * 1000 * 1000) {
+               ts.tv_nsec -= 1000 * 1000 * 1000;
+               ts.tv_sec ++;
+       }
+
+       res = pthread_cond_timedwait (cond, mutex, &ts);
+       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT)) {
+               g_print ("cond: %p mutex: %p\n", *(gpointer*)cond, *(gpointer*)mutex);
+               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms);
+       }
+       return res != 0 ? -1 : 0;
+#endif /* !HAVE_PTHREAD_COND_TIMEDWAIT_RELATIVE_NP */
+}
+
+#endif /* HOST_WIN32 */
index 3888d26441df95cd34c10822cd70c8db0ee8bef8..be1f64858863ba930c0340e6bfe44201e24b659f 100644 (file)
@@ -175,50 +175,8 @@ mono_os_cond_wait (mono_cond_t *cond, mono_mutex_t *mutex)
                g_error ("%s: pthread_cond_wait failed with \"%s\" (%d)", __func__, g_strerror (res), res);
 }
 
-static inline int
-mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms)
-{
-#ifdef BROKEN_CLOCK_SOURCE
-       struct timeval tv;
-#endif
-       struct timespec ts;
-       int res;
-
-       if (timeout_ms == MONO_INFINITE_WAIT) {
-               mono_os_cond_wait (cond, mutex);
-               return 0;
-       }
-
-       /* ms = 10^-3, us = 10^-6, ns = 10^-9 */
-
-#ifdef BROKEN_CLOCK_SOURCE
-       /* clock_gettime is not supported in MAC OS x */
-       res = gettimeofday (&tv, NULL);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: gettimeofday failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-
-       ts.tv_sec = tv.tv_sec;
-       ts.tv_nsec = tv.tv_usec * 1000;
-#else
-       /* cond is using CLOCK_MONOTONIC as time source */
-       res = clock_gettime (CLOCK_MONOTONIC, &ts);
-       if (G_UNLIKELY (res != 0))
-               g_error ("%s: clock_gettime failed with \"%s\" (%d)", __func__, g_strerror (errno), errno);
-#endif
-
-       ts.tv_sec += timeout_ms / 1000;
-       ts.tv_nsec += (timeout_ms % 1000) * 1000 * 1000;
-       if (ts.tv_nsec >= 1000 * 1000 * 1000) {
-               ts.tv_nsec -= 1000 * 1000 * 1000;
-               ts.tv_sec ++;
-       }
-
-       res = pthread_cond_timedwait (cond, mutex, &ts);
-       if (G_UNLIKELY (res != 0 && res != ETIMEDOUT))
-               g_error ("%s: pthread_cond_timedwait failed with \"%s\" (%d) %ld %ld %d", __func__, g_strerror (res), res, ts.tv_sec, ts.tv_nsec, timeout_ms);
-
-       return res != 0 ? -1 : 0;
-}
+int
+mono_os_cond_timedwait (mono_cond_t *cond, mono_mutex_t *mutex, guint32 timeout_ms);
 
 static inline void
 mono_os_cond_signal (mono_cond_t *cond)
index bd512ab75e69be5420df3b1f02b3fdfaec296edc..29903290d3381140bf7742288fbc2128591c5f4a 100644 (file)
@@ -1,4 +1,4 @@
-<?xml version="1.0" encoding="utf-8"?>\r
+<?xml version="1.0" encoding="utf-8"?>\r
 <Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">\r
   <ItemGroup Label="ProjectConfigurations">\r
     <ProjectConfiguration Include="Debug|Win32">\r
     <ClCompile Include="..\mono\utils\mono-uri.c" />\r
     <ClCompile Include="..\mono\utils\mono-value-hash.c" />\r
     <ClCompile Include="..\mono\utils\monobitset.c" />\r
+    <ClCompile Include="..\mono\utils\mono-os-mutex.c" />\r
     <ClCompile Include="..\mono\utils\os-event-win32.c" />\r
     <ClCompile Include="..\mono\utils\strenc.c" />\r
     <ClCompile Include="..\mono\utils\atomic.c" />\r