Statistics
| Branch: | Revision:

janus-gateway / mach_gettime.h @ 1f44763c

History | View | Annotate | Download (2.06 KB)

1 b1c60d34 Yulius Tjahjadi
#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 02d70f5d Akagi201
#if !defined(__DARWIN_C_LEVEL) || __DARWIN_C_LEVEL < 199309L
20
typedef int clockid_t;
21
#endif
22
23 b1c60d34 Yulius Tjahjadi
/* 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