Line data Source code
1 : /* SPDX-License-Identifier: BSD-3-Clause
2 : * Copyright (C) 2017 Intel Corporation. All rights reserved.
3 : * Copyright (c) 2019 Mellanox Technologies LTD. All rights reserved.
4 : */
5 :
6 : /** \file
7 : * General utility functions
8 : */
9 :
10 : #ifndef SPDK_UTIL_H
11 : #define SPDK_UTIL_H
12 :
13 : /* memset_s is only available if __STDC_WANT_LIB_EXT1__ is set to 1 before including \<string.h\> */
14 : #define __STDC_WANT_LIB_EXT1__ 1
15 :
16 : #include "spdk/stdinc.h"
17 :
18 : #ifdef __cplusplus
19 : extern "C" {
20 : #endif
21 :
22 : #define SPDK_CACHE_LINE_SIZE 64
23 :
24 : #define spdk_min(a,b) (((a)<(b))?(a):(b))
25 : #define spdk_max(a,b) (((a)>(b))?(a):(b))
26 :
27 : #define SPDK_COUNTOF(arr) (sizeof(arr) / sizeof((arr)[0]))
28 :
29 : #define SPDK_CONTAINEROF(ptr, type, member) ((type *)((uintptr_t)ptr - offsetof(type, member)))
30 :
31 : /** Returns size of an object pointer by ptr up to and including member */
32 : #define SPDK_SIZEOF(ptr, member) (offsetof(__typeof__(*(ptr)), member) + sizeof((ptr)->member))
33 :
34 : /**
35 : * Get the size of a member of a struct.
36 : */
37 : #define SPDK_SIZEOF_MEMBER(type, member) (sizeof(((type *)0)->member))
38 :
39 : /**
40 : * Get the number of elements in an array of a struct member
41 : */
42 : #define SPDK_COUNTOF_MEMBER(type, member) (SPDK_COUNTOF(((type *)0)->member))
43 :
44 : #define SPDK_SEC_TO_MSEC 1000ULL
45 : #define SPDK_SEC_TO_USEC 1000000ULL
46 : #define SPDK_SEC_TO_NSEC 1000000000ULL
47 :
48 : /* Ceiling division of unsigned integers */
49 : #define SPDK_CEIL_DIV(x,y) (((x)+(y)-1)/(y))
50 :
51 : /**
52 : * Macro to align a value to a given power-of-two. The resultant value
53 : * will be of the same type as the first parameter, and will be no
54 : * bigger than the first parameter. Second parameter must be a
55 : * power-of-two value.
56 : */
57 : #define SPDK_ALIGN_FLOOR(val, align) \
58 : (__typeof__(val))((val) & (~((__typeof__(val))((align) - 1))))
59 : /**
60 : * Macro to align a value to a given power-of-two. The resultant value
61 : * will be of the same type as the first parameter, and will be no lower
62 : * than the first parameter. Second parameter must be a power-of-two
63 : * value.
64 : */
65 : #define SPDK_ALIGN_CEIL(val, align) \
66 : SPDK_ALIGN_FLOOR(((val) + ((__typeof__(val)) (align) - 1)), align)
67 :
68 : #define SPDK_BIT(n) (1ul << (n))
69 :
70 : /**
71 : * Check if a given field is valid in a structure with size tracking. The third
72 : * parameter is optional and can be used to specify the size of the object. If
73 : * unset, (obj)->size will be used by default.
74 : */
75 : #define SPDK_FIELD_VALID(obj, field, ...) \
76 : _SPDK_FIELD_VALID(obj, field, ## __VA_ARGS__, (obj)->size)
77 :
78 : #define _SPDK_FIELD_VALID(obj, field, size, ...) \
79 : ((size) >= (offsetof(__typeof__(*(obj)), field) + sizeof((obj)->field)))
80 : /**
81 : * Get a field from a structure with size tracking. The fourth parameter is
82 : * optional and can be used to specify the size of the object. If unset,
83 : * (obj)->size will be used by default.
84 : */
85 : #define SPDK_GET_FIELD(obj, field, defval, ...) \
86 : _SPDK_GET_FIELD(obj, field, defval, ## __VA_ARGS__, (obj)->size)
87 :
88 : #define _SPDK_GET_FIELD(obj, field, defval, size, ...) \
89 : (SPDK_FIELD_VALID(obj, field, size) ? (obj)->field : (defval))
90 :
91 : uint32_t spdk_u32log2(uint32_t x);
92 :
93 : static inline uint32_t
94 243761 : spdk_align32pow2(uint32_t x)
95 : {
96 243761 : return 1u << (1 + spdk_u32log2(x - 1));
97 : }
98 :
99 : uint64_t spdk_u64log2(uint64_t x);
100 :
101 : static inline uint64_t
102 78945 : spdk_align64pow2(uint64_t x)
103 : {
104 78945 : return 1ULL << (1 + spdk_u64log2(x - 1));
105 : }
106 :
107 : /**
108 : * Check if a uint32_t is a power of 2.
109 : */
110 : static inline bool
111 3461 : spdk_u32_is_pow2(uint32_t x)
112 : {
113 3461 : if (x == 0) {
114 0 : return false;
115 : }
116 :
117 3461 : return (x & (x - 1)) == 0;
118 : }
119 :
120 : /**
121 : * Check if a uint64_t is a power of 2.
122 : */
123 : static inline bool
124 3 : spdk_u64_is_pow2(uint64_t x)
125 : {
126 3 : if (x == 0) {
127 0 : return false;
128 : }
129 :
130 3 : return (x & (x - 1)) == 0;
131 : }
132 :
133 : static inline uint64_t
134 10946 : spdk_divide_round_up(uint64_t num, uint64_t divisor)
135 : {
136 10946 : return (num + divisor - 1) / divisor;
137 : }
138 :
139 : struct spdk_single_ioviter {
140 : struct iovec *iov;
141 : size_t iovcnt;
142 : size_t idx;
143 : size_t iov_len;
144 : uint8_t *iov_base;
145 : };
146 :
147 : /**
148 : * An N-way iovec iterator. Calculate the size, given N, using
149 : * SPDK_IOVITER_SIZE. For backward compatibility, the structure
150 : * has a default size of 2 iovecs.
151 : */
152 : struct spdk_ioviter {
153 : uint32_t count;
154 :
155 : union {
156 : struct spdk_single_ioviter iters_compat[2];
157 : struct spdk_single_ioviter iters[0];
158 : };
159 : };
160 :
161 : /* count must be greater than or equal to 2 */
162 : #define SPDK_IOVITER_SIZE(count) (sizeof(struct spdk_single_ioviter) * (count - 2) + sizeof(struct spdk_ioviter))
163 :
164 : /**
165 : * Initialize and move to the first common segment of the two given
166 : * iovecs. See spdk_ioviter_next().
167 : */
168 : size_t spdk_ioviter_first(struct spdk_ioviter *iter,
169 : struct iovec *siov, size_t siovcnt,
170 : struct iovec *diov, size_t diovcnt,
171 : void **src, void **dst);
172 :
173 : /**
174 : * Initialize and move to the first common segment of the N given
175 : * iovecs. See spdk_ioviter_nextv().
176 : */
177 : size_t spdk_ioviter_firstv(struct spdk_ioviter *iter,
178 : uint32_t count,
179 : struct iovec **iov,
180 : size_t *iovcnt,
181 : void **out);
182 :
183 : /**
184 : * Move to the next segment in the iterator.
185 : *
186 : * This will iterate through the segments of the source and destination
187 : * and return the individual segments, one by one. For example, if the
188 : * source consists of one element of length 4k and the destination
189 : * consists of 4 elements each of length 1k, this function will return
190 : * 4 1k src+dst pairs of buffers, and then return 0 bytes to indicate
191 : * the iteration is complete on the fifth call.
192 : */
193 : size_t spdk_ioviter_next(struct spdk_ioviter *iter, void **src, void **dst);
194 :
195 : /**
196 : * Move to the next segment in the iterator.
197 : *
198 : * This will iterate through the segments of the iovecs in the iterator
199 : * and return the individual segments, one by one. For example, if the
200 : * set consists one iovec of one element of length 4k and another iovec
201 : * of 4 elements each of length 1k, this function will return
202 : * 4 1k pairs of buffers, and then return 0 bytes to indicate
203 : * the iteration is complete on the fifth call.
204 : */
205 : size_t spdk_ioviter_nextv(struct spdk_ioviter *iter, void **out);
206 :
207 : /**
208 : * Operate like memset across an iovec.
209 : */
210 : void
211 : spdk_iov_memset(struct iovec *iovs, int iovcnt, int c);
212 :
213 : /**
214 : * Initialize an iovec with just the single given buffer.
215 : */
216 : #define SPDK_IOV_ONE(piov, piovcnt, buf, buflen) do { \
217 : (piov)->iov_base = (buf); \
218 : (piov)->iov_len = (buflen); \
219 : *(piovcnt) = 1; \
220 : } while (0)
221 :
222 : /**
223 : * Copy the data described by the source iovec to the destination iovec.
224 : *
225 : * \return The number of bytes copied.
226 : */
227 : size_t spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt);
228 :
229 : /**
230 : * Same as spdk_iovcpy(), but the src/dst buffers might overlap.
231 : *
232 : * \return The number of bytes copied.
233 : */
234 : size_t spdk_iovmove(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt);
235 :
236 : /**
237 : * Transfer state for iterative copying in or out of an iovec.
238 : */
239 : struct spdk_iov_xfer {
240 : struct iovec *iovs;
241 : int iovcnt;
242 : int cur_iov_idx;
243 : size_t cur_iov_offset;
244 : };
245 :
246 : /**
247 : * Initialize a transfer context to point to the given iovec.
248 : */
249 : void
250 : spdk_iov_xfer_init(struct spdk_iov_xfer *ix, struct iovec *iovs, int iovcnt);
251 :
252 : /**
253 : * Copy from the given buf up to buf_len bytes, into the given ix iovec
254 : * iterator, advancing the iterator as needed.. Returns the number of bytes
255 : * copied.
256 : */
257 : size_t
258 : spdk_iov_xfer_from_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len);
259 :
260 : /**
261 : * Copy from the given ix iovec iterator into the given buf up to buf_len
262 : * bytes, advancing the iterator as needed. Returns the number of bytes copied.
263 : */
264 : size_t
265 : spdk_iov_xfer_to_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len);
266 :
267 : /**
268 : * Copy iovs contents to buf through memcpy.
269 : */
270 : void spdk_copy_iovs_to_buf(void *buf, size_t buf_len, struct iovec *iovs,
271 : int iovcnt);
272 :
273 : /**
274 : * Copy buf contents to iovs through memcpy.
275 : */
276 : void spdk_copy_buf_to_iovs(struct iovec *iovs, int iovcnt, void *buf,
277 : size_t buf_len);
278 :
279 : /**
280 : * Scan build is really pessimistic and assumes that mempool functions can
281 : * dequeue NULL buffers even if they return success. This is obviously a false
282 : * positive, but the mempool dequeue can be done in a DPDK inline function that
283 : * we can't decorate with usual assert(buf != NULL). Instead, we'll
284 : * preinitialize the dequeued buffer array with some dummy objects.
285 : */
286 : #define SPDK_CLANG_ANALYZER_PREINIT_PTR_ARRAY(arr, arr_size, buf_size) \
287 : do { \
288 : static char dummy_buf[buf_size]; \
289 : int i; \
290 : for (i = 0; i < arr_size; i++) { \
291 : arr[i] = (void *)dummy_buf; \
292 : } \
293 : } while (0)
294 :
295 : /**
296 : * Add two sequence numbers s1 and s2
297 : *
298 : * \param s1 First sequence number
299 : * \param s2 Second sequence number
300 : *
301 : * \return Sum of s1 and s2 based on serial number arithmetic.
302 : */
303 : static inline uint32_t
304 5 : spdk_sn32_add(uint32_t s1, uint32_t s2)
305 : {
306 5 : return (uint32_t)(s1 + s2);
307 : }
308 :
309 : #define SPDK_SN32_CMPMAX (1U << (32 - 1))
310 :
311 : /**
312 : * Compare if sequence number s1 is less than s2.
313 : *
314 : * \param s1 First sequence number
315 : * \param s2 Second sequence number
316 : *
317 : * \return true if s1 is less than s2, or false otherwise.
318 : */
319 : static inline bool
320 31 : spdk_sn32_lt(uint32_t s1, uint32_t s2)
321 : {
322 55 : return (s1 != s2) &&
323 24 : ((s1 < s2 && s2 - s1 < SPDK_SN32_CMPMAX) ||
324 9 : (s1 > s2 && s1 - s2 > SPDK_SN32_CMPMAX));
325 : }
326 :
327 : /**
328 : * Compare if sequence number s1 is greater than s2.
329 : *
330 : * \param s1 First sequence number
331 : * \param s2 Second sequence number
332 : *
333 : * \return true if s1 is greater than s2, or false otherwise.
334 : */
335 : static inline bool
336 26 : spdk_sn32_gt(uint32_t s1, uint32_t s2)
337 : {
338 33 : return (s1 != s2) &&
339 7 : ((s1 < s2 && s2 - s1 > SPDK_SN32_CMPMAX) ||
340 3 : (s1 > s2 && s1 - s2 < SPDK_SN32_CMPMAX));
341 : }
342 :
343 : /**
344 : * Copies the value (unsigned char)ch into each of the first \b count characters of the object pointed to by \b data
345 : * \b data_size is used to check that filling \b count bytes won't lead to buffer overflow
346 : *
347 : * \param data Buffer to fill
348 : * \param data_size Size of the buffer
349 : * \param ch Fill byte
350 : * \param count Number of bytes to fill
351 : */
352 : static inline void
353 14 : spdk_memset_s(void *data, size_t data_size, int ch, size_t count)
354 : {
355 : #ifdef __STDC_LIB_EXT1__
356 : /* memset_s was introduced as an optional feature in C11 */
357 : memset_s(data, data_size, ch, count);
358 : #else
359 : size_t i;
360 14 : volatile unsigned char *buf = (volatile unsigned char *)data;
361 :
362 14 : if (!buf) {
363 0 : return;
364 : }
365 14 : if (count > data_size) {
366 0 : count = data_size;
367 : }
368 :
369 833 : for (i = 0; i < count; i++) {
370 819 : buf[i] = (unsigned char)ch;
371 : }
372 : #endif
373 : }
374 :
375 : #ifdef __cplusplus
376 : }
377 : #endif
378 :
379 : #endif
|