Skip to content

Commit a8b28e8

Browse files
committed
Merge branch 'add-os-x-support'
Closes #4.
2 parents 1225869 + b31616c commit a8b28e8

File tree

4 files changed

+64
-1
lines changed

4 files changed

+64
-1
lines changed

configure.ac

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,10 @@ AC_TYPE_UINT32_T
5555
AC_CHECK_TYPE([struct timespec], [], [AC_MSG_ERROR([missing struct timespec])], [[#include <time.h>]])
5656

5757
# Checks for functions.
58-
AC_CHECK_FUNCS([clock_gettime], [], [AC_MSG_ERROR([missing clock_gettime])])
58+
AC_CHECK_FUNCS([clock_gettime],
59+
[AC_DEFINE([HAVE_CLOCK_GETTIME])],
60+
[AC_CHECK_FUNCS([host_get_clock_service], [AC_DEFINE([HAVE_HOST_GET_CLOCK_SERVICE])], [AC_MSG_ERROR([no clock_gettime or host_get_clock_service])])]
61+
)
5962

6063
# Checks for compiler flags.
6164
CCHECKFLAGS="-Wno-error"

libcurvecpr/lib/util.c

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
#include <curvecpr/bytes.h>
66

77
#include <time.h>
8+
#ifdef HAVE_HOST_GET_CLOCK_SERVICE
9+
#include <libkern/OSAtomic.h>
10+
#include <mach/clock.h>
11+
#include <mach/mach.h>
12+
#include <mach/mach_error.h>
13+
#include <stdint.h>
14+
#endif
815

916
#include <sodium/randombytes.h>
1017

@@ -29,9 +36,37 @@ long long curvecpr_util_random_mod_n (long long n)
2936
/* XXX: Nanosecond granularity limits users to 1 terabyte per second. */
3037
long long curvecpr_util_nanoseconds (void)
3138
{
39+
/* XXX: host_get_clock_service() has been officially deprecated for years;
40+
this may need to be updated in the future. */
41+
#ifdef HAVE_HOST_GET_CLOCK_SERVICE
42+
static int32_t cclock_registered = 0;
43+
static volatile clock_serv_t cclock = 0;
44+
mach_timespec_t t;
45+
46+
if (!cclock) {
47+
if (OSAtomicCompareAndSwap32Barrier(0, 1, &cclock_registered) == 1) {
48+
clock_serv_t cclock_actual;
49+
50+
if (host_get_clock_service(mach_host_self(), CALENDAR_CLOCK, &cclock_actual) != KERN_SUCCESS) {
51+
cclock_registered = 0;
52+
return -1;
53+
}
54+
55+
cclock = cclock_actual;
56+
} else {
57+
while (!cclock)
58+
/* Wait for clock to become available */;
59+
}
60+
}
61+
62+
if (clock_get_time(cclock, &t) != KERN_SUCCESS)
63+
return -1;
64+
#else
3265
struct timespec t;
66+
3367
if (clock_gettime(CLOCK_REALTIME, &t) != 0)
3468
return -1;
69+
#endif
3570

3671
return t.tv_sec * 1000000000LL + t.tv_nsec;
3772
}

libcurvecpr/test/Makefile.am

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,7 @@ messager_test_recv_requests_removal_from_sendmarkq_SOURCES = messager/test_recv_
1313
check_PROGRAMS += messager/test_send_with_1_failure_moves_message_from_sendq
1414
messager_test_send_with_1_failure_moves_message_from_sendq_SOURCES = messager/test_send_with_1_failure_moves_message_from_sendq.c
1515

16+
check_PROGRAMS += util/test_nanoseconds
17+
util_test_nanoseconds_SOURCES = util/test_nanoseconds.c
18+
1619
TESTS = $(check_PROGRAMS)
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
#include <check.h>
2+
#include <check_extras.h>
3+
4+
#include <curvecpr/util.h>
5+
6+
START_TEST (test_nanoseconds)
7+
{
8+
long long nanoseconds = curvecpr_util_nanoseconds();
9+
10+
fail_if(nanoseconds < 0);
11+
fail_unless(nanoseconds > 1374047000000000000LL);
12+
13+
/* On OS X, we may cache the kernel clock reference. Make sure it still
14+
works. */
15+
nanoseconds = curvecpr_util_nanoseconds();
16+
17+
fail_if(nanoseconds < 0);
18+
fail_unless(nanoseconds > 1374047000000000000LL);
19+
}
20+
END_TEST
21+
22+
RUN_TEST (test_nanoseconds)

0 commit comments

Comments
 (0)