DPDK
25.11.0
Toggle main menu visibility
Loading...
Searching...
No Matches
rte_common.h
Go to the documentation of this file.
1
/* SPDX-License-Identifier: BSD-3-Clause
2
* Copyright(c) 2010-2019 Intel Corporation
3
*/
4
5
#ifndef _RTE_COMMON_H_
6
#define _RTE_COMMON_H_
7
14
15
#include <assert.h>
16
#include <limits.h>
17
#include <stdbool.h>
18
#include <stdint.h>
19
#include <stdalign.h>
20
21
#include <rte_compat.h>
22
#include <rte_config.h>
23
24
/* OS specific include */
25
#include <rte_os.h>
26
27
#ifdef __cplusplus
28
extern
"C"
{
29
#endif
30
31
#ifndef RTE_TOOLCHAIN_MSVC
32
#ifndef typeof
33
#define typeof __typeof__
34
#endif
35
#endif
36
37
#ifndef __cplusplus
38
#ifndef asm
39
#define asm __asm__
40
#endif
41
#endif
42
43
#ifdef RTE_TOOLCHAIN_MSVC
44
#ifdef __cplusplus
45
#define __extension__
46
#endif
47
#endif
48
49
/*
50
* Macro __rte_constant checks if an expression's value can be determined at
51
* compile time. It takes a single argument, the expression to test, and
52
* returns 1 if the expression is a compile-time constant, and 0 otherwise.
53
* For most compilers it uses built-in function __builtin_constant_p, but for
54
* MSVC it uses a different method because MSVC does not have an equivalent
55
* to __builtin_constant_p.
56
*
57
* The trick used with MSVC relies on the way null pointer constants interact
58
* with the type of a ?: expression:
59
* An integer constant expression with the value 0, or such an expression cast
60
* to type void *, is called a null pointer constant.
61
* If both the second and third operands (of the ?: expression) are pointers or
62
* one is a null pointer constant and the other is a pointer, the result type
63
* is a pointer to a type qualified with all the type qualifiers of the types
64
* referenced by both operands. Furthermore, if both operands are pointers to
65
* compatible types or to differently qualified versions of compatible types,
66
* the result type is a pointer to an appropriately qualified version of the
67
* composite type; if one operand is a null pointer constant, the result has
68
* the type of the other operand; otherwise, one operand is a pointer to void
69
* or a qualified version of void, in which case the result type is a pointer
70
* to an appropriately qualified version of void.
71
*
72
* The _Generic keyword then checks the type of the expression
73
* (void *) ((e) * 0ll). It matches this type against the types listed in the
74
* _Generic construct:
75
* - If the type is int *, the result is 1.
76
* - If the type is void *, the result is 0.
77
*
78
* This explanation with some more details can be found at:
79
* https://stackoverflow.com/questions/49480442/detecting-integer-constant-expressions-in-macros
80
*/
81
#ifdef RTE_TOOLCHAIN_MSVC
82
#define __rte_constant(e) _Generic((1 ? (void *) ((e) * 0ll) : (int *) 0), int * : 1, void * : 0)
83
#else
84
#define __rte_constant(e) __extension__(__builtin_constant_p(e))
85
#endif
86
87
/*
88
* RTE_TOOLCHAIN_GCC is defined if the target is built with GCC,
89
* while a host application (like pmdinfogen) may have another compiler.
90
* RTE_CC_IS_GNU is true if the file is compiled with GCC,
91
* no matter it is a target or host application.
92
*/
93
#define RTE_CC_IS_GNU 0
94
#if defined __clang__
95
#define RTE_CC_CLANG
96
#elif defined __GNUC__
97
#define RTE_CC_GCC
98
#undef RTE_CC_IS_GNU
99
#define RTE_CC_IS_GNU 1
100
#endif
101
#if RTE_CC_IS_GNU
102
#define GCC_VERSION (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + \
103
__GNUC_PATCHLEVEL__)
104
#endif
105
118
#ifdef RTE_TOOLCHAIN_MSVC
119
#define __rte_aligned(a) __declspec(align(a))
120
#else
121
#define __rte_aligned(a) __attribute__((__aligned__(a)))
122
#endif
123
124
#ifdef RTE_ARCH_STRICT_ALIGN
125
typedef
uint64_t unaligned_uint64_t
__rte_aligned
(1);
126
typedef
uint32_t unaligned_uint32_t
__rte_aligned
(1);
127
typedef
uint16_t unaligned_uint16_t
__rte_aligned
(1);
128
#else
129
typedef
uint64_t unaligned_uint64_t;
130
typedef
uint32_t unaligned_uint32_t;
131
typedef
uint16_t unaligned_uint16_t;
132
#endif
133
141
#ifdef RTE_TOOLCHAIN_MSVC
142
#define __rte_packed RTE_DEPRECATED(__rte_packed)
143
#else
144
#define __rte_packed (RTE_DEPRECATED(__rte_packed) __attribute__((__packed__)))
145
#endif
146
154
#ifdef RTE_TOOLCHAIN_MSVC
155
#define __rte_packed_begin __pragma(pack(push, 1))
156
#define __rte_packed_end __pragma(pack(pop))
157
#else
158
#define __rte_packed_begin
159
#define __rte_packed_end __attribute__((__packed__))
160
#endif
161
165
#ifdef RTE_TOOLCHAIN_MSVC
166
#define __rte_may_alias
167
#else
168
#define __rte_may_alias __attribute__((__may_alias__))
169
#endif
170
171
/******* Macro to mark functions and fields scheduled for removal *****/
172
#ifdef RTE_TOOLCHAIN_MSVC
173
#define __rte_deprecated
174
#define __rte_deprecated_msg(msg)
175
#else
176
#define __rte_deprecated __attribute__((__deprecated__))
177
#define __rte_deprecated_msg(msg) __attribute__((__deprecated__(msg)))
178
#endif
179
183
#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
184
#define RTE_PRAGMA(x) _Pragma(#x)
185
#define RTE_PRAGMA_WARNING(w) RTE_PRAGMA(GCC warning #w)
186
#define RTE_DEPRECATED(x) RTE_PRAGMA_WARNING(#x is deprecated)
187
#else
188
#define RTE_DEPRECATED(x)
189
#endif
190
195
#if !defined(RTE_TOOLCHAIN_MSVC)
196
#define __rte_diagnostic_push _Pragma("GCC diagnostic push")
197
#define __rte_diagnostic_pop _Pragma("GCC diagnostic pop")
198
#else
199
#define __rte_diagnostic_push
200
#define __rte_diagnostic_pop
201
#endif
202
207
#if !defined(RTE_TOOLCHAIN_MSVC)
208
#define __rte_diagnostic_ignored_wcast_qual _Pragma("GCC diagnostic ignored \"-Wcast-qual\"")
209
#else
210
#define __rte_diagnostic_ignored_wcast_qual
211
#endif
212
216
#ifdef RTE_TOOLCHAIN_MSVC
217
#define __rte_weak RTE_DEPRECATED(__rte_weak)
218
#else
219
#define __rte_weak RTE_DEPRECATED(__rte_weak) __attribute__((__weak__))
220
#endif
221
225
#ifdef RTE_TOOLCHAIN_MSVC
226
#define __rte_pure
227
#else
228
#define __rte_pure __attribute__((pure))
229
#endif
230
234
#ifdef RTE_TOOLCHAIN_MSVC
235
#define __rte_used
236
#else
237
#define __rte_used __attribute__((used))
238
#endif
239
240
/*********** Macros to eliminate unused variable warnings ********/
241
245
#ifdef RTE_TOOLCHAIN_MSVC
246
#define __rte_unused
247
#else
248
#define __rte_unused __attribute__((__unused__))
249
#endif
250
254
#if !defined(__STDC_VERSION__) || __STDC_VERSION__ < 199901L
255
#define __rte_restrict __restrict
256
#else
257
#define __rte_restrict restrict
258
#endif
259
264
#define RTE_SET_USED(x) (void)(x)
265
273
#ifdef RTE_TOOLCHAIN_MSVC
274
#define __rte_format_printf(format_index, first_arg)
275
#else
276
#if RTE_CC_IS_GNU
277
#define __rte_format_printf(format_index, first_arg) \
278
__attribute__((format(gnu_printf, format_index, first_arg)))
279
#else
280
#define __rte_format_printf(format_index, first_arg) \
281
__attribute__((format(printf, format_index, first_arg)))
282
#endif
283
#endif
284
288
#ifdef RTE_TOOLCHAIN_MSVC
289
#define __rte_section(name) \
290
__pragma(data_seg(name)) __declspec(allocate(name))
291
#else
292
#define __rte_section(name) \
293
__attribute__((section(name)))
294
#endif
295
301
#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
302
#define __rte_alloc_size(...) \
303
__attribute__((alloc_size(__VA_ARGS__)))
304
#else
305
#define __rte_alloc_size(...)
306
#endif
307
314
#if defined(RTE_CC_GCC)
315
#define __rte_alloc_align(argno) \
316
__attribute__((alloc_align(argno)))
317
#else
318
#define __rte_alloc_align(argno)
319
#endif
320
325
#if defined(RTE_CC_GCC) || defined(RTE_CC_CLANG)
326
#define __rte_malloc __attribute__((__malloc__))
327
#else
328
#define __rte_malloc
329
#endif
330
335
#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 110000)
336
#define __rte_dealloc(dealloc, argno) \
337
__attribute__((malloc(dealloc, argno)))
338
#else
339
#define __rte_dealloc(dealloc, argno)
340
#endif
341
342
#define RTE_PRIORITY_LOG 101
343
#define RTE_PRIORITY_BUS 110
344
#define RTE_PRIORITY_CLASS 120
345
#define RTE_PRIORITY_LAST 65535
346
347
#define RTE_PRIO(prio) \
348
RTE_PRIORITY_ ## prio
349
359
#ifndef RTE_INIT_PRIO
/* Allow to override from EAL */
360
#ifndef RTE_TOOLCHAIN_MSVC
361
#define RTE_INIT_PRIO(func, prio) \
362
static void __attribute__((constructor(RTE_PRIO(prio)), used)) func(void)
363
#else
364
/* definition from the Microsoft CRT */
365
typedef
int(__cdecl *_PIFV)(void);
366
367
#define CTOR_SECTION_LOG ".CRT$XIB"
368
#define CTOR_SECTION_BUS ".CRT$XIC"
369
#define CTOR_SECTION_CLASS ".CRT$XID"
370
#define CTOR_SECTION_LAST ".CRT$XIY"
371
372
#define CTOR_PRIORITY_TO_SECTION(priority) CTOR_SECTION_ ## priority
373
374
#define RTE_INIT_PRIO(name, priority) \
375
static void name(void); \
376
static int __cdecl name ## _thunk(void) { name(); return 0; } \
377
__pragma(const_seg(CTOR_PRIORITY_TO_SECTION(priority))) \
378
__declspec(allocate(CTOR_PRIORITY_TO_SECTION(priority))) \
379
_PIFV name ## _pointer = &name ## _thunk; \
380
__pragma(const_seg()) \
381
static void name(void)
382
#endif
383
#endif
384
393
#define RTE_INIT(func) \
394
RTE_INIT_PRIO(func, LAST)
395
405
#ifndef RTE_FINI_PRIO
/* Allow to override from EAL */
406
#ifndef RTE_TOOLCHAIN_MSVC
407
#define RTE_FINI_PRIO(func, prio) \
408
static void __attribute__((destructor(RTE_PRIO(prio)), used)) func(void)
409
#else
410
#define DTOR_SECTION_LOG "mydtor$B"
411
#define DTOR_SECTION_BUS "mydtor$C"
412
#define DTOR_SECTION_CLASS "mydtor$D"
413
#define DTOR_SECTION_LAST "mydtor$Y"
414
415
#define DTOR_PRIORITY_TO_SECTION(priority) DTOR_SECTION_ ## priority
416
417
#define RTE_FINI_PRIO(name, priority) \
418
static void name(void); \
419
__pragma(const_seg(DTOR_PRIORITY_TO_SECTION(priority))) \
420
__declspec(allocate(DTOR_PRIORITY_TO_SECTION(priority))) void *name ## _pointer = &name; \
421
__pragma(const_seg()) \
422
static void name(void)
423
#endif
424
#endif
425
434
#define RTE_FINI(func) \
435
RTE_FINI_PRIO(func, LAST)
436
440
#ifdef RTE_TOOLCHAIN_MSVC
441
#define __rte_noreturn
442
#else
443
#define __rte_noreturn __attribute__((noreturn))
444
#endif
445
449
#if defined(RTE_TOOLCHAIN_GCC) || defined(RTE_TOOLCHAIN_CLANG)
450
#define __rte_unreachable() __extension__(__builtin_unreachable())
451
#else
452
#define __rte_unreachable() __assume(0)
453
#endif
454
478
#ifdef RTE_TOOLCHAIN_MSVC
479
#define __rte_warn_unused_result
480
#else
481
#define __rte_warn_unused_result __attribute__((warn_unused_result))
482
#endif
483
487
#ifdef RTE_TOOLCHAIN_MSVC
488
#define __rte_always_inline __forceinline
489
#else
490
#define __rte_always_inline inline __attribute__((always_inline))
491
#endif
492
496
#ifdef RTE_TOOLCHAIN_MSVC
497
#define __rte_noinline __declspec(noinline)
498
#else
499
#define __rte_noinline __attribute__((noinline))
500
#endif
501
505
#ifdef RTE_TOOLCHAIN_MSVC
506
#define __rte_hot
507
#else
508
#define __rte_hot __attribute__((hot))
509
#endif
510
514
#ifdef RTE_TOOLCHAIN_MSVC
515
#define __rte_cold
516
#else
517
#define __rte_cold __attribute__((cold))
518
#endif
519
526
#if defined(RTE_TOOLCHAIN_GCC) && (GCC_VERSION >= 130000)
527
#define __rte_assume(condition) __attribute__((assume(condition)))
528
#elif defined(RTE_TOOLCHAIN_GCC)
529
#define __rte_assume(condition) do { if (!(condition)) __rte_unreachable(); } while (0)
530
#elif defined(RTE_TOOLCHAIN_CLANG)
531
#define __rte_assume(condition) __extension__(__builtin_assume(condition))
532
#else
533
#define __rte_assume(condition) __assume(condition)
534
#endif
535
539
#ifdef RTE_MALLOC_ASAN
540
#ifdef RTE_CC_CLANG
541
#define __rte_no_asan __attribute__((no_sanitize("address", "hwaddress")))
542
#else
543
#define __rte_no_asan __attribute__((no_sanitize_address))
544
#endif
545
#else
/* ! RTE_MALLOC_ASAN */
546
#define __rte_no_asan
547
#endif
548
549
/*********** Macros for pointer arithmetic ********/
550
554
#define RTE_PTR_ADD(ptr, x) ((void*)((uintptr_t)(ptr) + (x)))
555
559
#define RTE_PTR_SUB(ptr, x) ((void *)((uintptr_t)(ptr) - (x)))
560
566
#define RTE_PTR_DIFF(ptr1, ptr2) ((uintptr_t)(ptr1) - (uintptr_t)(ptr2))
567
568
/*********** Macros for casting pointers ********/
569
574
#define RTE_PTR_UNQUAL(X) ((void *)(uintptr_t)(X))
575
593
#define RTE_CAST_PTR(type, ptr) ((type)(uintptr_t)(ptr))
594
598
#define RTE_CAST_FIELD(var, field, type) \
599
(*(type *)((uintptr_t)(var) + offsetof(typeof(*(var)), field)))
600
601
/*********** Macros/static functions for doing alignment ********/
602
603
610
#define RTE_PTR_ALIGN_FLOOR(ptr, align) \
611
((typeof(ptr))RTE_ALIGN_FLOOR((uintptr_t)(ptr), align))
612
619
#define RTE_ALIGN_FLOOR(val, align) \
620
(typeof(val))((val) & (~((typeof(val))((align) - 1))))
621
628
#define RTE_PTR_ALIGN_CEIL(ptr, align) \
629
RTE_PTR_ALIGN_FLOOR((typeof(ptr))RTE_PTR_ADD(ptr, (align) - 1), align)
630
637
#define RTE_ALIGN_CEIL(val, align) \
638
RTE_ALIGN_FLOOR(((val) + ((typeof(val)) (align) - 1)), align)
639
647
#define RTE_PTR_ALIGN(ptr, align) RTE_PTR_ALIGN_CEIL(ptr, align)
648
656
#define RTE_ALIGN(val, align) RTE_ALIGN_CEIL(val, align)
657
663
#define RTE_ALIGN_MUL_CEIL(v, mul) \
664
((((v) + (typeof(v))(mul) - 1) / ((typeof(v))(mul))) * (typeof(v))(mul))
665
671
#define RTE_ALIGN_MUL_FLOOR(v, mul) \
672
(((v) / ((typeof(v))(mul))) * (typeof(v))(mul))
673
679
#define RTE_ALIGN_MUL_NEAR(v, mul) \
680
__extension__ ({ \
681
typeof(v) ceil = RTE_ALIGN_MUL_CEIL(v, mul); \
682
typeof(v) floor = RTE_ALIGN_MUL_FLOOR(v, mul); \
683
(ceil - (v)) > ((v) - floor) ? floor : ceil; \
684
})
685
697
static
inline
int
698
rte_is_aligned
(
const
void
*
const
__rte_restrict
ptr,
const
unsigned
int
align)
699
{
700
return
((uintptr_t)ptr & (align - 1)) == 0;
701
}
702
703
/*********** Macros for compile type checks ********/
704
705
/* Workaround for toolchain issues with missing C11 macro in FreeBSD */
706
#if !defined(static_assert) && !defined(__cplusplus)
707
#define static_assert _Static_assert
708
#endif
709
716
#define RTE_BUILD_BUG_ON(condition) do { static_assert(!(condition), #condition); } while (0)
717
718
/*********** Cache line related macros ********/
719
721
#define RTE_CACHE_LINE_MASK (RTE_CACHE_LINE_SIZE-1)
722
724
#define RTE_CACHE_LINE_ROUNDUP(size) RTE_ALIGN_CEIL(size, RTE_CACHE_LINE_SIZE)
725
727
#if RTE_CACHE_LINE_SIZE == 64
728
#define RTE_CACHE_LINE_SIZE_LOG2 6
729
#elif RTE_CACHE_LINE_SIZE == 128
730
#define RTE_CACHE_LINE_SIZE_LOG2 7
731
#else
732
#error "Unsupported cache line size"
733
#endif
734
736
#define RTE_CACHE_LINE_MIN_SIZE 64
737
739
#define __rte_cache_aligned __rte_aligned(RTE_CACHE_LINE_SIZE)
740
742
#define __rte_cache_min_aligned __rte_aligned(RTE_CACHE_LINE_MIN_SIZE)
743
744
#define _RTE_CACHE_GUARD_HELPER2(unique) \
745
alignas(RTE_CACHE_LINE_SIZE) \
746
char cache_guard_ ## unique[RTE_CACHE_LINE_SIZE * RTE_CACHE_GUARD_LINES]
747
#define _RTE_CACHE_GUARD_HELPER1(unique) _RTE_CACHE_GUARD_HELPER2(unique)
755
#define RTE_CACHE_GUARD _RTE_CACHE_GUARD_HELPER1(__COUNTER__)
756
757
/*********** PA/IOVA type definitions ********/
758
760
typedef
uint64_t
phys_addr_t
;
761
#define RTE_BAD_PHYS_ADDR ((phys_addr_t)-1)
762
770
typedef
uint64_t
rte_iova_t
;
771
#define RTE_BAD_IOVA ((rte_iova_t)-1)
772
773
/*********** Structure alignment markers ********/
774
775
#ifndef RTE_TOOLCHAIN_MSVC
776
778
__extension__
typedef
void
*
RTE_MARKER
[0];
780
__extension__
typedef
uint8_t
RTE_MARKER8
[0];
782
__extension__
typedef
uint16_t
RTE_MARKER16
[0];
784
__extension__
typedef
uint32_t
RTE_MARKER32
[0];
786
__extension__
typedef
uint64_t
RTE_MARKER64
[0];
787
788
#endif
789
790
/*********** Macros for calculating min and max **********/
791
795
#define RTE_MIN(a, b) \
796
__extension__ ({ \
797
typeof (a) _a = (a); \
798
typeof (b) _b = (b); \
799
_a < _b ? _a : _b; \
800
})
801
809
#define RTE_MIN_T(a, b, t) \
810
((t)(a) < (t)(b) ? (t)(a) : (t)(b))
811
815
#define RTE_MAX(a, b) \
816
__extension__ ({ \
817
typeof (a) _a = (a); \
818
typeof (b) _b = (b); \
819
_a > _b ? _a : _b; \
820
})
821
829
#define RTE_MAX_T(a, b, t) \
830
((t)(a) > (t)(b) ? (t)(a) : (t)(b))
831
832
/*********** Other general functions / macros ********/
833
834
#ifndef offsetof
836
#define offsetof(TYPE, MEMBER) __builtin_offsetof (TYPE, MEMBER)
837
#endif
838
853
#ifndef container_of
854
#ifdef RTE_TOOLCHAIN_MSVC
855
#define container_of(ptr, type, member) \
856
((type *)((uintptr_t)(ptr) - offsetof(type, member)))
857
#else
858
#define container_of(ptr, type, member) __extension__ ({ \
859
const typeof(((type *)0)->member) *_ptr = (ptr); \
860
__rte_unused type *_target_ptr = \
861
(type *)(ptr); \
862
(type *)(((uintptr_t)_ptr) - offsetof(type, member)); \
863
})
864
#endif
865
#endif
866
868
#define RTE_SWAP(a, b) \
869
__extension__ ({ \
870
typeof (a) _a = a; \
871
a = b; \
872
b = _a; \
873
})
874
885
#define RTE_SIZEOF_FIELD(type, field) (sizeof(((type *)0)->field))
886
887
#define _RTE_STR(x) #x
889
#define RTE_STR(x) _RTE_STR(x)
890
896
#define RTE_FMT(fmt, ...) fmt "%.0s", __VA_ARGS__ ""
897
#define RTE_FMT_HEAD(fmt, ...) fmt
898
#define RTE_FMT_TAIL(fmt, ...) __VA_ARGS__
899
901
#define RTE_LEN2MASK(ln, tp) \
902
((tp)((uint64_t)-1 >> (sizeof(uint64_t) * CHAR_BIT - (ln))))
903
905
#define RTE_DIM(a) (sizeof (a) / sizeof ((a)[0]))
906
921
uint64_t
922
rte_str_to_size
(
const
char
*str);
923
955
__rte_experimental
956
char
*
957
rte_size_to_str
(
char
*buf,
int
buf_size, uint64_t count,
bool
use_iec,
const
char
*unit);
958
972
__rte_noreturn
void
973
rte_exit
(
int
exit_code,
const
char
*format, ...)
974
__rte_format_printf
(2, 3);
975
976
#ifdef __cplusplus
977
}
978
#endif
979
980
#endif
rte_str_to_size
uint64_t rte_str_to_size(const char *str)
RTE_MARKER64
__extension__ typedef uint64_t RTE_MARKER64[0]
Definition
rte_common.h:786
RTE_MARKER8
__extension__ typedef uint8_t RTE_MARKER8[0]
Definition
rte_common.h:780
RTE_MARKER32
__extension__ typedef uint32_t RTE_MARKER32[0]
Definition
rte_common.h:784
RTE_MARKER16
__extension__ typedef uint16_t RTE_MARKER16[0]
Definition
rte_common.h:782
__rte_format_printf
#define __rte_format_printf(format_index, first_arg)
Definition
rte_common.h:280
rte_iova_t
uint64_t rte_iova_t
Definition
rte_common.h:770
__rte_aligned
#define __rte_aligned(a)
Definition
rte_common.h:121
rte_size_to_str
__rte_experimental char * rte_size_to_str(char *buf, int buf_size, uint64_t count, bool use_iec, const char *unit)
rte_is_aligned
static int rte_is_aligned(const void *const __rte_restrict ptr, const unsigned int align)
Definition
rte_common.h:698
rte_exit
__rte_noreturn void rte_exit(int exit_code, const char *format,...) __rte_format_printf(2
__rte_noreturn
#define __rte_noreturn
Definition
rte_common.h:443
phys_addr_t
uint64_t phys_addr_t
Definition
rte_common.h:760
RTE_MARKER
__extension__ typedef void * RTE_MARKER[0]
Definition
rte_common.h:778
__rte_restrict
#define __rte_restrict
Definition
rte_common.h:255
lib
eal
include
rte_common.h
Generated by
1.17.0