X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libbcachefs%2Ffifo.h;h=66b945be10c2309a9e758b228b146047b20674e2;hb=1e358401ecdf1963e5799de19ab69111e82e5ebc;hp=a391277e7b7a5717c99fafcd30847fa03002b150;hpb=64c325ef483c863c720a7f53c6b3126e583e05a0;p=bcachefs-tools-debian diff --git a/libbcachefs/fifo.h b/libbcachefs/fifo.h index a391277..66b945b 100644 --- a/libbcachefs/fifo.h +++ b/libbcachefs/fifo.h @@ -1,45 +1,35 @@ -#ifndef _BCACHE_FIFO_H -#define _BCACHE_FIFO_H +/* SPDX-License-Identifier: GPL-2.0 */ +#ifndef _BCACHEFS_FIFO_H +#define _BCACHEFS_FIFO_H -#define DECLARE_FIFO(type, name) \ - struct { \ - size_t front, back, size, mask; \ - type *data; \ - } name +#include "util.h" + +#define FIFO(type) \ +struct { \ + size_t front, back, size, mask; \ + type *data; \ +} + +#define DECLARE_FIFO(type, name) FIFO(type) name + +#define fifo_buf_size(fifo) \ + ((fifo)->size \ + ? roundup_pow_of_two((fifo)->size) * sizeof((fifo)->data[0]) \ + : 0) #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; \ + (fifo)->size = (_size); \ + (fifo)->mask = (fifo)->size \ + ? roundup_pow_of_two((fifo)->size) - 1 \ + : 0; \ + (fifo)->data = kvpmalloc(fifo_buf_size(fifo), (_gfp)); \ }) #define free_fifo(fifo) \ do { \ - kvfree((fifo)->data); \ + kvpfree((fifo)->data, fifo_buf_size(fifo)); \ (fifo)->data = NULL; \ } while (0) @@ -69,7 +59,13 @@ do { \ #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_abs(fifo, p) \ + ((((p) >= &fifo_peek_front(fifo) \ + ? (fifo)->front : (fifo)->back) & ~(fifo)->mask) + \ + (((p) - (fifo)->data))) + #define fifo_entry_idx(fifo, p) (((p) - &fifo_peek_front(fifo)) & (fifo)->mask) +#define fifo_idx_entry(fifo, i) ((fifo)->data[((fifo)->front + (i)) & (fifo)->mask]) #define fifo_push_back_ref(f) \ (fifo_full((f)) ? NULL : &(f)->data[(f)->back++ & (f)->mask]) @@ -105,7 +101,7 @@ do { \ ({ \ bool _r = !fifo_empty((fifo)); \ if (_r) \ - (i) = (fifo)->data[--(fifo)->back & (fifo)->mask] \ + (i) = (fifo)->data[--(fifo)->back & (fifo)->mask]; \ _r; \ }) @@ -115,16 +111,17 @@ do { \ #define fifo_peek(fifo) fifo_peek_front(fifo) #define fifo_for_each_entry(_entry, _fifo, _iter) \ - for (_iter = (_fifo)->front; \ + for (typecheck(typeof((_fifo)->front), _iter), \ + (_iter) = (_fifo)->front; \ ((_iter != (_fifo)->back) && \ (_entry = (_fifo)->data[(_iter) & (_fifo)->mask], true)); \ - _iter++) + (_iter)++) #define fifo_for_each_entry_ptr(_ptr, _fifo, _iter) \ - for (_iter = (_fifo)->front; \ + for (typecheck(typeof((_fifo)->front), _iter), \ + (_iter) = (_fifo)->front; \ ((_iter != (_fifo)->back) && \ (_ptr = &(_fifo)->data[(_iter) & (_fifo)->mask], true)); \ - _iter++) - -#endif /* _BCACHE_FIFO_H */ + (_iter)++) +#endif /* _BCACHEFS_FIFO_H */