9 k8clock_type k8clock_initialized
= K8CLOCK_ERROR
;
13 #ifndef CLOCK_MONOTONIC_RAW
14 # define K8CLOCK_CLOCK_TYPE CLOCK_MONOTONIC_RAW
16 # define K8CLOCK_CLOCK_TYPE CLOCK_MONOTONIC
20 static k8clock_type
k8clock_check_source (void) {
21 FILE *fl
= fopen("/sys/devices/system/clocksource/clocksource0/current_clocksource", "r");
24 fprintf(stderr
, "WARNING: can't determine clock source!\n");
27 memset(buf
, 0, sizeof(buf
));
28 if (fgets(buf
, sizeof(buf
)-1, fl
) == NULL
) {
30 fprintf(stderr
, "WARNING: can't determine clock source!\n");
34 while (buf
[0] && isspace(buf
[strlen(buf
)-1])) buf
[strlen(buf
)-1] = 0;
35 //fprintf(stderr, "clock source: %s\n", buf);
36 return (strcasecmp(buf
, "hpet") == 0 ? K8CLOCK_HPET
: K8CLOCK_OTHER
);
40 __attribute__((constructor
)) static void k8clock_ctor (void) {
41 if (k8clock_initialized
== K8CLOCK_ERROR
) {
43 k8clock_initialized
= k8clock_check_source();
44 if (clock_getres(K8CLOCK_CLOCK_TYPE
, &cres
) != 0) {
45 fprintf(stderr
, "ERROR: can't get clock resolution!\n");
46 k8clock_initialized
= K8CLOCK_ERROR
;
49 //fprintf(stderr, "CLOCK_MONOTONIC: %ld:%ld\n", cres.tv_sec, cres.tv_nsec);
50 if (cres
.tv_sec
> 0 || cres
.tv_nsec
> (long)1000000*10 /*10 ms*/) {
51 fprintf(stderr
, "ERROR: real-time clock resolution is too low!\n");
52 k8clock_initialized
= K8CLOCK_ERROR
;
60 void k8clock_init (k8clock_t
*clk
) {
61 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
62 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &clk
->stt
) != 0) {
63 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
69 uint64_t k8clock_ms (k8clock_t
*clk
) {
70 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
72 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &ts
) != 0) {
73 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
76 // ah, ignore nanoseconds in clk->stt here: we need only 'differential' time, and it can start with something weird
77 return ((int64_t)(ts
.tv_sec
-clk
->stt
.tv_sec
))*1000+(ts
.tv_nsec
-clk
->stt
.tv_nsec
)/1000000+1;
83 uint64_t k8clock_micro (k8clock_t
*clk
) {
84 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
86 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &ts
) != 0) {
87 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
90 // ah, ignore nanoseconds in clk->stt here: we need only 'differential' time, and it can start with something weird
91 return ((int64_t)(ts
.tv_sec
-clk
->stt
.tv_sec
))*1000000+(ts
.tv_nsec
-clk
->stt
.tv_nsec
)/1000+1;
97 uint64_t k8clock (void) {
98 return k8clock_ms(&clk
);
102 uint64_t k8clockmicro (void) {
103 return k8clock_micro(&clk
);