Simplify clock_gettime() conditionalization and fallback on macOS Removed the logic in configure.ac (for Darwin only) that detected if the clock_gettime() function exists. Instead, just use the preprocessor to introspect the macOS SDK version and deployment target and call clock_gettime() if they are new enough. Also replaced the fallback code for older macOS with mach_absolute_time() and gettimeofday(), which are simplier because they do not need setup and teardown carefully balanced and their usage is in one place instead of spread in multiple places in the file. Closes #1080
diff --git a/Xcode/config.h b/Xcode/config.h index 59f3463..c589a0f 100644 --- a/Xcode/config.h +++ b/Xcode/config.h
@@ -8,12 +8,6 @@ /* Define to 1 to enable message logging. */ #define ENABLE_LOGGING 1 -/* On 10.12 and later, use newly available clock_*() functions */ -#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200 -/* Define to 1 if you have the `clock_gettime' function. */ -#define HAVE_CLOCK_GETTIME 1 -#endif - /* On 10.6 and later, use newly available pthread_threadid_np() function */ #if MAC_OS_X_VERSION_MIN_REQUIRED >= 1060 /* Define to 1 if you have the 'pthread_threadid_np' function. */
diff --git a/configure.ac b/configure.ac index 07ec17e..968cdb7 100644 --- a/configure.ac +++ b/configure.ac
@@ -211,29 +211,9 @@ dnl headers not available on all platforms but required on others AC_CHECK_HEADERS([sys/time.h]) -if test "x$platform" = xposix; then - dnl check availability of clock_gettime() - if test "x$backend" = xdarwin; then - dnl need to verify that OS X target is 10.12 or later for clock_gettime() - AC_MSG_CHECKING([whether OS X target version is 10.12 or later]) - AC_COMPILE_IFELSE([AC_LANG_PROGRAM([ - #include <AvailabilityMacros.h> - #if MAC_OS_X_VERSION_MIN_REQUIRED < 101200 - # error "Target OS X version is too old" - #endif - ], [])], - [AC_MSG_RESULT([yes]) - osx_10_12_or_later=yes], - [AC_MSG_RESULT([no]) - osx_10_12_or_later=]) - if test "x$osx_10_12_or_later" = xyes; then - AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [have_clock_gettime=]) - else - AC_MSG_NOTICE([clock_gettime() is not available on target OS X version]) - fi - else - AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [AC_MSG_ERROR([clock_gettime() is required on this platform])]) - fi +dnl check availability of clock_gettime(), except don't bother on Darwin, because the result is not used. +if test "x$platform" = xposix && test "x$backend" != xdarwin; then + AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [AC_MSG_ERROR([clock_gettime() is required on this platform])]) if test "x$have_clock_gettime" = xyes; then dnl the clock_gettime() function needs certain clock IDs defined
diff --git a/libusb/libusbi.h b/libusb/libusbi.h index b1fc88c..c2b9a6b 100644 --- a/libusb/libusbi.h +++ b/libusb/libusbi.h
@@ -533,7 +533,7 @@ desc->bcdDevice = libusb_le16_to_cpu(desc->bcdDevice); } -#ifdef HAVE_CLOCK_GETTIME +#if defined(HAVE_CLOCK_GETTIME) && !defined(__APPLE__) static inline void usbi_get_monotonic_time(struct timespec *tp) { ASSERT_EQ(clock_gettime(CLOCK_MONOTONIC, tp), 0);
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c index 7730d71..c7cbc38 100644 --- a/libusb/os/darwin_usb.c +++ b/libusb/os/darwin_usb.c
@@ -32,10 +32,7 @@ #include <fcntl.h> #include <sys/sysctl.h> -#include <mach/clock.h> -#include <mach/clock_types.h> -#include <mach/mach_host.h> -#include <mach/mach_port.h> +#include <mach/mach_time.h> /* Suppress warnings about the use of the deprecated objc_registerThreadWithCollector * function. Its use is also conditionalized to only older deployment targets. */ @@ -63,11 +60,6 @@ static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER; -#if !defined(HAVE_CLOCK_GETTIME) -static clock_serv_t clock_realtime; -static clock_serv_t clock_monotonic; -#endif - #define LIBUSB_DARWIN_STARTUP_FAILURE ((CFRunLoopRef) -1) static CFRunLoopRef libusb_darwin_acfl = NULL; /* event cf loop */ @@ -608,16 +600,6 @@ return LIBUSB_ERROR_OTHER; } -#if !defined(HAVE_CLOCK_GETTIME) - /* create the clocks that will be used if clock_gettime() is not available */ - host_name_port_t host_self; - - host_self = mach_host_self(); - host_get_clock_service(host_self, CALENDAR_CLOCK, &clock_realtime); - host_get_clock_service(host_self, SYSTEM_CLOCK, &clock_monotonic); - mach_port_deallocate(mach_task_self(), host_self); -#endif - int rc = pthread_create (&libusb_darwin_at, NULL, darwin_event_thread_main, NULL); if (0 != rc) { usbi_err (NULL, "could not create event thread, error %d", rc); @@ -680,11 +662,6 @@ pthread_join (libusb_darwin_at, NULL); darwin_cleanup_devices (); - -#if !defined(HAVE_CLOCK_GETTIME) - mach_port_deallocate(mach_task_self(), clock_realtime); - mach_port_deallocate(mach_task_self(), clock_monotonic); -#endif } usbi_mutex_unlock(&darwin_cached_devices_mutex); } @@ -2402,27 +2379,36 @@ return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result)); } -#if !defined(HAVE_CLOCK_GETTIME) void usbi_get_monotonic_time(struct timespec *tp) { - mach_timespec_t sys_time; +/* Check if the SDK is new enough to declare clock_gettime(), and the deployment target is at least 10.12. */ +#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= 101200) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) + clock_gettime(CLOCK_MONOTONIC, tp); +#else + mach_timebase_info_data_t machTimeBaseInfo; + mach_timebase_info(&machTimeBaseInfo); - /* use system boot time as reference for the monotonic clock */ - clock_get_time (clock_monotonic, &sys_time); + uint64_t uptime = mach_absolute_time(); + uint64_t uptimeNano = uptime * machTimeBaseInfo.numer / machTimeBaseInfo.denom; - tp->tv_sec = sys_time.tv_sec; - tp->tv_nsec = sys_time.tv_nsec; + uint64_t uptimeSeconds = uptimeNano / NSEC_PER_SEC; + uint64_t uptimeNanoRemainder = uptimeNano - (uptimeSeconds * NSEC_PER_SEC); + + tp->tv_sec = uptimeSeconds; + tp->tv_nsec = uptimeNanoRemainder; +#endif } void usbi_get_real_time(struct timespec *tp) { - mach_timespec_t sys_time; - - /* CLOCK_REALTIME represents time since the epoch */ - clock_get_time (clock_realtime, &sys_time); - - tp->tv_sec = sys_time.tv_sec; - tp->tv_nsec = sys_time.tv_nsec; -} +/* Check if the SDK is new enough to declare clock_gettime(), and the deployment target is at least 10.12. */ +#if ((MAC_OS_X_VERSION_MAX_ALLOWED >= 101200) && (MAC_OS_X_VERSION_MIN_REQUIRED >= 101200)) + clock_gettime(CLOCK_REALTIME, tp); +#else + struct timeval tv; + gettimeofday(&tv, NULL); + tp->tv_sec = tv.tv_sec; + tp->tv_nsec = tv.tv_usec * NSEC_PER_USEC; #endif +} #if InterfaceVersion >= 550 static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
diff --git a/libusb/version_nano.h b/libusb/version_nano.h index 7830159..87b0870 100644 --- a/libusb/version_nano.h +++ b/libusb/version_nano.h
@@ -1 +1 @@ -#define LIBUSB_NANO 11727 +#define LIBUSB_NANO 11728