diff --git a/src/mono/mono/eglib/CMakeLists.txt b/src/mono/mono/eglib/CMakeLists.txt index 1325ee6c1126c..69bf7e188696b 100644 --- a/src/mono/mono/eglib/CMakeLists.txt +++ b/src/mono/mono/eglib/CMakeLists.txt @@ -43,6 +43,10 @@ set(eglib_common_sources gunicode.c unicode-data.h) +if(HAVE_CLOCK_NANOSLEEP) +list(APPEND eglib_common_sources gclock-nanosleep.c) +endif() + addprefix(eglib_sources ../eglib/ "${eglib_platform_sources};${eglib_common_sources}") add_library(eglib_objects OBJECT "${eglib_sources}") diff --git a/src/mono/mono/eglib/eglib-remap.h b/src/mono/mono/eglib/eglib-remap.h index c3e956842dea8..3af646a8e47b2 100644 --- a/src/mono/mono/eglib/eglib-remap.h +++ b/src/mono/mono/eglib/eglib-remap.h @@ -318,3 +318,7 @@ #define g_ascii_charcmp monoeg_ascii_charcmp #define g_ascii_charcasecmp monoeg_ascii_charcasecmp #define g_warning_d monoeg_warning_d + +#ifdef HAVE_CLOCK_NANOSLEEP +#define g_clock_nanosleep monoeg_clock_nanosleep +#endif diff --git a/src/mono/mono/eglib/gclock-nanosleep.c b/src/mono/mono/eglib/gclock-nanosleep.c new file mode 100644 index 0000000000000..f2ced8b2c07d1 --- /dev/null +++ b/src/mono/mono/eglib/gclock-nanosleep.c @@ -0,0 +1,31 @@ +/* + * gclock_nanosleep.c: Clock nanosleep on platforms that have clock_nanosleep(). + * + * Copyright 2022 Microsoft + * Licensed under the MIT license. See LICENSE file in the project root for full license information. +*/ + +#include +#include +#include + +gint +g_clock_nanosleep (clockid_t clockid, gint flags, const struct timespec *request, struct timespec *remain) +{ + gint ret = 0; + +#if defined(HAVE_CLOCK_NANOSLEEP) && !defined(__PASE__) + ret = clock_nanosleep (clockid, flags, request, remain); +#else + g_assert_not_reached (); +#endif + +#ifdef HOST_ANDROID + // Workaround for incorrect implementation of clock_nanosleep return value on old Android (<=5.1) + // See https://github.com/xamarin/xamarin-android/issues/6600 + if (ret == -1) + ret = errno; +#endif + + return ret; +} diff --git a/src/mono/mono/eglib/gdate-unix.c b/src/mono/mono/eglib/gdate-unix.c index 53f4bbb3d5adc..9a98e66304576 100644 --- a/src/mono/mono/eglib/gdate-unix.c +++ b/src/mono/mono/eglib/gdate-unix.c @@ -64,7 +64,7 @@ g_usleep (gulong microseconds) } do { - ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); + ret = g_clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); if (ret != 0 && ret != EINTR) g_error ("%s: clock_nanosleep () returned %d", __func__, ret); } while (ret == EINTR); diff --git a/src/mono/mono/eglib/glib.h b/src/mono/mono/eglib/glib.h index 14872b9814f48..5cc269957307e 100644 --- a/src/mono/mono/eglib/glib.h +++ b/src/mono/mono/eglib/glib.h @@ -28,6 +28,7 @@ #include #include #include +#include // - Pointers should only be converted to or from pointer-sized integers. // - Any size integer can be converted to any other size integer. @@ -1506,4 +1507,13 @@ mono_qsort (void* base, size_t num, size_t size, int (*compare)(const void*, con #define g_try_realloc(obj, size) (g_cast (monoeg_try_realloc ((obj), (size)))) #define g_memdup(mem, size) (g_cast (monoeg_g_memdup ((mem), (size)))) +/* + * Clock Nanosleep + */ + +#ifdef HAVE_CLOCK_NANOSLEEP +gint +g_clock_nanosleep (clockid_t clockid, gint flags, const struct timespec *request, struct timespec *remain); +#endif + #endif // __GLIB_H diff --git a/src/mono/mono/mini/mini-posix.c b/src/mono/mono/mini/mini-posix.c index b706de969f5ce..8bb41ee1cb9a3 100644 --- a/src/mono/mono/mini/mini-posix.c +++ b/src/mono/mono/mini/mini-posix.c @@ -78,6 +78,7 @@ #include #include "mini-runtime.h" #include "jit-icalls.h" +#include #ifdef HOST_DARWIN #include @@ -484,7 +485,7 @@ clock_init_for_profiler (MonoProfilerSampleMode mode) * CLOCK_PROCESS_CPUTIME_ID clock but don't actually support it. For * those systems, we fall back to CLOCK_MONOTONIC if we get EINVAL. */ - if (clock_nanosleep (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME, &ts, NULL) != EINVAL) { + if (g_clock_nanosleep (CLOCK_PROCESS_CPUTIME_ID, TIMER_ABSTIME, &ts, NULL) != EINVAL) { sampling_clock = CLOCK_PROCESS_CPUTIME_ID; break; } @@ -509,7 +510,6 @@ clock_sleep_ns_abs (guint64 ns_abs) do { ret = clock_nanosleep (sampling_clock, TIMER_ABSTIME, &then, NULL); - if (ret != 0 && ret != EINTR) g_error ("%s: clock_nanosleep () returned %d", __func__, ret); } while (ret == EINTR && mono_atomic_load_i32 (&sampling_thread_running)); diff --git a/src/mono/mono/utils/mono-threads.c b/src/mono/mono/utils/mono-threads.c index e3a936a1abc3c..7697ac5002240 100644 --- a/src/mono/mono/utils/mono-threads.c +++ b/src/mono/mono/utils/mono-threads.c @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -1748,7 +1749,7 @@ mono_thread_info_sleep (guint32 ms, gboolean *alerted) } do { - ret = clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); + ret = g_clock_nanosleep (CLOCK_MONOTONIC, TIMER_ABSTIME, &target, NULL); } while (ret != 0); #elif HOST_WIN32 Sleep (ms);