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 3702704 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
87 : {
88 : #if HAVE_SSE42
89 3702704 : if (tommy_likely(crc_x86)) {
90 3702704 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
91 3702704 : 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 337 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
101 : {
102 20972024 : while (size >= 4) {
103 20971687 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
104 20971687 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
105 20971687 : ptr += 4;
106 20971687 : size -= 4;
107 : }
108 :
109 346 : while (size) {
110 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
111 9 : ++ptr;
112 9 : --size;
113 : }
114 :
115 337 : return crc;
116 : }
117 :
118 : /**
119 : * Compute the CRC-32 (Castagnoli) without the IV.
120 : */
121 : #if HAVE_SSE42
122 20756682 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
123 : {
124 : #ifdef CONFIG_X86_64
125 20756682 : uint64_t crc64 = crc;
126 207764879 : while (size >= 8) {
127 187008197 : asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
128 187008197 : ptr += 8;
129 187008197 : size -= 8;
130 : }
131 20756682 : 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 64965005 : while (size) {
140 44208323 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
141 44208323 : ++ptr;
142 44208323 : --size;
143 : }
144 :
145 20756682 : return crc;
146 : }
147 : #endif
148 :
149 : /**
150 : * Compute CRC-32 (Castagnoli) without the IV.
151 : */
152 20110700 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
153 : {
154 : #if HAVE_SSE42
155 20110700 : if (tommy_likely(crc_x86)) {
156 20110700 : 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 :
194 : /**
195 : * Compute the HASH of a memory block.
196 : * Seed is a 128 bit vector.
197 : */
198 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size);
199 :
200 : /**
201 : * Return the hash name.
202 : */
203 : const char* hash_config_name(unsigned kind);
204 :
205 : /**
206 : * Count the number of different bits in the two buffers.
207 : */
208 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size);
209 :
210 : /****************************************************************************/
211 : /* lock */
212 :
213 : /**
214 : * Create and locks the lock file.
215 : * Return -1 on error, otherwise it's the file handle to pass to lock_unlock().
216 : */
217 : int lock_lock(const char* file);
218 :
219 : /**
220 : * Unlock the lock file.
221 : * Return -1 on error.
222 : */
223 : int lock_unlock(int f);
224 :
225 : /****************************************************************************/
226 : /* bitvect */
227 :
228 : typedef unsigned char bit_vect_t;
229 : #define BIT_VECT_SIZE (sizeof(bit_vect_t) * 8)
230 :
231 212 : static inline size_t bit_vect_size(size_t max)
232 : {
233 212 : return (max + BIT_VECT_SIZE - 1) / BIT_VECT_SIZE;
234 : }
235 :
236 1051115 : static inline void bit_vect_set(bit_vect_t* bit_vect, size_t off)
237 : {
238 1051115 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
239 1051115 : bit_vect[off / BIT_VECT_SIZE] |= mask;
240 1051115 : }
241 :
242 : static inline void bit_vect_clear(bit_vect_t* bit_vect, size_t off)
243 : {
244 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
245 : bit_vect[off / BIT_VECT_SIZE] &= ~mask;
246 : }
247 :
248 1401649 : static inline int bit_vect_test(bit_vect_t* bit_vect, size_t off)
249 : {
250 1401649 : bit_vect_t mask = 1 << (off % BIT_VECT_SIZE);
251 1401649 : return (bit_vect[off / BIT_VECT_SIZE] & mask) != 0;
252 : }
253 :
254 : /****************************************************************************/
255 : /* muldiv */
256 :
257 : unsigned muldiv(uint64_t v, uint64_t mul, uint64_t div);
258 : unsigned muldiv_upper(uint64_t v, uint64_t mul, uint64_t div);
259 :
260 : #endif
261 :
|