summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean McBride <sean@rogue-research.com>2022-04-15 13:37:54 -0400
committerTormod Volden <debian.tormod@gmail.com>2022-06-26 17:09:07 +0200
commitd520f4d5e9c6593ed61a32cc01a3eeec4e5387c6 (patch)
tree645720ef58126bc49e970b448c044567aaf86ed1
parentba698478afc3d3a72644eef9fc4cd24ce8383a4c (diff)
downloadlibusb-d520f4d5e9c6593ed61a32cc01a3eeec4e5387c6.tar.gz
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
-rw-r--r--Xcode/config.h6
-rw-r--r--configure.ac26
-rw-r--r--libusb/libusbi.h2
-rw-r--r--libusb/os/darwin_usb.c62
-rw-r--r--libusb/version_nano.h2
5 files changed, 29 insertions, 69 deletions
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 @@ esac
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 @@ static inline void usbi_localize_device_descriptor(struct libusb_device_descript
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 const mach_port_t darwin_default_master_port = 0;
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 @@ static int darwin_first_time_init(void) {
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 @@ static void darwin_exit (struct libusb_context *ctx) {
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 @@ static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
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