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