[PATCH 1/2] COMMON: clock_gettime for Mac OS X


Philip Preston
 

Mac OS X does not support the clock_gettime function that is used in a number of the performance testing applications, but does have equivalient fucntions. This change wraps the time functions from the mac behind clock_gettime function

Tested on

* Mac OS X 10.9.2 x86_64
* Ubuntu 12.04 x86_64

With

* Mamapublisherc / MamaSubscriberc
* Mamainboxc
* Mamalistenc / Capturereplay
* Mamaproducerc_v2 / Mamaconsumerc_v2
* Unit Tests

Signed-off-by: Phil Preston <philippreston@mac.com>
---
common/c_cpp/src/c/SConscript | 2 +
common/c_cpp/src/c/darwin/clock.c | 122 ++++++++++++++++++++++++++++++++++++++
common/c_cpp/src/c/darwin/port.h | 7 +++
3 files changed, 131 insertions(+)
create mode 100644 common/c_cpp/src/c/darwin/clock.c

diff --git a/common/c_cpp/src/c/SConscript b/common/c_cpp/src/c/SConscript
index b18e8d0..36bfe18 100644
--- a/common/c_cpp/src/c/SConscript
+++ b/common/c_cpp/src/c/SConscript
@@ -52,6 +52,8 @@ elif env['host']['os'] == 'Darwin':
'common/c_cpp/src/c/linux/platform.c'),
('common/c_cpp/src/c/wSemaphore.c',
'common/c_cpp/src/c/darwin/wSemaphore.c'),
+ ('common/c_cpp/src/c/clock.c',
+ 'common/c_cpp/src/c/darwin/clock.c'),
('common/c_cpp/src/c/network.c',
'common/c_cpp/src/c/linux/network.c'),
('common/c_cpp/src/c/environment.c',
diff --git a/common/c_cpp/src/c/darwin/clock.c b/common/c_cpp/src/c/darwin/clock.c
new file mode 100644
index 0000000..7181b7e
--- /dev/null
+++ b/common/c_cpp/src/c/darwin/clock.c
@@ -0,0 +1,122 @@
+/*
+ * OpenMAMA: The open middleware agnostic messaging API
+ * Copyright (C) 2011 NYSE Technologies, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
+ * 02110-1301 USA
+ */
+
+#include "wombat/port.h"
+
+#include <mach/mach.h>
+#include <mach/mach_time.h>
+#include <mach/clock.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+#include <sys/errno.h>
+
+#define CHECK_MACH_INITIALISED() \
+do { \
+ if (!clock_gettime_initialised) \
+ { \
+ if(GETTIME_SUCCESS != clock_gettime_init ()) \
+ return GETTIME_FAIL; \
+ } \
+} \
+while (0) \
+
+#define NANOS_IN_SEC 1000000000L
+
+// Private function declarations
+static int clock_gettime_init ();
+static int clock_gettime_internal ();
+static int clock_gettime_process_cputime_id (struct timespec * ts);
+
+// Timer variables
+static mach_timebase_info_data_t timebase_info;
+static uint64_t init_clock; // ticks boot --> initialised
+static uint8_t clock_gettime_initialised = 0;
+
+int clock_gettime (int type, struct timespec * ts)
+{
+ switch (type)
+ {
+ case CLOCK_MONOTONIC:
+ return clock_gettime_internal(ts, SYSTEM_CLOCK);
+ break;
+ case CLOCK_REALTIME:
+ return clock_gettime_internal(ts, CALENDAR_CLOCK);
+ break;
+ case CLOCK_PROCESS_CPUTIME_ID:
+ return clock_gettime_process_cputime_id (ts);
+ break;
+ default:
+ errno = EINVAL;
+ return GETTIME_FAIL;
+ }
+}
+
+int clock_gettime_init()
+{
+
+ // Initialise the timebase
+ if (0 != mach_timebase_info (&timebase_info))
+ {
+ return GETTIME_FAIL;
+ }
+
+ // Ticks since boot
+ init_clock = mach_absolute_time ();
+
+ // Only do once
+ clock_gettime_initialised = 1;
+
+ return GETTIME_SUCCESS;
+}
+
+int clock_gettime_internal(struct timespec * ts, int type)
+{
+ clock_serv_t cclock;
+ mach_timespec_t mts;
+ kern_return_t retval;
+
+ // Get the time
+ host_get_clock_service(mach_host_self(), type, &cclock);
+ retval = clock_get_time(cclock, &mts);
+ mach_port_deallocate(mach_task_self(), cclock);
+
+ ts->tv_sec = mts.tv_sec;
+ ts->tv_nsec = mts.tv_nsec;
+
+ return (retval == KERN_SUCCESS) ? GETTIME_SUCCESS : GETTIME_FAIL;
+}
+
+int clock_gettime_process_cputime_id (struct timespec * ts)
+{
+ CHECK_MACH_INITIALISED ();
+
+ // Get the time
+ uint64_t time; // ticks since mach initialised --> now
+ time = mach_absolute_time () - init_clock;
+
+ // Convert to timespec
+ uint64_t nanos; // nanos since mach initialised --> now
+ nanos = time * (uint64_t)timebase_info.numer / (uint64_t)timebase_info.denom;
+
+ ts->tv_sec = nanos / NANOS_IN_SEC;
+ ts->tv_nsec = nanos % NANOS_IN_SEC;
+
+ return GETTIME_SUCCESS;
+}
diff --git a/common/c_cpp/src/c/darwin/port.h b/common/c_cpp/src/c/darwin/port.h
index 7aa559e..52f1145 100644
--- a/common/c_cpp/src/c/darwin/port.h
+++ b/common/c_cpp/src/c/darwin/port.h
@@ -177,6 +177,13 @@ struct wtimespec

#define wnanosleep(ts, remain) nanosleep(((struct timespec*)(ts)),(remain))

+/* Add fake clock_gettime function */
+#define CLOCK_REALTIME 0
+#define CLOCK_MONOTONIC 1
+#define CLOCK_PROCESS_CPUTIME_ID 2
+#define GETTIME_SUCCESS 0
+#define GETTIME_FAIL 1
+int clock_gettime (int type, struct timespec * ts);

/* net work utility functions */
const char* getIpAddress (void);
--
1.8.5.2 (Apple Git-48)