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