]> git.sesse.net Git - bcachefs-tools-debian/blob - libbcachefs/fifo.h
rust: bump rpassword to v7.x
[bcachefs-tools-debian] / libbcachefs / fifo.h
1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _BCACHEFS_FIFO_H
3 #define _BCACHEFS_FIFO_H
4
5 #include "util.h"
6
7 #define FIFO(type)                                                      \
8 struct {                                                                \
9         size_t front, back, size, mask;                                 \
10         type *data;                                                     \
11 }
12
13 #define DECLARE_FIFO(type, name)        FIFO(type) name
14
15 #define fifo_buf_size(fifo)                                             \
16         ((fifo)->size                                                   \
17          ? roundup_pow_of_two((fifo)->size) * sizeof((fifo)->data[0])   \
18          : 0)
19
20 #define init_fifo(fifo, _size, _gfp)                                    \
21 ({                                                                      \
22         (fifo)->front   = (fifo)->back = 0;                             \
23         (fifo)->size    = (_size);                                      \
24         (fifo)->mask    = (fifo)->size                                  \
25                 ? roundup_pow_of_two((fifo)->size) - 1                  \
26                 : 0;                                                    \
27         (fifo)->data    = kvpmalloc(fifo_buf_size(fifo), (_gfp));       \
28 })
29
30 #define free_fifo(fifo)                                                 \
31 do {                                                                    \
32         kvpfree((fifo)->data, fifo_buf_size(fifo));                     \
33         (fifo)->data = NULL;                                            \
34 } while (0)
35
36 #define fifo_swap(l, r)                                                 \
37 do {                                                                    \
38         swap((l)->front, (r)->front);                                   \
39         swap((l)->back, (r)->back);                                     \
40         swap((l)->size, (r)->size);                                     \
41         swap((l)->mask, (r)->mask);                                     \
42         swap((l)->data, (r)->data);                                     \
43 } while (0)
44
45 #define fifo_move(dest, src)                                            \
46 do {                                                                    \
47         typeof(*((dest)->data)) _t;                                     \
48         while (!fifo_full(dest) &&                                      \
49                fifo_pop(src, _t))                                       \
50                 fifo_push(dest, _t);                                    \
51 } while (0)
52
53 #define fifo_used(fifo)         (((fifo)->back - (fifo)->front))
54 #define fifo_free(fifo)         ((fifo)->size - fifo_used(fifo))
55
56 #define fifo_empty(fifo)        ((fifo)->front == (fifo)->back)
57 #define fifo_full(fifo)         (fifo_used(fifo) == (fifo)->size)
58
59 #define fifo_peek_front(fifo)   ((fifo)->data[(fifo)->front & (fifo)->mask])
60 #define fifo_peek_back(fifo)    ((fifo)->data[((fifo)->back - 1) & (fifo)->mask])
61
62 #define fifo_entry_idx_abs(fifo, p)                                     \
63         ((((p) >= &fifo_peek_front(fifo)                                \
64            ? (fifo)->front : (fifo)->back) & ~(fifo)->mask) +           \
65            (((p) - (fifo)->data)))
66
67 #define fifo_entry_idx(fifo, p) (((p) - &fifo_peek_front(fifo)) & (fifo)->mask)
68 #define fifo_idx_entry(fifo, i) ((fifo)->data[((fifo)->front + (i)) & (fifo)->mask])
69
70 #define fifo_push_back_ref(f)                                           \
71         (fifo_full((f)) ? NULL : &(f)->data[(f)->back++ & (f)->mask])
72
73 #define fifo_push_front_ref(f)                                          \
74         (fifo_full((f)) ? NULL : &(f)->data[--(f)->front & (f)->mask])
75
76 #define fifo_push_back(fifo, new)                                       \
77 ({                                                                      \
78         typeof((fifo)->data) _r = fifo_push_back_ref(fifo);             \
79         if (_r)                                                         \
80                 *_r = (new);                                            \
81         _r != NULL;                                                     \
82 })
83
84 #define fifo_push_front(fifo, new)                                      \
85 ({                                                                      \
86         typeof((fifo)->data) _r = fifo_push_front_ref(fifo);            \
87         if (_r)                                                         \
88                 *_r = (new);                                            \
89         _r != NULL;                                                     \
90 })
91
92 #define fifo_pop_front(fifo, i)                                         \
93 ({                                                                      \
94         bool _r = !fifo_empty((fifo));                                  \
95         if (_r)                                                         \
96                 (i) = (fifo)->data[(fifo)->front++ & (fifo)->mask];     \
97         _r;                                                             \
98 })
99
100 #define fifo_pop_back(fifo, i)                                          \
101 ({                                                                      \
102         bool _r = !fifo_empty((fifo));                                  \
103         if (_r)                                                         \
104                 (i) = (fifo)->data[--(fifo)->back & (fifo)->mask];      \
105         _r;                                                             \
106 })
107
108 #define fifo_push_ref(fifo)     fifo_push_back_ref(fifo)
109 #define fifo_push(fifo, i)      fifo_push_back(fifo, (i))
110 #define fifo_pop(fifo, i)       fifo_pop_front(fifo, (i))
111 #define fifo_peek(fifo)         fifo_peek_front(fifo)
112
113 #define fifo_for_each_entry(_entry, _fifo, _iter)                       \
114         for (typecheck(typeof((_fifo)->front), _iter),                  \
115              (_iter) = (_fifo)->front;                                  \
116              ((_iter != (_fifo)->back) &&                               \
117               (_entry = (_fifo)->data[(_iter) & (_fifo)->mask], true)); \
118              (_iter)++)
119
120 #define fifo_for_each_entry_ptr(_ptr, _fifo, _iter)                     \
121         for (typecheck(typeof((_fifo)->front), _iter),                  \
122              (_iter) = (_fifo)->front;                                  \
123              ((_iter != (_fifo)->back) &&                               \
124               (_ptr = &(_fifo)->data[(_iter) & (_fifo)->mask], true));  \
125              (_iter)++)
126
127 #endif /* _BCACHEFS_FIFO_H */