Commit | Line | Data |
---|---|---|
19be9217 MD |
1 | // SPDX-License-Identifier: MIT |
2 | // SPDX-FileCopyrightText: 2024 Mathieu Desnoyers <mathieu.desnoyers@efficios.com> | |
3 | ||
c3fad074 MD |
4 | #ifndef _RSEQ_COMMON_UTILS_H |
5 | #define _RSEQ_COMMON_UTILS_H | |
6 | ||
7 | #include <stdbool.h> | |
8 | #include <stdint.h> | |
19be9217 | 9 | |
57d8b586 OD |
10 | #define RSEQ_ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0])) |
11 | ||
19be9217 MD |
12 | #define __rseq_align_mask(v, mask) (((v) + (mask)) & ~(mask)) |
13 | #define rseq_align(v, align) __rseq_align_mask(v, (__typeof__(v)) (align) - 1) | |
14 | ||
15 | static inline | |
16 | unsigned int rseq_fls_u64(uint64_t x) | |
17 | { | |
18 | unsigned int r = 64; | |
19 | ||
20 | if (!x) | |
21 | return 0; | |
22 | ||
23 | if (!(x & 0xFFFFFFFF00000000ULL)) { | |
24 | x <<= 32; | |
25 | r -= 32; | |
26 | } | |
27 | if (!(x & 0xFFFF000000000000ULL)) { | |
28 | x <<= 16; | |
29 | r -= 16; | |
30 | } | |
31 | if (!(x & 0xFF00000000000000ULL)) { | |
32 | x <<= 8; | |
33 | r -= 8; | |
34 | } | |
35 | if (!(x & 0xF000000000000000ULL)) { | |
36 | x <<= 4; | |
37 | r -= 4; | |
38 | } | |
39 | if (!(x & 0xC000000000000000ULL)) { | |
40 | x <<= 2; | |
41 | r -= 2; | |
42 | } | |
43 | if (!(x & 0x8000000000000000ULL)) { | |
44 | x <<= 1; | |
45 | r -= 1; | |
46 | } | |
47 | return r; | |
48 | } | |
49 | ||
50 | static inline | |
51 | unsigned int rseq_fls_u32(uint32_t x) | |
52 | { | |
53 | unsigned int r = 32; | |
54 | ||
55 | if (!x) | |
56 | return 0; | |
57 | if (!(x & 0xFFFF0000U)) { | |
58 | x <<= 16; | |
59 | r -= 16; | |
60 | } | |
61 | if (!(x & 0xFF000000U)) { | |
62 | x <<= 8; | |
63 | r -= 8; | |
64 | } | |
65 | if (!(x & 0xF0000000U)) { | |
66 | x <<= 4; | |
67 | r -= 4; | |
68 | } | |
69 | if (!(x & 0xC0000000U)) { | |
70 | x <<= 2; | |
71 | r -= 2; | |
72 | } | |
73 | if (!(x & 0x80000000U)) { | |
74 | x <<= 1; | |
75 | r -= 1; | |
76 | } | |
77 | return r; | |
78 | } | |
79 | ||
80 | static inline | |
81 | unsigned int rseq_fls_ulong(unsigned long x) | |
82 | { | |
83 | #if RSEQ_BITS_PER_LONG == 32 | |
84 | return rseq_fls_u32(x); | |
85 | #else | |
86 | return rseq_fls_u64(x); | |
87 | #endif | |
88 | } | |
89 | ||
90 | /* | |
91 | * Return the minimum order for which x <= (1UL << order). | |
92 | * Return -1 if x is 0. | |
93 | */ | |
94 | static inline | |
95 | int rseq_get_count_order_ulong(unsigned long x) | |
96 | { | |
97 | if (!x) | |
98 | return -1; | |
99 | ||
100 | return rseq_fls_ulong(x - 1); | |
101 | } | |
102 | ||
103 | #define RSEQ_DEFAULT_PAGE_SIZE 4096 | |
104 | ||
105 | static inline | |
f2981623 | 106 | unsigned long rseq_get_page_len(void) |
19be9217 MD |
107 | { |
108 | long page_len = sysconf(_SC_PAGE_SIZE); | |
109 | ||
110 | if (page_len < 0) | |
111 | page_len = RSEQ_DEFAULT_PAGE_SIZE; | |
f2981623 | 112 | return (unsigned long) page_len; |
19be9217 MD |
113 | } |
114 | ||
9649c7ee MD |
115 | static inline |
116 | int rseq_hweight_ulong(unsigned long v) | |
117 | { | |
d9b46e1c | 118 | return __builtin_popcountl(v); |
9649c7ee MD |
119 | } |
120 | ||
f2981623 MD |
121 | static inline |
122 | bool is_pow2(uint64_t x) | |
123 | { | |
124 | return !(x & (x - 1)); | |
125 | } | |
126 | ||
127 | /* | |
128 | * Calculate offset needed to align p on alignment towards higher | |
129 | * addresses. Alignment must be a power of 2 | |
130 | */ | |
131 | static inline | |
132 | off_t offset_align(uintptr_t p, size_t alignment) | |
133 | { | |
134 | return (alignment - p) & (alignment - 1); | |
135 | } | |
136 | ||
c3fad074 | 137 | #endif /* _RSEQ_COMMON_UTILS_H */ |