#ifndef PK_PKTMR_H #define PK_PKTMR_H #include /* 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 */