Mempool: default as global
[librseq.git] / src / rseq-utils.h
CommitLineData
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
15static inline
16unsigned 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
50static inline
51unsigned 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
80static inline
81unsigned 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 */
94static inline
95int 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
105static inline
f2981623 106unsigned 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
115static inline
116int rseq_hweight_ulong(unsigned long v)
117{
d9b46e1c 118 return __builtin_popcountl(v);
9649c7ee
MD
119}
120
f2981623
MD
121static inline
122bool 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 */
131static inline
132off_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 */
This page took 0.026893 seconds and 4 git commands to generate.