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