1#pragma once
2
3#include <atomic>
4#include <cassert>
5#include <cerrno>
6#include <cstdarg>
7#include <cstddef>
8#include <cstdint>
9#include <cstdio>
10#include <cstdlib>
11#include <ctime>
12
13#define unlikely(x) __builtin_expect(!!(x), 0)
14#define likely(x) __builtin_expect(!!(x), 1)
15
16#ifndef UNUSED
17# define UNUSED(x) (void) (x)
18#endif
19
20/** Checks is a value is a power of two. Does not handle zero. */
21#define IS_POT(v) (((v) & ((v) - 1)) == 0)
22
23/** Checks is a value is a power of two. Zero handled. */
24#define IS_POT_NONZERO(v) ((v) != 0 && IS_POT(v))
25
26/** Align a value to a power of two */
27#define ALIGN_POT(x, pot_align) (((x) + (pot_align) - 1) & ~((pot_align) - 1))
28
29#define p_atomic_read(_v) __atomic_load_n((_v), __ATOMIC_ACQUIRE)
30
31static inline bool util_is_power_of_two_nonzero64(uint64_t v) {
32 return IS_POT_NONZERO(v);
33}
34
35static inline uint64_t align64(uint64_t value, uint64_t alignment) {
36 assert(util_is_power_of_two_nonzero64(alignment));
37 return ALIGN_POT(value, alignment);
38}
39
40struct list_head {
41 list_head * prev;
42 list_head * next;
43};
44
45struct util_sparse_array {
46 size_t elem_size;
47 unsigned node_size_log2;
48
49 uintptr_t root;
50};
51
52void * util_sparse_array_get(util_sparse_array * arr, uint64_t idx);
53void util_sparse_array_init(util_sparse_array * arr, size_t elem_size, size_t node_size);
54
55inline void os_time_sleep(int64_t usecs) {
56 timespec time;
57 time.tv_sec = usecs / 1000000;
58 time.tv_nsec = (usecs % 1000000) * 1000;
59 while (clock_nanosleep(CLOCK_MONOTONIC, 0, &time, &time) == EINTR)
60 ;
61}
62
63struct timer_data {
64 long long start;
65 long long total;
66 long long count;
67};
68
69static inline void start_timer(timer_data * timer) {
70 timespec ts;
71 clock_gettime(CLOCK_MONOTONIC, &ts);
72 timer->start = (long long) ts.tv_sec * 1000000000LL + ts.tv_nsec;
73}
74
75// returns the duration in ns
76static inline long long stop_timer(timer_data * timer) {
77 timespec ts;
78 clock_gettime(CLOCK_MONOTONIC, &ts);
79 long long timer_end = (long long) ts.tv_sec * 1000000000LL + ts.tv_nsec;
80
81 long long duration = (timer_end - timer->start);
82 timer->total += duration;
83 timer->count += 1;
84
85 return duration;
86}