| 1 |
|
| 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 |
|
| 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
|