1 /**
2 * Copyright (C) Mellanox Technologies Ltd. 2001-2014.  ALL RIGHTS RESERVED.
3 * Copyright (C) UT-Battelle, LLC. 2015. ALL RIGHTS RESERVED.
4 *
5 * See file LICENSE for terms.
6 */
7 
8 
9 #ifndef UCS_MATH_H
10 #define UCS_MATH_H
11 
12 #include "compiler_def.h"
13 
14 #include <stddef.h>
15 #include <stdint.h>
16 #include <math.h>
17 #include <ucs/arch/bitops.h>
18 
19 BEGIN_C_DECLS
20 
21 /** @file math.h */
22 
23 #define UCS_KBYTE    (1ull << 10)
24 #define UCS_MBYTE    (1ull << 20)
25 #define UCS_GBYTE    (1ull << 30)
26 #define UCS_TBYTE    (1ull << 40)
27 
28 #define ucs_min(_a, _b) \
29 ({ \
30     typeof(_a) _min_a = (_a); \
31     typeof(_b) _min_b = (_b); \
32     (_min_a < _min_b) ? _min_a : _min_b; \
33 })
34 
35 #define ucs_max(_a, _b) \
36 ({ \
37     typeof(_a) _max_a = (_a); \
38     typeof(_b) _max_b = (_b); \
39     (_max_a > _max_b) ? _max_a : _max_b; \
40 })
41 
42 #define ucs_is_pow2_or_zero(_n) \
43     !((_n) & ((_n) - 1))
44 
45 #define ucs_is_pow2(_n) \
46     (((_n) > 0) && ucs_is_pow2_or_zero(_n))
47 
48 #define ucs_padding(_n, _alignment) \
49     ( ((_alignment) - (_n) % (_alignment)) % (_alignment) )
50 
51 #define ucs_align_down(_n, _alignment) \
52     ( (_n) - ((_n) % (_alignment)) )
53 
54 #define ucs_align_up(_n, _alignment) \
55     ( (_n) + ucs_padding(_n, _alignment) )
56 
57 #define ucs_align_down_pow2(_n, _alignment) \
58     ( (_n) & ~((_alignment) - 1) )
59 
60 #define ucs_align_up_pow2(_n, _alignment) \
61     ucs_align_down_pow2((_n) + (_alignment) - 1, _alignment)
62 
63 #define ucs_align_down_pow2_ptr(_ptr, _alignment) \
64     ((typeof(_ptr))ucs_align_down_pow2((uintptr_t)(_ptr), (_alignment)))
65 
66 #define ucs_align_up_pow2_ptr(_ptr, _alignment) \
67     ((typeof(_ptr))ucs_align_up_pow2((uintptr_t)(_ptr), (_alignment)))
68 
69 #define ucs_roundup_pow2(_n) \
70     ({ \
71         typeof(_n) pow2; \
72         ucs_assert((_n) >= 1); \
73         for (pow2 = 1; pow2 < (_n); pow2 <<= 1); \
74         pow2; \
75     })
76 
77 #define ucs_rounddown_pow2(_n) (ucs_roundup_pow2(_n + 1) / 2)
78 
79 #define ucs_signum(_n) \
80     (((_n) > (typeof(_n))0) - ((_n) < (typeof(_n))0))
81 
82 #define ucs_roundup_pow2_or0(_n) \
83     ( ((_n) == 0) ? 0 : ucs_roundup_pow2(_n) )
84 
85 /* Return values: 0 - aligned, non-0 - unaligned */
86 #define ucs_check_if_align_pow2(_n, _p) ((_n) & ((_p) - 1))
87 
88 /* Return values: off-set from the alignment */
89 #define ucs_padding_pow2(_n, _p) ucs_check_if_align_pow2(_n, _p)
90 
91 #define UCS_MASK_SAFE(_i) \
92     (((_i) >= 64) ? ((uint64_t)(-1)) : UCS_MASK(_i))
93 
94 #define ucs_div_round_up(_n, _d) \
95     (((_n) + (_d) - 1) / (_d))
96 
ucs_log2(double x)97 static inline double ucs_log2(double x)
98 {
99     return log(x) / log(2.0);
100 }
101 
102 /**
103  * Convert flags without a branch
104  * @return '_newflag' if '_oldflag' is set in '_value', otherwise - 0
105  */
106 #define ucs_convert_flag(_value, _oldflag, _newflag) \
107     ({ \
108         UCS_STATIC_ASSERT(ucs_is_constant(_oldflag)); \
109         UCS_STATIC_ASSERT(ucs_is_constant(_newflag)); \
110         UCS_STATIC_ASSERT(ucs_is_pow2(_oldflag)); \
111         UCS_STATIC_ASSERT(ucs_is_pow2(_newflag)); \
112         (((_value) & (_oldflag)) ? (_newflag) : 0); \
113     })
114 
115 
116 /**
117  * Test if a value is one of a specified list of values, assuming all possible
118  * values are powers of 2.
119  */
120 #define __ucs_test_flags(__value, __f1, __f2, __f3, __f4, __f5, __f6, __f7, __f8, __f9, ...) \
121     (__value & ((__f1) | (__f2) | (__f3) | (__f4) | (__f5) | (__f6) | (__f7) | (__f8) | (__f9)))
122 #define ucs_test_flags(__value, ...) \
123     __ucs_test_flags((__value), __VA_ARGS__, 0, 0, 0, 0, 0, 0, 0, 0, 0)
124 
125 /*
126  * Check if all given flags are on
127  */
128 #define ucs_test_all_flags(__value, __mask) \
129     ( ((__value) & (__mask)) == (__mask) )
130 
131 /**
132  * Compare unsigned numbers which can wrap-around, assuming the wrap-around
133  * distance can be at most the maximal value of the signed type.
134  *
135  * @param __a            First number
136  * @param __op           Operator (e.g >=)
137  * @param __b            Second number
138  * @param _signed_type   Signed type of __a/__b (e.g int32_t)
139  *
140  * @return value of the expression "__a __op __b".
141  */
142 #define UCS_CIRCULAR_COMPARE(__a, __op, __b, __signed_type)  \
143     ((__signed_type)((__a) - (__b)) __op 0)
144 
145 #define UCS_CIRCULAR_COMPARE8(__a, __op, __b)  UCS_CIRCULAR_COMPARE(__a, __op, __b, int8_t)
146 #define UCS_CIRCULAR_COMPARE16(__a, __op, __b)  UCS_CIRCULAR_COMPARE(__a, __op, __b, int16_t)
147 #define UCS_CIRCULAR_COMPARE32(__a, __op, __b)  UCS_CIRCULAR_COMPARE(__a, __op, __b, int32_t)
148 #define UCS_CIRCULAR_COMPARE64(__a, __op, __b)  UCS_CIRCULAR_COMPARE(__a, __op, __b, int64_t)
149 
150 #define ucs_for_each_bit(_index, _map)                   \
151     for ((_index) = ucs_ffs64_safe(_map); (_index) < 64; \
152          (_index) = ucs_ffs64_safe((uint64_t)(_map) & (-2ull << (uint64_t)(_index))))
153 
154 
155 /*
156  * Generate a large prime number
157  */
158 uint64_t ucs_get_prime(unsigned index);
159 
160 END_C_DECLS
161 
162 #endif /* MACROS_H_ */
163