Skip to content

Commit 77f706c

Browse files
author
Vladimir Veljkovic
committed
Abstracted clock_gettime() to be able to build on OSX
1 parent 20909f6 commit 77f706c

File tree

8 files changed

+91
-3
lines changed

8 files changed

+91
-3
lines changed

core/samples/pubnub_sync_sample.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
22
#include "pubnub_sync.h"
33

4+
#include "pubnub_helper.h"
5+
46
#include <stdio.h>
57

68

posix/README.md

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,16 @@ build on any regular POSIX system with a C compiler. To use a compiler
2525
of your choice (rather than the default one), say, `clang`, run:
2626

2727
make -f posix.mk CC=clang
28+
29+
30+
## OSX / Darwin remarks
31+
32+
While being a "mostly POSIX" compliant environment, OSX, in its
33+
"Darwin" OS base, doesn't support POSIX standard `clock_gettime()`
34+
API. It is strange as this is a well-known and often complained
35+
about, and the actual code to implement it is rather simple.
36+
37+
Anyway, to be able to work on OSX / Darwin, we have a small module
38+
that abstracts "getting a monotonic clock time", with an
39+
implementation for POSIX and another for Darwin. You have to link the
40+
right one, and we do that in `posix.mk`.

posix/monotonic_clock_get_time.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
#include "monotonic_clock_get_time.h"
2+
3+
4+
int monotonic_clock_get_time(struct timespec *tp)
5+
{
6+
return clock_gettime(CLOCK_MONOTONIC, tp);
7+
}

posix/monotonic_clock_get_time.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#if !defined INC_MONOTONIC_CLOCK_GET_TIME
2+
#define INC_MONOTONIC_CLOCK_GET_TIME
3+
4+
#include <time.h>
5+
6+
/** How many "millis" in a "nano" of some (any) unit. */
7+
#define MILLI_IN_NANO (1000 * 1000)
8+
9+
/** How many "nanos" in one (unit) of something. */
10+
#define UNIT_IN_NANO (1000 * MILLI_IN_NANO)
11+
12+
/** This abstracts getting of monotonic clock time. On POSIX compliant
13+
systems, this is a simple `clock_gettime(CLOCK_MONOTONIC, tp)`.
14+
But, not all Unix-like OSes are POSIX compliant that way, with OSX
15+
/ Darwin being a well-known one.
16+
*/
17+
int monotonic_clock_get_time(struct timespec *tp);
18+
19+
20+
#endif /* !defined INC_MONOTONIC_CLOCK_GET_TIME */
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
2+
#include "monotonic_clock_get_time.h"
3+
4+
#include <mach/mach.h>
5+
#include <mach/mach_time.h>
6+
#include <unistd.h>
7+
8+
9+
int monotonic_clock_get_time(struct timespec *tp)
10+
{
11+
static mach_timebase_info_data_t s_time_base_info;
12+
uint64_t absolute_time = mach_absolute_time();
13+
uint64_t nanos;
14+
15+
if (0 == s_time_base_info.denom) {
16+
/* This is obviously not thread safe, but, we don't care, as
17+
we always call it from the same thread. A thread safe
18+
variant would either always call it, or provide some kind
19+
of protection (it is actually hard to foresee which one of
20+
those approaches would be faster).
21+
*/
22+
mach_timebase_info(&s_time_base_info);
23+
}
24+
nanos = (absolute_time * s_time_base_info.numer) / s_time_base_info.denom;
25+
tp->tv_sec = nanos / UNIT_IN_NANO;
26+
tp->tv_nsec = nanos % UNIT_IN_NANO;
27+
28+
return 0;
29+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
2+
#include "monotonic_clock_get_time.h"
3+
4+
5+
int monotonic_clock_get_time(struct timespec *tp)
6+
{
7+
return clock_gettime(CLOCK_MONOTONIC, tp);
8+
}

posix/posix.mk

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,12 @@
11
SOURCEFILES = ../core/pubnub_coreapi.c ../core/pubnub_ccore.c ../core/pubnub_netcore.c ../lib/sockets/pbpal_sockets.c ../lib/sockets/pbpal_resolv_and_connect_sockets.c ../core/pubnub_alloc_std.c ../core/pubnub_assert_std.c ../core/pubnub_generate_uuid.c ../core/pubnub_blocking_io.c ../core/pubnub_json_parse.c ../core/pubnub_helper.c pubnub_version_posix.c pubnub_generate_uuid_posix.c pbpal_posix_blocking_io.c
22

3+
OS := $(shell uname)
4+
ifeq ($(OS),Darwin)
5+
SOURCEFILES += monotonic_clock_get_time_darwin.c
6+
else
7+
SOURCEFILES += monotonic_clock_get_time_posix.c
8+
endif
9+
310
CFLAGS =-g -I ../core -I . -I fntest -I ../core/fntest -Wall
411
# -g enables debugging, remove to get a smaller executable
512

posix/pubnub_ntf_callback_posix.c

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/* -*- c-file-style:"stroustrup"; indent-tabs-mode: nil -*- */
22
#include "pubnub_ntf_callback.h"
33

4+
#include "monotonic_clock_get_time.h"
5+
46
#include "pubnub_internal.h"
57
#include "pubnub_assert.h"
68
#include "pbntf_trans_outcome_common.h"
@@ -79,9 +81,9 @@ void* socket_watcher_thread(void *arg)
7981
for (;;) {
8082
struct timespec timspec;
8183

82-
clock_gettime(CLOCK_MONOTONIC, &timspec);
83-
timspec.tv_sec = (timspec.tv_nsec + 300) / 1000;
84-
timspec.tv_nsec = (timspec.tv_nsec + 300) % 1000;
84+
monotonic_clock_get_time(&timspec);
85+
timspec.tv_sec = (timspec.tv_nsec + 300*MILLI_IN_NANO) / UNIT_IN_NANO;
86+
timspec.tv_nsec = (timspec.tv_nsec + 300*MILLI_IN_NANO) % UNIT_IN_NANO;
8587

8688
pthread_mutex_lock(&m_watcher.mutw);
8789
pthread_cond_timedwait(&m_watcher.condw, &m_watcher.mutw, &timspec);

0 commit comments

Comments
 (0)