summaryrefslogtreecommitdiff
path: root/pktmr.h
blob: b0bcdee8ff064d2d82b893cece0e3cf6799dc380 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#ifndef PK_PKTMR_H
#define PK_PKTMR_H

#include <time.h>

/* 2024-12-17 JCB
 * I have read that in more recent Linux kernels, _MONOTONIC and _REALTIME
 *  do not require syscalls, while all of the other calls can.
 *  In testing on my personal machine, this seems to hold true. Using
 *  CLOCK_PROCESS_CPUTIME_ID consistently elapsed thousands of nanoseconds,
 *  even with no work between sequential _start() and _stop() calls.
 *  Meanwhile, the same test with _MONOTONIC elapsed only tens of nanoseconds.
 */

/* struct pk_tmr */
struct pk_tmr {
	struct timespec b; // begin
	struct timespec e; // end
};

#ifndef PK_TMR_CLOCK
	#define PK_TMR_CLOCK CLOCK_MONOTONIC
#endif

#define pk_tmr_start(tmr) { clock_gettime(PK_TMR_CLOCK, &tmr.b); }
#define pk_tmr_stop(tmr) { clock_gettime(PK_TMR_CLOCK, &tmr.e); }
#define pk_tmr_duration_u64_nano(tmr)  ((((unsigned long long int)tmr.e.tv_sec * 1000000000llu) + tmr.e.tv_nsec) - (((unsigned long long int)tmr.b.tv_sec * 1000000000llu) + (unsigned long long int)tmr.b.tv_nsec))
#define pk_tmr_duration_dbl_nano(tmr)  ((1e+9 * tmr.e.tv_sec + tmr.e.tv_nsec) - (1e+9 * tmr.b.tv_sec + tmr.b.tv_nsec))
#define pk_tmr_duration_dbl_micro(tmr) ((1e+6 * tmr.e.tv_sec + 1e-3 * tmr.e.tv_nsec) - (1e+6 * tmr.b.tv_sec + 1e-3 * tmr.b.tv_nsec))
#define pk_tmr_duration_dbl_mili(tmr)  ((1e+3 * tmr.e.tv_sec + 1e-6 * tmr.e.tv_nsec) - (1e+3 * tmr.b.tv_sec + 1e-6 * tmr.b.tv_nsec))
#define pk_tmr_duration_dbl_scnd(tmr)  ((tmr.e.tv_sec + 1e-9 * tmr.e.tv_nsec) - (tmr.b.tv_sec + 1e-9 * tmr.b.tv_nsec))

#endif /* PK_PKTMR_H */