Line data Source code
1 : // SPDX-License-Identifier: GPL-3.0-or-later
2 : // Copyright (C) 2011 Andrea Mazzoleni
3 :
4 : #ifndef __UTIL_H
5 : #define __UTIL_H
6 :
7 :
8 : /****************************************************************************/
9 : /* memory */
10 :
11 : /**
12 : * Safe aligned malloc.
13 : * If no memory is available, it aborts.
14 : */
15 : void* malloc_nofail_align(size_t size, void** freeptr);
16 :
17 : /**
18 : * Safe aligned malloc. Usable for direct io.
19 : */
20 : void* malloc_nofail_direct(size_t size, void** freeptr);
21 :
22 : /**
23 : * Safe aligned vector allocation.
24 : * If no memory is available, it aborts.
25 : */
26 : void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr);
27 :
28 : /**
29 : * Safe page vector allocation. Usable for direct io.
30 : * If no memory is available, it aborts.
31 : */
32 : void** malloc_nofail_vector_direct(int nd, int n, size_t size, void** freeptr);
33 :
34 : /**
35 : * Safe allocation with memory test.
36 : */
37 : void* malloc_nofail_test(size_t size);
38 :
39 : /**
40 : * Test the memory vector for RAM problems.
41 : * If a problem is found, it crashes.
42 : */
43 : void mtest_vector(int n, size_t size, void** vv);
44 :
45 : /****************************************************************************/
46 : /* crc */
47 :
48 : /**
49 : * CRC initial value.
50 : * Using a not zero value allows to detect a leading run of zeros.
51 : */
52 : #define CRC_IV 0xffffffffU
53 :
54 : /**
55 : * CRC-32 (Castagnoli) table.
56 : */
57 : extern uint32_t CRC32C_0[256];
58 : extern uint32_t CRC32C_1[256];
59 : extern uint32_t CRC32C_2[256];
60 : extern uint32_t CRC32C_3[256];
61 :
62 : /**
63 : * If the CPU support the CRC instructions.
64 : */
65 : #if HAVE_SSE42
66 : extern int crc_x86;
67 : #endif
68 :
69 : /**
70 : * Compute CRC-32 (Castagnoli) for a single byte without the IV.
71 : */
72 4202652 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
73 : {
74 : #if HAVE_SSE42
75 4202652 : if (tommy_likely(crc_x86)) {
76 4202652 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
77 4202652 : return crc;
78 : }
79 : #endif
80 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
81 : }
82 :
83 : /**
84 : * Compute the CRC-32 (Castagnoli) without the IV.
85 : */
86 361 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
87 : {
88 22544912 : while (size >= 4) {
89 22544551 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
90 22544551 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
91 22544551 : ptr += 4;
92 22544551 : size -= 4;
93 : }
94 :
95 370 : while (size) {
96 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
97 9 : ++ptr;
98 9 : --size;
99 : }
100 :
101 361 : return crc;
102 : }
103 :
104 : /**
105 : * Compute the CRC-32 (Castagnoli) without the IV.
106 : */
107 : #if HAVE_SSE42
108 23874767 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
109 : {
110 : #ifdef CONFIG_X86_64
111 23874767 : uint64_t crc64 = crc;
112 238439925 : while (size >= 8) {
113 214565158 : asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
114 214565158 : ptr += 8;
115 214565158 : size -= 8;
116 : }
117 23874767 : crc = crc64;
118 : #else
119 : while (size >= 4) {
120 : asm ("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
121 : ptr += 4;
122 : size -= 4;
123 : }
124 : #endif
125 74776955 : while (size) {
126 50902188 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
127 50902188 : ++ptr;
128 50902188 : --size;
129 : }
130 :
131 23874767 : return crc;
132 : }
133 : #endif
134 :
135 : /**
136 : * Compute CRC-32 (Castagnoli) without the IV.
137 : */
138 23225887 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
139 : {
140 : #if HAVE_SSE42
141 23225887 : if (tommy_likely(crc_x86)) {
142 23225887 : return crc32c_x86_plain(crc, ptr, size);
143 : }
144 : #endif
145 0 : return crc32c_gen_plain(crc, ptr, size);
146 : }
147 :
148 : /**
149 : * Compute the CRC-32 (Castagnoli)
150 : */
151 : extern uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
152 :
153 : /**
154 : * Internal entry points for testing.
155 : */
156 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size);
157 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size);
158 :
159 : /**
160 : * Initialize the CRC-32 (Castagnoli) support.
161 : */
162 : void crc32c_init(void);
163 :
164 : /****************************************************************************/
165 : /* hash */
166 :
167 : /**
168 : * Size of the hash.
169 : */
170 : #define HASH_MAX 16
171 :
172 : /**
173 : * Hash kinds.
174 : */
175 : #define HASH_UNDEFINED 0
176 : #define HASH_MURMUR3 1
177 : #define HASH_SPOOKY2 2
178 : #define HASH_METRO 3
179 : #define HASH_MUSEAIR 4
180 :
181 : /**
182 : * Return the hash that is expected to be the fastest in this architecture
183 : */
184 : unsigned membesthash(void);
185 :
186 : /**
187 : * Return the name of the hash
188 : */
189 : const char* memhashname(unsigned kind);
190 :
191 : /**
192 : * Compute the HASH of a memory block.
193 : * Seed is a 128 bit vector.
194 : */
195 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size);
196 :
197 : /**
198 : * Return the hash name.
199 : */
200 : const char* hash_config_name(unsigned kind);
201 :
202 : /**
203 : * Count the number of different bits in the two buffers.
204 : */
205 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size);
206 :
207 : /**
208 : * Unit test
209 : */
210 : int util_selftest(void);
211 :
212 : /****************************************************************************/
213 : /* lock */
214 :
215 : /**
216 : * Create and locks the lock file.
217 : * Return -1 on error, otherwise it's the file handle to pass to lock_unlock().
218 : */
219 : int lock_lock(const char* file);
220 :
221 : /**
222 : * Unlock the lock file.
223 : * Return -1 on error.
224 : */
225 : int lock_unlock(int f);
226 :
227 : /****************************************************************************/
228 : /* bitvect */
229 :
230 : typedef unsigned char bit_vect_t;
231 : #define BIT_VECT_SIZE (sizeof(bit_vect_t) * 8)
232 :
233 244 : static inline size_t bit_vect_size(size_t max)
234 : {
235 244 : return (max + BIT_VECT_SIZE - 1) / BIT_VECT_SIZE;
236 : }
237 :
238 1111724 : static inline void bit_vect_set(bit_vect_t* bit_vect, size_t off)
239 : {
240 1111724 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
241 1111724 : bit_vect[off / BIT_VECT_SIZE] |= mask;
242 1111724 : }
243 :
244 : static inline void bit_vect_clear(bit_vect_t* bit_vect, size_t off)
245 : {
246 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
247 : bit_vect[off / BIT_VECT_SIZE] &= ~mask;
248 : }
249 :
250 1503708 : static inline int bit_vect_test(bit_vect_t* bit_vect, size_t off)
251 : {
252 1503708 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
253 1503708 : return (bit_vect[off / BIT_VECT_SIZE] & mask) != 0;
254 : }
255 :
256 : /****************************************************************************/
257 : /* muldiv */
258 :
259 : unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div);
260 : unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div);
261 :
262 : #endif
263 :
|