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 : * Get a field from a structure with size tracking. The fourth parameter is
72 : * optional and can be used to specify the size of the object. If unset,
73 : * (obj)->size will be used by default.
74 : */
75 : #define SPDK_GET_FIELD(obj, field, defval, ...) \
76 : _SPDK_GET_FIELD(obj, field, defval, ## __VA_ARGS__, (obj)->size)
77 :
78 : #define _SPDK_GET_FIELD(obj, field, defval, size, ...) \
79 : ((size) >= (offsetof(__typeof__(*(obj)), field) + sizeof((obj)->field)) ? \
80 : (obj)->field : (defval))
81 :
82 : uint32_t spdk_u32log2(uint32_t x);
83 :
84 : static inline uint32_t
85 212774 : spdk_align32pow2(uint32_t x)
86 : {
87 212774 : return 1u << (1 + spdk_u32log2(x - 1));
88 : }
89 :
90 : uint64_t spdk_u64log2(uint64_t x);
91 :
92 : static inline uint64_t
93 52692 : spdk_align64pow2(uint64_t x)
94 : {
95 52692 : return 1ULL << (1 + spdk_u64log2(x - 1));
96 : }
97 :
98 : /**
99 : * Check if a uint32_t is a power of 2.
100 : */
101 : static inline bool
102 1863 : spdk_u32_is_pow2(uint32_t x)
103 : {
104 1863 : if (x == 0) {
105 0 : return false;
106 : }
107 :
108 1863 : return (x & (x - 1)) == 0;
109 : }
110 :
111 : /**
112 : * Check if a uint64_t is a power of 2.
113 : */
114 : static inline bool
115 3 : spdk_u64_is_pow2(uint64_t x)
116 : {
117 3 : if (x == 0) {
118 0 : return false;
119 : }
120 :
121 3 : return (x & (x - 1)) == 0;
122 : }
123 :
124 : static inline uint64_t
125 8223 : spdk_divide_round_up(uint64_t num, uint64_t divisor)
126 : {
127 8223 : return (num + divisor - 1) / divisor;
128 : }
129 :
130 : struct spdk_single_ioviter {
131 : struct iovec *iov;
132 : size_t iovcnt;
133 : size_t idx;
134 : size_t iov_len;
135 : uint8_t *iov_base;
136 : };
137 :
138 : /**
139 : * An N-way iovec iterator. Calculate the size, given N, using
140 : * SPDK_IOVITER_SIZE. For backward compatibility, the structure
141 : * has a default size of 2 iovecs.
142 : */
143 : struct spdk_ioviter {
144 : uint32_t count;
145 :
146 : union {
147 : struct spdk_single_ioviter iters_compat[2];
148 : struct spdk_single_ioviter iters[0];
149 : };
150 : };
151 :
152 : /* count must be greater than or equal to 2 */
153 : #define SPDK_IOVITER_SIZE(count) (sizeof(struct spdk_single_ioviter) * (count - 2) + sizeof(struct spdk_ioviter))
154 :
155 : /**
156 : * Initialize and move to the first common segment of the two given
157 : * iovecs. See spdk_ioviter_next().
158 : */
159 : size_t spdk_ioviter_first(struct spdk_ioviter *iter,
160 : struct iovec *siov, size_t siovcnt,
161 : struct iovec *diov, size_t diovcnt,
162 : void **src, void **dst);
163 :
164 : /**
165 : * Initialize and move to the first common segment of the N given
166 : * iovecs. See spdk_ioviter_nextv().
167 : */
168 : size_t spdk_ioviter_firstv(struct spdk_ioviter *iter,
169 : uint32_t count,
170 : struct iovec **iov,
171 : size_t *iovcnt,
172 : void **out);
173 :
174 : /**
175 : * Move to the next segment in the iterator.
176 : *
177 : * This will iterate through the segments of the source and destination
178 : * and return the individual segments, one by one. For example, if the
179 : * source consists of one element of length 4k and the destination
180 : * consists of 4 elements each of length 1k, this function will return
181 : * 4 1k src+dst pairs of buffers, and then return 0 bytes to indicate
182 : * the iteration is complete on the fifth call.
183 : */
184 : size_t spdk_ioviter_next(struct spdk_ioviter *iter, void **src, void **dst);
185 :
186 : /**
187 : * Move to the next segment in the iterator.
188 : *
189 : * This will iterate through the segments of the iovecs in the iterator
190 : * and return the individual segments, one by one. For example, if the
191 : * set consists one iovec of one element of length 4k and another iovec
192 : * of 4 elements each of length 1k, this function will return
193 : * 4 1k pairs of buffers, and then return 0 bytes to indicate
194 : * the iteration is complete on the fifth call.
195 : */
196 : size_t spdk_ioviter_nextv(struct spdk_ioviter *iter, void **out);
197 :
198 : /**
199 : * Operate like memset across an iovec.
200 : */
201 : void
202 : spdk_iov_memset(struct iovec *iovs, int iovcnt, int c);
203 :
204 : /**
205 : * Initialize an iovec with just the single given buffer.
206 : */
207 : #define SPDK_IOV_ONE(piov, piovcnt, buf, buflen) do { \
208 : (piov)->iov_base = (buf); \
209 : (piov)->iov_len = (buflen); \
210 : *(piovcnt) = 1; \
211 : } while (0)
212 :
213 : /**
214 : * Copy the data described by the source iovec to the destination iovec.
215 : *
216 : * \return The number of bytes copied.
217 : */
218 : size_t spdk_iovcpy(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt);
219 :
220 : /**
221 : * Same as spdk_iovcpy(), but the src/dst buffers might overlap.
222 : *
223 : * \return The number of bytes copied.
224 : */
225 : size_t spdk_iovmove(struct iovec *siov, size_t siovcnt, struct iovec *diov, size_t diovcnt);
226 :
227 : /**
228 : * Transfer state for iterative copying in or out of an iovec.
229 : */
230 : struct spdk_iov_xfer {
231 : struct iovec *iovs;
232 : int iovcnt;
233 : int cur_iov_idx;
234 : size_t cur_iov_offset;
235 : };
236 :
237 : /**
238 : * Initialize a transfer context to point to the given iovec.
239 : */
240 : void
241 : spdk_iov_xfer_init(struct spdk_iov_xfer *ix, struct iovec *iovs, int iovcnt);
242 :
243 : /**
244 : * Copy from the given buf up to buf_len bytes, into the given ix iovec
245 : * iterator, advancing the iterator as needed.. Returns the number of bytes
246 : * copied.
247 : */
248 : size_t
249 : spdk_iov_xfer_from_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len);
250 :
251 : /**
252 : * Copy from the given ix iovec iterator into the given buf up to buf_len
253 : * bytes, advancing the iterator as needed. Returns the number of bytes copied.
254 : */
255 : size_t
256 : spdk_iov_xfer_to_buf(struct spdk_iov_xfer *ix, const void *buf, size_t buf_len);
257 :
258 : /**
259 : * Copy iovs contents to buf through memcpy.
260 : */
261 : void spdk_copy_iovs_to_buf(void *buf, size_t buf_len, struct iovec *iovs,
262 : int iovcnt);
263 :
264 : /**
265 : * Copy buf contents to iovs through memcpy.
266 : */
267 : void spdk_copy_buf_to_iovs(struct iovec *iovs, int iovcnt, void *buf,
268 : size_t buf_len);
269 :
270 : /**
271 : * Scan build is really pessimistic and assumes that mempool functions can
272 : * dequeue NULL buffers even if they return success. This is obviously a false
273 : * positive, but the mempool dequeue can be done in a DPDK inline function that
274 : * we can't decorate with usual assert(buf != NULL). Instead, we'll
275 : * preinitialize the dequeued buffer array with some dummy objects.
276 : */
277 : #define SPDK_CLANG_ANALYZER_PREINIT_PTR_ARRAY(arr, arr_size, buf_size) \
278 : do { \
279 : static char dummy_buf[buf_size]; \
280 : int i; \
281 : for (i = 0; i < arr_size; i++) { \
282 : arr[i] = (void *)dummy_buf; \
283 : } \
284 : } while (0)
285 :
286 : /**
287 : * Add two sequence numbers s1 and s2
288 : *
289 : * \param s1 First sequence number
290 : * \param s2 Second sequence number
291 : *
292 : * \return Sum of s1 and s2 based on serial number arithmetic.
293 : */
294 : static inline uint32_t
295 5 : spdk_sn32_add(uint32_t s1, uint32_t s2)
296 : {
297 5 : return (uint32_t)(s1 + s2);
298 : }
299 :
300 : #define SPDK_SN32_CMPMAX (1U << (32 - 1))
301 :
302 : /**
303 : * Compare if sequence number s1 is less than s2.
304 : *
305 : * \param s1 First sequence number
306 : * \param s2 Second sequence number
307 : *
308 : * \return true if s1 is less than s2, or false otherwise.
309 : */
310 : static inline bool
311 31 : spdk_sn32_lt(uint32_t s1, uint32_t s2)
312 : {
313 55 : return (s1 != s2) &&
314 24 : ((s1 < s2 && s2 - s1 < SPDK_SN32_CMPMAX) ||
315 9 : (s1 > s2 && s1 - s2 > SPDK_SN32_CMPMAX));
316 : }
317 :
318 : /**
319 : * Compare if sequence number s1 is greater than s2.
320 : *
321 : * \param s1 First sequence number
322 : * \param s2 Second sequence number
323 : *
324 : * \return true if s1 is greater than s2, or false otherwise.
325 : */
326 : static inline bool
327 26 : spdk_sn32_gt(uint32_t s1, uint32_t s2)
328 : {
329 33 : return (s1 != s2) &&
330 7 : ((s1 < s2 && s2 - s1 > SPDK_SN32_CMPMAX) ||
331 3 : (s1 > s2 && s1 - s2 < SPDK_SN32_CMPMAX));
332 : }
333 :
334 : /**
335 : * Copies the value (unsigned char)ch into each of the first \b count characters of the object pointed to by \b data
336 : * \b data_size is used to check that filling \b count bytes won't lead to buffer overflow
337 : *
338 : * \param data Buffer to fill
339 : * \param data_size Size of the buffer
340 : * \param ch Fill byte
341 : * \param count Number of bytes to fill
342 : */
343 : static inline void
344 10 : spdk_memset_s(void *data, size_t data_size, int ch, size_t count)
345 : {
346 : #ifdef __STDC_LIB_EXT1__
347 : /* memset_s was introduced as an optional feature in C11 */
348 : memset_s(data, data_size, ch, count);
349 : #else
350 : size_t i;
351 10 : volatile unsigned char *buf = (volatile unsigned char *)data;
352 :
353 10 : if (!buf) {
354 0 : return;
355 : }
356 10 : if (count > data_size) {
357 0 : count = data_size;
358 : }
359 :
360 733 : for (i = 0; i < count; i++) {
361 723 : buf[i] = (unsigned char)ch;
362 : }
363 : #endif
364 : }
365 :
366 : #ifdef __cplusplus
367 : }
368 : #endif
369 :
370 : #endif
|