xref: /linux/tools/testing/selftests/ublk/utils.h (revision 69050f8d6d075dc01af7a5f2f550a8067510366f)
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef KUBLK_UTILS_H
3 #define KUBLK_UTILS_H
4 
5 #ifndef min
6 #define min(a, b) ((a) < (b) ? (a) : (b))
7 #endif
8 
9 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
10 
11 #ifndef offsetof
12 #define offsetof(TYPE, MEMBER)  ((size_t)&((TYPE *)0)->MEMBER)
13 #endif
14 
15 #ifndef container_of
16 #define container_of(ptr, type, member) ({                              \
17 	unsigned long __mptr = (unsigned long)(ptr);                    \
18 	((type *)(__mptr - offsetof(type, member))); })
19 #endif
20 
21 #define round_up(val, rnd) \
22 	(((val) + ((rnd) - 1)) & ~((rnd) - 1))
23 
24 /* small sized & per-thread allocator */
25 struct allocator {
26 	unsigned int size;
27 	cpu_set_t *set;
28 };
29 
30 static inline int allocator_init(struct allocator *a, unsigned size)
31 {
32 	a->set = CPU_ALLOC(size);
33 	a->size = size;
34 
35 	if (a->set)
36 		return 0;
37 	return -ENOMEM;
38 }
39 
40 static inline void allocator_deinit(struct allocator *a)
41 {
42 	CPU_FREE(a->set);
43 	a->set = NULL;
44 	a->size = 0;
45 }
46 
47 static inline int allocator_get(struct allocator *a)
48 {
49 	int i;
50 
51 	for (i = 0; i < a->size; i += 1) {
52 		size_t set_size = CPU_ALLOC_SIZE(a->size);
53 
54 		if (!CPU_ISSET_S(i, set_size, a->set)) {
55 			CPU_SET_S(i, set_size, a->set);
56 			return i;
57 		}
58 	}
59 
60 	return -1;
61 }
62 
63 static inline void allocator_put(struct allocator *a, int i)
64 {
65 	size_t set_size = CPU_ALLOC_SIZE(a->size);
66 
67 	if (i >= 0 && i < a->size)
68 		CPU_CLR_S(i, set_size, a->set);
69 }
70 
71 static inline int allocator_get_val(struct allocator *a, int i)
72 {
73 	size_t set_size = CPU_ALLOC_SIZE(a->size);
74 
75 	return CPU_ISSET_S(i, set_size, a->set);
76 }
77 
78 static inline unsigned int ilog2(unsigned int x)
79 {
80 	if (x == 0)
81 		return 0;
82 	return (sizeof(x) * 8 - 1) - __builtin_clz(x);
83 }
84 
85 #define UBLK_DBG_DEV            (1U << 0)
86 #define UBLK_DBG_THREAD         (1U << 1)
87 #define UBLK_DBG_IO_CMD         (1U << 2)
88 #define UBLK_DBG_IO             (1U << 3)
89 #define UBLK_DBG_CTRL_CMD       (1U << 4)
90 #define UBLK_LOG                (1U << 5)
91 
92 extern unsigned int ublk_dbg_mask;
93 
94 static inline void ublk_err(const char *fmt, ...)
95 {
96 	va_list ap;
97 
98 	va_start(ap, fmt);
99 	vfprintf(stderr, fmt, ap);
100 	va_end(ap);
101 }
102 
103 static inline void ublk_log(const char *fmt, ...)
104 {
105 	if (ublk_dbg_mask & UBLK_LOG) {
106 		va_list ap;
107 
108 		va_start(ap, fmt);
109 		vfprintf(stdout, fmt, ap);
110 		va_end(ap);
111 	}
112 }
113 
114 static inline void ublk_dbg(int level, const char *fmt, ...)
115 {
116 	if (level & ublk_dbg_mask) {
117 		va_list ap;
118 
119 		va_start(ap, fmt);
120 		vfprintf(stdout, fmt, ap);
121 		va_end(ap);
122 	}
123 }
124 
125 #define ublk_assert(x)  do { \
126 	if (!(x)) {     \
127 		ublk_err("%s %d: assert!\n", __func__, __LINE__); \
128 		assert(x);      \
129 	}       \
130 } while (0)
131 
132 #endif
133