From: Zoltan Varga Date: Fri, 30 Jun 2017 03:05:00 +0000 (-0400) Subject: [runtime] Use pthread_cond_timedwait_relative_np () function on osx if available... X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=commitdiff_plain;h=27ce7560302b86abce3a38fff2199d986a70bdc3;hp=51d1c47c8b35d4dd14ee52c67821b06cec596644;p=mono.git [runtime] Use pthread_cond_timedwait_relative_np () function on osx if available. (#5147) --- diff --git a/configure.ac b/configure.ac index a61341e306f..b14ee03463c 100644 --- a/configure.ac +++ b/configure.ac @@ -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 ], [ diff --git a/mono/utils/Makefile.am b/mono/utils/Makefile.am index f85393101e4..e16931a2888 100644 --- a/mono/utils/Makefile.am +++ b/mono/utils/Makefile.am @@ -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 index 00000000000..aea54c4dd8f --- /dev/null +++ b/mono/utils/mono-os-mutex.c @@ -0,0 +1,84 @@ +/** + * \file + * Portability wrappers around POSIX Mutexes + * + * Authors: Jeffrey Stedfast + * + * Copyright 2002 Ximian, Inc. (www.ximian.com) + * + * Licensed under the MIT license. See LICENSE file in the project root for full license information. + * + */ + +#include + +#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 + +#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 */ diff --git a/mono/utils/mono-os-mutex.h b/mono/utils/mono-os-mutex.h index 3888d26441d..be1f6485886 100644 --- a/mono/utils/mono-os-mutex.h +++ b/mono/utils/mono-os-mutex.h @@ -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) diff --git a/msvc/libmonoutils.vcxproj b/msvc/libmonoutils.vcxproj index bd512ab75e6..29903290d33 100644 --- a/msvc/libmonoutils.vcxproj +++ b/msvc/libmonoutils.vcxproj @@ -1,4 +1,4 @@ - + @@ -109,6 +109,7 @@ +