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