summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChris Dickens <christopher.a.dickens@gmail.com>2020-01-26 22:43:28 -0800
committerChris Dickens <christopher.a.dickens@gmail.com>2020-03-15 23:31:14 -0700
commit26b16eb65a61b37b64ce8962b5b7d927c3c54a7d (patch)
tree24091a43dc1cec22b078c9b2de886ddcff7ae3c8
parentf5c9f6794dc8afd8789e383bbcbf0eab087c55f2 (diff)
downloadlibusb-26b16eb65a61b37b64ce8962b5b7d927c3c54a7d.tar.gz
core: Kill usbi_backend.clock_gettime() function
Out of all the backends supported by libusb, only two need to provide an implementation of the clock_gettime() function. Windows completely lacks such a function and versions of Mac OS prior to 10.12 do not provide it. In all other cases the backend simply ends up calling the C library's clock_gettime() function. Let's optimize for the common case and check for the availability of clock_gettime() during configure. If available, we will just call it directly from any part of the library that needs it. If not available, the backend is required to provide an implementation of usbi_clock_gettime() that matches the current requirements. Closes #685 Signed-off-by: Chris Dickens <christopher.a.dickens@gmail.com>
-rw-r--r--Xcode/config.h7
-rw-r--r--configure.ac9
-rw-r--r--libusb/core.c4
-rw-r--r--libusb/io.c6
-rw-r--r--libusb/libusbi.h32
-rw-r--r--libusb/os/darwin_usb.c32
-rw-r--r--libusb/os/haiku_usb_raw.cpp12
-rw-r--r--libusb/os/linux_usbfs.c14
-rw-r--r--libusb/os/netbsd_usb.c15
-rw-r--r--libusb/os/null_usb.c14
-rw-r--r--libusb/os/openbsd_usb.c15
-rw-r--r--libusb/os/sunos_usb.c14
-rw-r--r--libusb/os/threads_posix.c2
-rw-r--r--libusb/os/windows_common.c9
-rw-r--r--libusb/version_nano.h2
15 files changed, 55 insertions, 132 deletions
diff --git a/Xcode/config.h b/Xcode/config.h
index 694fd9a..1815715 100644
--- a/Xcode/config.h
+++ b/Xcode/config.h
@@ -1,5 +1,12 @@
/* config.h. Manually generated for Xcode. */
+/* On 10.12 and later, use newly available clock_*() functions */
+#include <AvailabilityMacros.h>
+#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+#endif
+
/* Default visibility */
#define DEFAULT_VISIBILITY /**/
diff --git a/configure.ac b/configure.ac
index 6512078..a9eddba 100644
--- a/configure.ac
+++ b/configure.ac
@@ -215,6 +215,15 @@ fi
dnl headers not available on all platforms but required on others
AC_CHECK_HEADERS([sys/time.h])
+dnl the clock_gettime() function needs certain clock IDs defined
+AC_CHECK_FUNCS([clock_gettime], [have_clock_gettime=yes], [have_clockgettime=no])
+if test "x$have_clock_gettime" = xyes; then
+ AC_CHECK_DECL([CLOCK_REALTIME], [], [AC_MSG_ERROR([C library headers missing definition for CLOCK_REALTIME])], [[#include <time.h>]])
+ AC_CHECK_DECL([CLOCK_MONOTONIC], [], [AC_MSG_ERROR([C library headers missing definition for CLOCK_MONOTONIC])], [[#include <time.h>]])
+elif test "x$backend" != xdarwin && test "x$backend" != xwindows; then
+ AC_MSG_ERROR([clock_gettime() is required on this platform])
+fi
+
dnl timerfd support
if test "x$backend" = xlinux || test "x$backend" = xsunos; then
AC_ARG_ENABLE([timerfd],
diff --git a/libusb/core.c b/libusb/core.c
index ad2f837..85d62e4 100644
--- a/libusb/core.c
+++ b/libusb/core.c
@@ -2246,7 +2246,7 @@ int API_EXPORTED libusb_init(libusb_context **context)
usbi_mutex_static_lock(&default_context_lock);
if (!timestamp_origin.tv_sec) {
- usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timestamp_origin);
+ usbi_clock_gettime(USBI_CLOCK_REALTIME, &timestamp_origin);
}
if (!context && usbi_default_context) {
@@ -2578,7 +2578,7 @@ void usbi_log_v(struct libusb_context *ctx, enum libusb_log_level level,
global_debug = (ctx_level == LIBUSB_LOG_LEVEL_DEBUG);
#endif
- usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &now);
+ usbi_clock_gettime(USBI_CLOCK_REALTIME, &now);
if ((global_debug) && (!has_debug_header_been_displayed)) {
has_debug_header_been_displayed = 1;
usbi_log_str(LIBUSB_LOG_LEVEL_DEBUG, "[timestamp] [threadID] facility level [function call] <message>" USBI_LOG_LINE_END);
diff --git a/libusb/io.c b/libusb/io.c
index 1068f9f..b843d4a 100644
--- a/libusb/io.c
+++ b/libusb/io.c
@@ -1210,7 +1210,7 @@ static int calculate_timeout(struct usbi_transfer *itransfer)
return 0;
}
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &itransfer->timeout);
+ r = usbi_clock_gettime(USBI_CLOCK_MONOTONIC, &itransfer->timeout);
if (r < 0) {
usbi_err(ITRANSFER_CTX(itransfer),
"failed to read monotonic clock, errno=%d", errno);
@@ -2024,7 +2024,7 @@ static int handle_timeouts_locked(struct libusb_context *ctx)
return 0;
/* get current time */
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime);
+ r = usbi_clock_gettime(USBI_CLOCK_MONOTONIC, &systime);
if (r < 0)
return r;
@@ -2624,7 +2624,7 @@ int API_EXPORTED libusb_get_next_timeout(libusb_context *ctx,
return 0;
}
- r = usbi_backend.clock_gettime(USBI_CLOCK_MONOTONIC, &systime);
+ r = usbi_clock_gettime(USBI_CLOCK_MONOTONIC, &systime);
if (r < 0) {
usbi_err(ctx, "failed to read monotonic clock, errno=%d", errno);
return 0;
diff --git a/libusb/libusbi.h b/libusb/libusbi.h
index da9334f..faaeff3 100644
--- a/libusb/libusbi.h
+++ b/libusb/libusbi.h
@@ -454,10 +454,24 @@ struct libusb_device_handle {
int auto_detach_kernel_driver;
};
-enum {
- USBI_CLOCK_MONOTONIC,
- USBI_CLOCK_REALTIME
-};
+#ifdef HAVE_CLOCK_GETTIME
+#define USBI_CLOCK_REALTIME CLOCK_REALTIME
+#define USBI_CLOCK_MONOTONIC CLOCK_MONOTONIC
+#define usbi_clock_gettime clock_gettime
+#else
+/* If the platform doesn't provide the clock_gettime() function, the backend
+ * must provide its own implementation. Two clocks must be supported by the
+ * backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
+ *
+ * Description of clocks:
+ * USBI_CLOCK_REALTIME: clock returns time since system epoch.
+ * USBI_CLOCK_MONOTONIC: clock returns time since unspecified start time
+ * (usually boot).
+ */
+#define USBI_CLOCK_REALTIME 0
+#define USBI_CLOCK_MONOTONIC 1
+int usbi_clock_gettime(int clk_id, struct timespec *tp);
+#endif
/* in-memory transfer layout:
*
@@ -1158,16 +1172,6 @@ struct usbi_os_backend {
*/
int (*handle_transfer_completion)(struct usbi_transfer *itransfer);
- /* Get time from specified clock. At least two clocks must be implemented
- by the backend: USBI_CLOCK_REALTIME, and USBI_CLOCK_MONOTONIC.
-
- Description of clocks:
- USBI_CLOCK_REALTIME : clock returns time since system epoch.
- USBI_CLOCK_MONOTONIC: clock returns time since unspecified start
- time (usually boot).
- */
- int (*clock_gettime)(int clkid, struct timespec *tp);
-
/* Number of bytes to reserve for per-context private backend data.
* This private data area is accessible by calling
* usbi_get_context_priv() on the libusb_context instance.
diff --git a/libusb/os/darwin_usb.c b/libusb/os/darwin_usb.c
index 956e7b0..e0a364e 100644
--- a/libusb/os/darwin_usb.c
+++ b/libusb/os/darwin_usb.c
@@ -47,13 +47,6 @@
#include <objc/objc-auto.h>
#endif
-/* On 10.12 and later, use newly available clock_*() functions */
-#if MAC_OS_X_VERSION_MIN_REQUIRED >= 101200
-#define OSX_USE_CLOCK_GETTIME 1
-#else
-#define OSX_USE_CLOCK_GETTIME 0
-#endif
-
#include "darwin_usb.h"
static pthread_mutex_t libusb_darwin_init_mutex = PTHREAD_MUTEX_INITIALIZER;
@@ -63,7 +56,7 @@ static int init_count = 0;
static pthread_mutex_t libusb_darwin_at_mutex = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t libusb_darwin_at_cond = PTHREAD_COND_INITIALIZER;
-#if !OSX_USE_CLOCK_GETTIME
+#if !defined(HAVE_CLOCK_GETTIME)
static clock_serv_t clock_realtime;
static clock_serv_t clock_monotonic;
#endif
@@ -585,7 +578,7 @@ static int darwin_init(struct libusb_context *ctx) {
first_init = (1 == ++init_count);
do {
-#if !OSX_USE_CLOCK_GETTIME
+#if !defined(HAVE_CLOCK_GETTIME)
if (first_init) {
/* create the clocks that will be used if clock_gettime() is not available */
host_name_port_t host_self;
@@ -624,7 +617,7 @@ static int darwin_init(struct libusb_context *ctx) {
} while (0);
if (LIBUSB_SUCCESS != rc) {
-#if !OSX_USE_CLOCK_GETTIME
+#if !defined(HAVE_CLOCK_GETTIME)
if (first_init) {
mach_port_deallocate(mach_task_self(), clock_realtime);
mach_port_deallocate(mach_task_self(), clock_monotonic);
@@ -653,7 +646,7 @@ static void darwin_exit (struct libusb_context *ctx) {
pthread_mutex_unlock (&libusb_darwin_at_mutex);
pthread_join (libusb_darwin_at, NULL);
-#if !OSX_USE_CLOCK_GETTIME
+#if !defined(HAVE_CLOCK_GETTIME)
mach_port_deallocate(mach_task_self(), clock_realtime);
mach_port_deallocate(mach_task_self(), clock_monotonic);
#endif
@@ -2174,8 +2167,8 @@ static int darwin_handle_transfer_completion (struct usbi_transfer *itransfer) {
return usbi_handle_transfer_completion (itransfer, darwin_transfer_status (itransfer, tpriv->result));
}
-static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
-#if !OSX_USE_CLOCK_GETTIME
+#if !defined(HAVE_CLOCK_GETTIME)
+int usbi_clock_gettime(int clk_id, struct timespec *tp) {
mach_timespec_t sys_time;
clock_serv_t clock_ref;
@@ -2198,17 +2191,8 @@ static int darwin_clock_gettime(int clk_id, struct timespec *tp) {
tp->tv_nsec = sys_time.tv_nsec;
return LIBUSB_SUCCESS;
-#else
- switch (clk_id) {
- case USBI_CLOCK_MONOTONIC:
- return clock_gettime(CLOCK_MONOTONIC, tp);
- case USBI_CLOCK_REALTIME:
- return clock_gettime(CLOCK_REALTIME, tp);
- default:
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-#endif
}
+#endif
#if InterfaceVersion >= 550
static int darwin_alloc_streams (struct libusb_device_handle *dev_handle, uint32_t num_streams, unsigned char *endpoints,
@@ -2304,8 +2288,6 @@ const struct usbi_os_backend usbi_backend = {
.handle_transfer_completion = darwin_handle_transfer_completion,
- .clock_gettime = darwin_clock_gettime,
-
.device_priv_size = sizeof(struct darwin_device_priv),
.device_handle_priv_size = sizeof(struct darwin_device_handle_priv),
.transfer_priv_size = sizeof(struct darwin_transfer_priv),
diff --git a/libusb/os/haiku_usb_raw.cpp b/libusb/os/haiku_usb_raw.cpp
index 9bd89c4..3162371 100644
--- a/libusb/os/haiku_usb_raw.cpp
+++ b/libusb/os/haiku_usb_raw.cpp
@@ -193,16 +193,6 @@ haiku_handle_transfer_completion(struct usbi_transfer *itransfer)
return usbi_handle_transfer_completion(itransfer, status);
}
-static int
-haiku_clock_gettime(int clkid, struct timespec *tp)
-{
- if (clkid == USBI_CLOCK_REALTIME)
- return clock_gettime(CLOCK_REALTIME, tp);
- if (clkid == USBI_CLOCK_MONOTONIC)
- return clock_gettime(CLOCK_MONOTONIC, tp);
- return LIBUSB_ERROR_INVALID_PARAM;
-}
-
const struct usbi_os_backend usbi_backend = {
.name = "Haiku usbfs",
.caps = 0,
@@ -229,8 +219,6 @@ const struct usbi_os_backend usbi_backend = {
.handle_transfer_completion = haiku_handle_transfer_completion,
- .clock_gettime = haiku_clock_gettime,
-
.device_priv_size = sizeof(USBDevice *),
.device_handle_priv_size = sizeof(USBDeviceHandle *),
.transfer_priv_size = sizeof(USBTransfer *),
diff --git a/libusb/os/linux_usbfs.c b/libusb/os/linux_usbfs.c
index d6c8ea4..e1b25b0 100644
--- a/libusb/os/linux_usbfs.c
+++ b/libusb/os/linux_usbfs.c
@@ -2664,18 +2664,6 @@ out:
return r;
}
-static int op_clock_gettime(int clk_id, struct timespec *tp)
-{
- switch (clk_id) {
- case USBI_CLOCK_MONOTONIC:
- return clock_gettime(CLOCK_MONOTONIC, tp);
- case USBI_CLOCK_REALTIME:
- return clock_gettime(CLOCK_REALTIME, tp);
- default:
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-}
-
const struct usbi_os_backend usbi_backend = {
.name = "Linux usbfs",
.caps = USBI_CAP_HAS_HID_ACCESS|USBI_CAP_SUPPORTS_DETACH_KERNEL_DRIVER,
@@ -2717,8 +2705,6 @@ const struct usbi_os_backend usbi_backend = {
.handle_events = op_handle_events,
- .clock_gettime = op_clock_gettime,
-
.device_priv_size = sizeof(struct linux_device_priv),
.device_handle_priv_size = sizeof(struct linux_device_handle_priv),
.transfer_priv_size = sizeof(struct linux_transfer_priv),
diff --git a/libusb/os/netbsd_usb.c b/libusb/os/netbsd_usb.c
index 8bbda30..66ff887 100644
--- a/libusb/os/netbsd_usb.c
+++ b/libusb/os/netbsd_usb.c
@@ -74,7 +74,6 @@ static void netbsd_destroy_device(struct libusb_device *);
static int netbsd_submit_transfer(struct usbi_transfer *);
static int netbsd_cancel_transfer(struct usbi_transfer *);
static int netbsd_handle_transfer_completion(struct usbi_transfer *);
-static int netbsd_clock_gettime(int, struct timespec *);
/*
* Private functions
@@ -113,8 +112,6 @@ const struct usbi_os_backend usbi_backend = {
.handle_transfer_completion = netbsd_handle_transfer_completion,
- .clock_gettime = netbsd_clock_gettime,
-
.device_priv_size = sizeof(struct device_priv),
.device_handle_priv_size = sizeof(struct handle_priv),
};
@@ -469,18 +466,6 @@ netbsd_handle_transfer_completion(struct usbi_transfer *itransfer)
}
int
-netbsd_clock_gettime(int clkid, struct timespec *tp)
-{
- if (clkid == USBI_CLOCK_REALTIME)
- return clock_gettime(CLOCK_REALTIME, tp);
-
- if (clkid == USBI_CLOCK_MONOTONIC)
- return clock_gettime(CLOCK_MONOTONIC, tp);
-
- return (LIBUSB_ERROR_INVALID_PARAM);
-}
-
-int
_errno_to_libusb(int err)
{
switch (err) {
diff --git a/libusb/os/null_usb.c b/libusb/os/null_usb.c
index c050322..03c33e1 100644
--- a/libusb/os/null_usb.c
+++ b/libusb/os/null_usb.c
@@ -106,19 +106,6 @@ null_cancel_transfer(struct usbi_transfer *itransfer)
return LIBUSB_ERROR_NOT_SUPPORTED;
}
-static int
-null_clock_gettime(int clkid, struct timespec *tp)
-{
- switch (clkid) {
- case USBI_CLOCK_MONOTONIC:
- return clock_gettime(CLOCK_REALTIME, tp);
- case USBI_CLOCK_REALTIME:
- return clock_gettime(CLOCK_REALTIME, tp);
- default:
- return LIBUSB_ERROR_INVALID_PARAM;
- }
-}
-
const struct usbi_os_backend usbi_backend = {
.name = "Null backend",
.caps = 0,
@@ -136,5 +123,4 @@ const struct usbi_os_backend usbi_backend = {
.reset_device = null_reset_device,
.submit_transfer = null_submit_transfer,
.cancel_transfer = null_cancel_transfer,
- .clock_gettime = null_clock_gettime,
};
diff --git a/libusb/os/openbsd_usb.c b/libusb/os/openbsd_usb.c
index 4788267..430023a 100644
--- a/libusb/os/openbsd_usb.c
+++ b/libusb/os/openbsd_usb.c
@@ -74,7 +74,6 @@ static void obsd_destroy_device(struct libusb_device *);
static int obsd_submit_transfer(struct usbi_transfer *);
static int obsd_cancel_transfer(struct usbi_transfer *);
static int obsd_handle_transfer_completion(struct usbi_transfer *);
-static int obsd_clock_gettime(int, struct timespec *);
/*
* Private functions
@@ -114,8 +113,6 @@ const struct usbi_os_backend usbi_backend = {
.handle_transfer_completion = obsd_handle_transfer_completion,
- .clock_gettime = obsd_clock_gettime,
-
.device_priv_size = sizeof(struct device_priv),
.device_handle_priv_size = sizeof(struct handle_priv),
};
@@ -508,18 +505,6 @@ obsd_handle_transfer_completion(struct usbi_transfer *itransfer)
}
int
-obsd_clock_gettime(int clkid, struct timespec *tp)
-{
- if (clkid == USBI_CLOCK_REALTIME)
- return clock_gettime(CLOCK_REALTIME, tp);
-
- if (clkid == USBI_CLOCK_MONOTONIC)
- return clock_gettime(CLOCK_MONOTONIC, tp);
-
- return (LIBUSB_ERROR_INVALID_PARAM);
-}
-
-int
_errno_to_libusb(int err)
{
usbi_dbg("error: %s (%d)", strerror(err), err);
diff --git a/libusb/os/sunos_usb.c b/libusb/os/sunos_usb.c
index 08db3e9..8d0c812 100644
--- a/libusb/os/sunos_usb.c
+++ b/libusb/os/sunos_usb.c
@@ -80,7 +80,6 @@ static void sunos_destroy_device(struct libusb_device *);
static int sunos_submit_transfer(struct usbi_transfer *);
static int sunos_cancel_transfer(struct usbi_transfer *);
static int sunos_handle_transfer_completion(struct usbi_transfer *);
-static int sunos_clock_gettime(int, struct timespec *);
static int sunos_kernel_driver_active(struct libusb_device_handle *, int interface);
static int sunos_detach_kernel_driver (struct libusb_device_handle *dev, int interface_number);
static int sunos_attach_kernel_driver (struct libusb_device_handle *dev, int interface_number);
@@ -1505,18 +1504,6 @@ sunos_handle_transfer_completion(struct usbi_transfer *itransfer)
}
int
-sunos_clock_gettime(int clkid, struct timespec *tp)
-{
- if (clkid == USBI_CLOCK_REALTIME)
- return clock_gettime(CLOCK_REALTIME, tp);
-
- if (clkid == USBI_CLOCK_MONOTONIC)
- return clock_gettime(CLOCK_MONOTONIC, tp);
-
- return (LIBUSB_ERROR_INVALID_PARAM);
-}
-
-int
_errno_to_libusb(int err)
{
usbi_dbg("error: %s (%d)", strerror(err), err);
@@ -1662,7 +1649,6 @@ const struct usbi_os_backend usbi_backend = {
.submit_transfer = sunos_submit_transfer,
.cancel_transfer = sunos_cancel_transfer,
.handle_transfer_completion = sunos_handle_transfer_completion,
- .clock_gettime = sunos_clock_gettime,
.device_priv_size = sizeof(sunos_dev_priv_t),
.device_handle_priv_size = sizeof(sunos_dev_handle_priv_t),
.transfer_priv_size = sizeof(sunos_xfer_priv_t),
diff --git a/libusb/os/threads_posix.c b/libusb/os/threads_posix.c
index 76384ac..c18bc7a 100644
--- a/libusb/os/threads_posix.c
+++ b/libusb/os/threads_posix.c
@@ -36,7 +36,7 @@ int usbi_cond_timedwait(pthread_cond_t *cond,
struct timespec timeout;
int r;
- r = usbi_backend.clock_gettime(USBI_CLOCK_REALTIME, &timeout);
+ r = usbi_clock_gettime(USBI_CLOCK_REALTIME, &timeout);
if (r < 0)
return r;
diff --git a/libusb/os/windows_common.c b/libusb/os/windows_common.c
index 370ea60..e37a514 100644
--- a/libusb/os/windows_common.c
+++ b/libusb/os/windows_common.c
@@ -42,9 +42,11 @@ enum windows_version windows_version = WINDOWS_UNDEFINED;
static unsigned int init_count;
static bool usbdk_available;
+#if !defined(HAVE_CLOCK_GETTIME)
// Global variables for clock_gettime mechanism
static uint64_t hires_ticks_to_ps;
static uint64_t hires_frequency;
+#endif
/*
* Converts a windows error to human readable string
@@ -277,6 +279,7 @@ void windows_force_sync_completion(OVERLAPPED *overlapped, ULONG size)
static void windows_init_clock(void)
{
+#if !defined(HAVE_CLOCK_GETTIME)
LARGE_INTEGER li_frequency;
// Microsoft says that the QueryPerformanceFrequency() and
@@ -288,6 +291,7 @@ static void windows_init_clock(void)
hires_frequency = li_frequency.QuadPart;
hires_ticks_to_ps = UINT64_C(1000000000000) / hires_frequency;
usbi_dbg("hires timer frequency: %"PRIu64" Hz", hires_frequency);
+#endif
}
/* Windows version detection */
@@ -810,7 +814,8 @@ static int windows_handle_events(struct libusb_context *ctx, struct pollfd *fds,
return r;
}
-static int windows_clock_gettime(int clk_id, struct timespec *tp)
+#if !defined(HAVE_CLOCK_GETTIME)
+int usbi_clock_gettime(int clk_id, struct timespec *tp)
{
LARGE_INTEGER hires_counter;
#if !defined(_MSC_VER) || (_MSC_VER < 1900)
@@ -848,6 +853,7 @@ static int windows_clock_gettime(int clk_id, struct timespec *tp)
return LIBUSB_ERROR_INVALID_PARAM;
}
}
+#endif
// NB: MSVC6 does not support named initializers.
const struct usbi_os_backend usbi_backend = {
@@ -885,7 +891,6 @@ const struct usbi_os_backend usbi_backend = {
NULL, /* clear_transfer_priv */
windows_handle_events,
NULL, /* handle_transfer_completion */
- windows_clock_gettime,
sizeof(struct windows_context_priv),
sizeof(union windows_device_priv),
sizeof(union windows_device_handle_priv),
diff --git a/libusb/version_nano.h b/libusb/version_nano.h
index e949678..3804599 100644
--- a/libusb/version_nano.h
+++ b/libusb/version_nano.h
@@ -1 +1 @@
-#define LIBUSB_NANO 11463
+#define LIBUSB_NANO 11464