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 : /* memory */
23 :
24 : /**
25 : * Safe aligned malloc.
26 : * If no memory is available, it aborts.
27 : */
28 : void* malloc_nofail_align(size_t size, void** freeptr);
29 :
30 : /**
31 : * Safe aligned malloc. Usable for direct io.
32 : */
33 : void* malloc_nofail_direct(size_t size, void** freeptr);
34 :
35 : /**
36 : * Safe aligned vector allocation.
37 : * If no memory is available, it aborts.
38 : */
39 : void** malloc_nofail_vector_align(int nd, int n, size_t size, void** freeptr);
40 :
41 : /**
42 : * Safe page vector allocation. Usable for direct io.
43 : * If no memory is available, it aborts.
44 : */
45 : void** malloc_nofail_vector_direct(int nd, int n, size_t size, void** freeptr);
46 :
47 : /**
48 : * Safe allocation with memory test.
49 : */
50 : void* malloc_nofail_test(size_t size);
51 :
52 : /**
53 : * Test the memory vector for RAM problems.
54 : * If a problem is found, it crashes.
55 : */
56 : void mtest_vector(int n, size_t size, void** vv);
57 :
58 : /****************************************************************************/
59 : /* crc */
60 :
61 : /**
62 : * CRC initial value.
63 : * Using a not zero value allows to detect a leading run of zeros.
64 : */
65 : #define CRC_IV 0xffffffffU
66 :
67 : /**
68 : * CRC-32 (Castagnoli) table.
69 : */
70 : extern uint32_t CRC32C_0[256];
71 : extern uint32_t CRC32C_1[256];
72 : extern uint32_t CRC32C_2[256];
73 : extern uint32_t CRC32C_3[256];
74 :
75 : /**
76 : * If the CPU support the CRC instructions.
77 : */
78 : #if HAVE_SSE42
79 : extern int crc_x86;
80 : #endif
81 :
82 : /**
83 : * Compute CRC-32 (Castagnoli) for a single byte without the IV.
84 : */
85 3809331 : static inline uint32_t crc32c_plain_char(uint32_t crc, unsigned char c)
86 : {
87 : #if HAVE_SSE42
88 3809331 : if (tommy_likely(crc_x86)) {
89 3809331 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (c));
90 3809331 : return crc;
91 : }
92 : #endif
93 0 : return CRC32C_0[(crc ^ c) & 0xff] ^ (crc >> 8);
94 : }
95 :
96 : /**
97 : * Compute the CRC-32 (Castagnoli) without the IV.
98 : */
99 369 : static inline uint32_t crc32c_gen_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
100 : {
101 23069577 : while (size >= 4) {
102 23068839 : crc ^= ptr[0] | (uint32_t)ptr[1] << 8 | (uint32_t)ptr[2] << 16 | (uint32_t)ptr[3] << 24;
103 23068839 : crc = CRC32C_3[crc & 0xff] ^ CRC32C_2[(crc >> 8) & 0xff] ^ CRC32C_1[(crc >> 16) & 0xff] ^ CRC32C_0[crc >> 24];
104 23068839 : ptr += 4;
105 23068839 : size -= 4;
106 : }
107 :
108 747 : while (size) {
109 9 : crc = CRC32C_0[(crc ^ *ptr) & 0xff] ^ (crc >> 8);
110 9 : ++ptr;
111 9 : --size;
112 : }
113 :
114 369 : return crc;
115 : }
116 :
117 : /**
118 : * Compute the CRC-32 (Castagnoli) without the IV.
119 : */
120 : #if HAVE_SSE42
121 21366077 : static inline uint32_t crc32c_x86_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
122 : {
123 : #ifdef CONFIG_X86_64
124 21366077 : uint64_t crc64 = crc;
125 225773646 : while (size >= 8) {
126 183041492 : asm ("crc32q %1, %0\n" : "+r" (crc64) : "m" (*(const uint64_t*)ptr));
127 183041492 : ptr += 8;
128 183041492 : size -= 8;
129 : }
130 21366077 : crc = crc64;
131 : #else
132 : while (size >= 4) {
133 : asm ("crc32l %1, %0\n" : "+r" (crc) : "m" (*(const uint32_t*)ptr));
134 : ptr += 4;
135 : size -= 4;
136 : }
137 : #endif
138 88679490 : while (size) {
139 45947336 : asm ("crc32b %1, %0\n" : "+r" (crc) : "m" (*ptr));
140 45947336 : ++ptr;
141 45947336 : --size;
142 : }
143 :
144 21366077 : return crc;
145 : }
146 : #endif
147 :
148 : /**
149 : * Compute CRC-32 (Castagnoli) without the IV.
150 : */
151 20718864 : static inline uint32_t crc32c_plain(uint32_t crc, const unsigned char* ptr, unsigned size)
152 : {
153 : #if HAVE_SSE42
154 20718864 : if (tommy_likely(crc_x86)) {
155 20718864 : return crc32c_x86_plain(crc, ptr, size);
156 : }
157 : #endif
158 0 : return crc32c_gen_plain(crc, ptr, size);
159 : }
160 :
161 : /**
162 : * Compute the CRC-32 (Castagnoli)
163 : */
164 : uint32_t (*crc32c)(uint32_t crc, const unsigned char* ptr, unsigned size);
165 :
166 : /**
167 : * Internal entry points for testing.
168 : */
169 : uint32_t crc32c_gen(uint32_t crc, const unsigned char* ptr, unsigned size);
170 : uint32_t crc32c_x86(uint32_t crc, const unsigned char* ptr, unsigned size);
171 :
172 : /**
173 : * Initialize the CRC-32 (Castagnoli) support.
174 : */
175 : void crc32c_init(void);
176 :
177 : /****************************************************************************/
178 : /* hash */
179 :
180 : /**
181 : * Size of the hash.
182 : */
183 : #define HASH_MAX 16
184 :
185 : /**
186 : * Hash kinds.
187 : */
188 : #define HASH_UNDEFINED 0
189 : #define HASH_MURMUR3 1
190 : #define HASH_SPOOKY2 2
191 :
192 : /**
193 : * Compute the HASH of a memory block.
194 : * Seed is a 128 bit vector.
195 : */
196 : void memhash(unsigned kind, const unsigned char* seed, void* digest, const void* src, size_t size);
197 :
198 : /**
199 : * Return the hash name.
200 : */
201 : const char* hash_config_name(unsigned kind);
202 :
203 : /**
204 : * Count the number of different bits in the two buffers.
205 : */
206 : unsigned memdiff(const unsigned char* data1, const unsigned char* data2, size_t size);
207 :
208 : /****************************************************************************/
209 : /* lock */
210 :
211 : /**
212 : * Create and locks the lock file.
213 : * Return -1 on error, otherwise it's the file handle to pass to lock_unlock().
214 : */
215 : int lock_lock(const char* file);
216 :
217 : /**
218 : * Unlock the lock file.
219 : * Return -1 on error.
220 : */
221 : int lock_unlock(int f);
222 :
223 : #endif
224 :
|