Fork me on GitHub
mach_gettime.h
Go to the documentation of this file.
1 #ifndef MACH_GETTIME_H
2 #define MACH_GETTIME_H
3 
4 #include <sys/types.h>
5 #include <sys/_types/_timespec.h>
6 #include <mach/mach.h>
7 #include <mach/clock.h>
8 #include <mach/mach_time.h>
9 
10 /* The opengroup spec isn't clear on the mapping from REALTIME to CALENDAR
11  being appropriate or not.
12  http://pubs.opengroup.org/onlinepubs/009695299/basedefs/time.h.html */
13 
14 // XXX only supports a single timer
15 #define TIMER_ABSTIME -1
16 #define CLOCK_REALTIME CALENDAR_CLOCK
17 #define CLOCK_MONOTONIC SYSTEM_CLOCK
18 
19 #if !defined(__DARWIN_C_LEVEL) || __DARWIN_C_LEVEL < 199309L
20 typedef int clockid_t;
21 #endif
22 
23 /* the mach kernel uses struct mach_timespec, so struct timespec
24  is loaded from <sys/_types/_timespec.h> for compatability */
25 // struct timespec { time_t tv_sec; long tv_nsec; };
26 
27 int clock_gettime(clockid_t clk_id, struct timespec *tp);
28 
29 #include <mach/mach_time.h>
30 
31 #define MT_NANO (+1.0E-9)
32 #define MT_GIGA UINT64_C(1000000000)
33 
34 // TODO create a list of timers,
35 static double mt_timebase = 0.0;
36 static uint64_t mt_timestart = 0;
37 
38 // TODO be more careful in a multithreaded environement
39 int clock_gettime(clockid_t clk_id, struct timespec *tp)
40 {
41  kern_return_t retval = KERN_SUCCESS;
42  if( clk_id == TIMER_ABSTIME)
43  {
44  if (!mt_timestart) { // only one timer, initilized on the first call to the TIMER
45  mach_timebase_info_data_t tb = { 0 };
46  mach_timebase_info(&tb);
47  mt_timebase = tb.numer;
48  mt_timebase /= tb.denom;
49  mt_timestart = mach_absolute_time();
50  }
51 
52  double diff = (mach_absolute_time() - mt_timestart) * mt_timebase;
53  tp->tv_sec = diff * MT_NANO;
54  tp->tv_nsec = diff - (tp->tv_sec * MT_GIGA);
55  }
56  else // other clk_ids are mapped to the coresponding mach clock_service
57  {
58  clock_serv_t cclock;
59  mach_timespec_t mts;
60 
61  host_get_clock_service(mach_host_self(), clk_id, &cclock);
62  retval = clock_get_time(cclock, &mts);
63  mach_port_deallocate(mach_task_self(), cclock);
64 
65  tp->tv_sec = mts.tv_sec;
66  tp->tv_nsec = mts.tv_nsec;
67  }
68 
69  return retval;
70 }
71 #endif
#define TIMER_ABSTIME
Definition: mach_gettime.h:15
int clockid_t
Definition: mach_gettime.h:20
int clock_gettime(clockid_t clk_id, struct timespec *tp)
Definition: mach_gettime.h:39
#define MT_GIGA
Definition: mach_gettime.h:32
#define MT_NANO
Definition: mach_gettime.h:31