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