Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
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 */
25struct allocator {
26 unsigned int size;
27 cpu_set_t *set;
28};
29
30static 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
40static inline void allocator_deinit(struct allocator *a)
41{
42 CPU_FREE(a->set);
43 a->set = NULL;
44 a->size = 0;
45}
46
47static 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
63static 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
71static 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
78static 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
92extern unsigned int ublk_dbg_mask;
93
94static 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
103static 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
114static 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