1 /* coded by Ketmar // Vampire Avalon (psyc://ketmar.no-ip.org/~Ketmar)
2 * Understanding is not required. Only obedience.
4 * This program is free software. It comes without any warranty, to
5 * the extent permitted by applicable law. You can redistribute it
6 * and/or modify it under the terms of the Do What The Fuck You Want
7 * To Public License, Version 2, as published by Sam Hocevar. See
8 * http://www.wtfpl.net/txt/copying/ for more details.
18 k8clock_type k8clock_initialized
= K8CLOCK_ERROR
;
22 #ifndef CLOCK_MONOTONIC_RAW
23 # define K8CLOCK_CLOCK_TYPE CLOCK_MONOTONIC_RAW
25 # define K8CLOCK_CLOCK_TYPE CLOCK_MONOTONIC
29 static k8clock_type
k8clock_check_source (void) {
30 FILE *fl
= fopen("/sys/devices/system/clocksource/clocksource0/current_clocksource", "r");
33 fprintf(stderr
, "WARNING: can't determine clock source!\n");
36 memset(buf
, 0, sizeof(buf
));
37 if (fgets(buf
, sizeof(buf
)-1, fl
) == NULL
) {
39 fprintf(stderr
, "WARNING: can't determine clock source!\n");
43 while (buf
[0] && isspace(buf
[strlen(buf
)-1])) buf
[strlen(buf
)-1] = 0;
44 //fprintf(stderr, "clock source: %s\n", buf);
45 return (strcasecmp(buf
, "hpet") == 0 ? K8CLOCK_HPET
: K8CLOCK_OTHER
);
49 __attribute__((constructor
)) static void k8clock_ctor (void) {
50 if (k8clock_initialized
== K8CLOCK_ERROR
) {
52 k8clock_initialized
= k8clock_check_source();
53 if (clock_getres(K8CLOCK_CLOCK_TYPE
, &cres
) != 0) {
54 fprintf(stderr
, "ERROR: can't get clock resolution!\n");
55 k8clock_initialized
= K8CLOCK_ERROR
;
58 //fprintf(stderr, "CLOCK_MONOTONIC: %ld:%ld\n", cres.tv_sec, cres.tv_nsec);
59 if (cres
.tv_sec
> 0 || cres
.tv_nsec
> (long)1000000*10 /*10 ms*/) {
60 fprintf(stderr
, "ERROR: real-time clock resolution is too low!\n");
61 k8clock_initialized
= K8CLOCK_ERROR
;
69 void k8clock_init (k8clock_t
*clk
) {
70 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
71 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &clk
->stt
) != 0) {
72 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
78 uint64_t k8clock_ms (k8clock_t
*clk
) {
79 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
81 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &ts
) != 0) {
82 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
85 // ah, ignore nanoseconds in clk->stt here: we need only 'differential' time, and it can start with something weird
86 return ((int64_t)(ts
.tv_sec
-clk
->stt
.tv_sec
))*1000+(ts
.tv_nsec
-clk
->stt
.tv_nsec
)/1000000+1;
92 uint64_t k8clock_micro (k8clock_t
*clk
) {
93 if (clk
!= NULL
&& k8clock_initialized
!= K8CLOCK_ERROR
) {
95 if (clock_gettime(K8CLOCK_CLOCK_TYPE
, &ts
) != 0) {
96 fprintf(stderr
, "ERROR: can't get real-time clock value!\n");
99 // ah, ignore nanoseconds in clk->stt here: we need only 'differential' time, and it can start with something weird
100 return ((int64_t)(ts
.tv_sec
-clk
->stt
.tv_sec
))*1000000+(ts
.tv_nsec
-clk
->stt
.tv_nsec
)/1000+1;
106 uint64_t k8clock (void) {
107 return k8clock_ms(&clk
);
111 uint64_t k8clockmicro (void) {
112 return k8clock_micro(&clk
);