Skip to content

Commit

Permalink
[runtime] Use pthread_cond_timedwait_relative_np () function on osx i…
Browse files Browse the repository at this point in the history
…f available. (#5147)
  • Loading branch information
vargaz committed Jun 30, 2017
1 parent 51d1c47 commit 27ce756
Show file tree
Hide file tree
Showing 5 changed files with 90 additions and 46 deletions.
2 changes: 1 addition & 1 deletion configure.ac
Expand Up @@ -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>], [
Expand Down
1 change: 1 addition & 0 deletions mono/utils/Makefile.am
Expand Up @@ -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 \
Expand Down
84 changes: 84 additions & 0 deletions mono/utils/mono-os-mutex.c
@@ -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 */
46 changes: 2 additions & 44 deletions mono/utils/mono-os-mutex.h
Expand Up @@ -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)
Expand Down
3 changes: 2 additions & 1 deletion msvc/libmonoutils.vcxproj
@@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug|Win32">
Expand Down Expand Up @@ -109,6 +109,7 @@
<ClCompile Include="..\mono\utils\mono-uri.c" />
<ClCompile Include="..\mono\utils\mono-value-hash.c" />
<ClCompile Include="..\mono\utils\monobitset.c" />
<ClCompile Include="..\mono\utils\mono-os-mutex.c" />
<ClCompile Include="..\mono\utils\os-event-win32.c" />
<ClCompile Include="..\mono\utils\strenc.c" />
<ClCompile Include="..\mono\utils\atomic.c" />
Expand Down

0 comments on commit 27ce756

Please sign in to comment.