From 543e0256c19f397921a332e06b423215fd9aecb5 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Thu, 30 Nov 2023 15:51:05 +0800 Subject: build: don't define FUNC_ATTR_* as empty in headers (#26317) FUNC_ATTR_* should only be used in .c files with generated headers. Defining FUNC_ATTR_* as empty in headers causes misuses of them to be silently ignored. Instead don't define them by default, and only define them as empty after a .c file has included its generated header. --- src/nvim/lib/queue.h | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) (limited to 'src/nvim/lib') diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index 40769e44b5..0c4ab7e9ed 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -44,22 +44,29 @@ typedef struct _queue { } // ffi.cdef is unable to swallow `bool` in place of `int` here. +static inline int QUEUE_EMPTY(const QUEUE *q) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; + static inline int QUEUE_EMPTY(const QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT { return q == q->next; } #define QUEUE_HEAD(q) (q)->next -static inline void QUEUE_INIT(QUEUE *const q) FUNC_ATTR_ALWAYS_INLINE +static inline void QUEUE_INIT(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_INIT(QUEUE *const q) { q->next = q; q->prev = q; } +static inline void QUEUE_ADD(QUEUE *h, QUEUE *n) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) - FUNC_ATTR_ALWAYS_INLINE { h->prev->next = n->next; n->next->prev = h->prev; @@ -67,8 +74,10 @@ static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) h->prev->next = h; } +static inline void QUEUE_INSERT_HEAD(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE { q->next = h->next; q->prev = h; @@ -76,8 +85,10 @@ static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) h->next = q; } +static inline void QUEUE_INSERT_TAIL(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) - FUNC_ATTR_ALWAYS_INLINE { q->next = h; q->prev = h->prev; @@ -85,7 +96,10 @@ static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) h->prev = q; } -static inline void QUEUE_REMOVE(QUEUE *const q) FUNC_ATTR_ALWAYS_INLINE +static inline void QUEUE_REMOVE(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_REMOVE(QUEUE *const q) { q->prev->next = q->next; q->next->prev = q->prev; -- cgit From 481a3158866638946c91fab28ae5bca97ff1e814 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 2 Dec 2023 14:10:26 +0100 Subject: refactor: remove unused file ringbuf.h --- src/nvim/lib/ringbuf.h | 290 ------------------------------------------------- 1 file changed, 290 deletions(-) delete mode 100644 src/nvim/lib/ringbuf.h (limited to 'src/nvim/lib') diff --git a/src/nvim/lib/ringbuf.h b/src/nvim/lib/ringbuf.h deleted file mode 100644 index c8abccfeb4..0000000000 --- a/src/nvim/lib/ringbuf.h +++ /dev/null @@ -1,290 +0,0 @@ -/// Macros-based ring buffer implementation. -/// -/// Supported functions: -/// -/// - new: allocates new ring buffer. -/// - dealloc: free ring buffer itself. -/// - free: free ring buffer and all its elements. -/// - push: adds element to the end of the buffer. -/// - length: get buffer length. -/// - size: size of the ring buffer. -/// - idx: get element at given index. -/// - idx_p: get pointer to the element at given index. -/// - insert: insert element at given position. -/// - remove: remove element from given position. - -#pragma once - -#include -#include -#include -#include - -#include "nvim/func_attr.h" -#include "nvim/memory.h" - -#define _RINGBUF_LENGTH(rb) \ - ((rb)->first == NULL ? 0 \ - : ((rb)->next == (rb)->first) ? (size_t)((rb)->buf_end - (rb)->buf) + 1 \ - : ((rb)->next > (rb)->first) ? (size_t)((rb)->next - (rb)->first) \ - : (size_t)((rb)->next - (rb)->buf + (rb)->buf_end - (rb)->first + 1)) - -#define _RINGBUF_NEXT(rb, var) \ - ((var) == (rb)->buf_end ? (rb)->buf : (var) + 1) -#define _RINGBUF_PREV(rb, var) \ - ((var) == (rb)->buf ? (rb)->buf_end : (var) - 1) - -/// Iterate over all ringbuf values -/// -/// @param rb Ring buffer to iterate over. -/// @param RBType Type of the ring buffer element. -/// @param varname Variable name. -#define RINGBUF_FORALL(rb, RBType, varname) \ - size_t varname##_length_fa_ = _RINGBUF_LENGTH(rb); \ - for (RBType *varname = ((rb)->first == NULL ? (rb)->next : (rb)->first); \ - varname##_length_fa_; \ - (varname = _RINGBUF_NEXT(rb, varname)), \ - varname##_length_fa_--) - -/// Iterate over all ringbuf values, from end to the beginning -/// -/// Unlike previous RINGBUF_FORALL uses already defined variable, in place of -/// defining variable in the cycle body. -/// -/// @param rb Ring buffer to iterate over. -/// @param RBType Type of the ring buffer element. -/// @param varname Variable name. -#define RINGBUF_ITER_BACK(rb, RBType, varname) \ - size_t varname##_length_ib_ = _RINGBUF_LENGTH(rb); \ - for (varname = ((rb)->next == (rb)->buf ? (rb)->buf_end : (rb)->next - 1); \ - varname##_length_ib_; \ - (varname = _RINGBUF_PREV(rb, varname)), \ - varname##_length_ib_--) - -/// Define a ring buffer structure -/// -/// @param TypeName Ring buffer type name. Actual type name will be -/// `{TypeName}RingBuffer`. -/// @param RBType Type of the single ring buffer element. -#define RINGBUF_TYPEDEF(TypeName, RBType) \ - typedef struct { \ - RBType *buf; \ - RBType *next; \ - RBType *first; \ - RBType *buf_end; \ - } TypeName##RingBuffer; - -/// Dummy item free macros, for use in RINGBUF_INIT -/// -/// This macros actually does nothing. -/// -/// @param[in] item Item to be freed. -#define RINGBUF_DUMMY_FREE(item) - -/// Static ring buffer -/// -/// @warning Ring buffers created with this macros must neither be freed nor -/// deallocated. -/// -/// @param scope Ring buffer scope. -/// @param TypeName Ring buffer type name. -/// @param RBType Type of the single ring buffer element. -/// @param varname Variable name. -/// @param rbsize Ring buffer size. -#define RINGBUF_STATIC(scope, TypeName, RBType, varname, rbsize) \ - static RBType _##varname##_buf[rbsize]; \ - scope TypeName##RingBuffer varname = { \ - .buf = _##varname##_buf, \ - .next = _##varname##_buf, \ - .first = NULL, \ - .buf_end = _##varname##_buf + rbsize - 1, \ - }; - -/// Initialize a new ring buffer -/// -/// @param TypeName Ring buffer type name. Actual type name will be -/// `{TypeName}RingBuffer`. -/// @param funcprefix Prefix for all ring buffer functions. Function name will -/// look like `{funcprefix}_rb_{function_name}`. -/// @param RBType Type of the single ring buffer element. -/// @param rbfree Function used to free ring buffer element. May be -/// a macros like `#define RBFREE(item)` (to skip freeing). -/// -/// Intended function signature: `void *rbfree(RBType *)`; -#define RINGBUF_INIT(TypeName, funcprefix, RBType, rbfree) \ - static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ - REAL_FATTR_WARN_UNUSED_RESULT; \ - static inline TypeName##RingBuffer funcprefix##_rb_new(const size_t size) \ - { \ - assert(size != 0); \ - RBType *buf = xmalloc(size * sizeof(RBType)); \ - return (TypeName##RingBuffer) { \ - .buf = buf, \ - .next = buf, \ - .first = NULL, \ - .buf_end = buf + size - 1, \ - }; \ - } \ - static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ - REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_free(TypeName##RingBuffer *const rb) \ - { \ - if (rb == NULL) { \ - return; \ - } \ - RINGBUF_FORALL(rb, RBType, rbitem) { \ - rbfree(rbitem); \ - } \ - XFREE_CLEAR(rb->buf); \ - } \ - static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ - REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_dealloc(TypeName##RingBuffer *const rb) \ - { \ - XFREE_CLEAR(rb->buf); \ - } \ - static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ - REAL_FATTR_NONNULL_ARG(1); \ - static inline void funcprefix##_rb_push(TypeName##RingBuffer *const rb, \ - RBType item) \ - { \ - if (rb->next == rb->first) { \ - rbfree(rb->first); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rb->first == NULL) { \ - rb->first = rb->next; \ - } \ - *rb->next = item; \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ - } \ - static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ - const RBType *const item_p) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ - static inline ptrdiff_t funcprefix##_rb_find_idx(const TypeName##RingBuffer *const rb, \ - const RBType *const item_p) \ - { \ - assert(rb->buf <= item_p); \ - assert(rb->buf_end >= item_p); \ - if (rb->first == NULL) { \ - return -1; \ - } else if (item_p >= rb->first) { \ - return item_p - rb->first; \ - } else { \ - return item_p - rb->buf + rb->buf_end - rb->first + 1; \ - } \ - } \ - static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline size_t funcprefix##_rb_size(const TypeName##RingBuffer *const rb) \ - { \ - return (size_t)(rb->buf_end - rb->buf) + 1; \ - } \ - static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline size_t funcprefix##_rb_length(const TypeName##RingBuffer *const rb) \ - { \ - return _RINGBUF_LENGTH(rb); \ - } \ - static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE; \ - static inline RBType *funcprefix##_rb_idx_p(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - if (rb->first + idx > rb->buf_end) { \ - return rb->buf + ((rb->first + idx) - (rb->buf_end + 1)); \ - } else { \ - return rb->first + idx; \ - } \ - } \ - static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ALL REAL_FATTR_PURE REAL_FATTR_UNUSED; \ - static inline RBType funcprefix##_rb_idx(const TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - return *funcprefix##_rb_idx_p(rb, idx); \ - } \ - static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ - REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_insert(TypeName##RingBuffer *const rb, \ - const size_t idx, \ - RBType item) \ - { \ - assert(idx <= funcprefix##_rb_size(rb)); \ - assert(idx <= funcprefix##_rb_length(rb)); \ - const size_t length = funcprefix##_rb_length(rb); \ - if (idx == length) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - RBType *const insertpos = funcprefix##_rb_idx_p(rb, idx); \ - if (insertpos == rb->next) { \ - funcprefix##_rb_push(rb, item); \ - return; \ - } \ - if (length == funcprefix##_rb_size(rb)) { \ - rbfree(rb->first); \ - } \ - if (insertpos < rb->next) { \ - memmove(insertpos + 1, insertpos, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)insertpos)); \ - } else { \ - assert(insertpos > rb->first); \ - assert(rb->next <= rb->first); \ - memmove(rb->buf + 1, rb->buf, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)rb->buf)); \ - *rb->buf = *rb->buf_end; \ - memmove(insertpos + 1, insertpos, \ - (size_t)((uintptr_t)(rb->buf_end + 1) - (uintptr_t)insertpos)); \ - } \ - *insertpos = item; \ - if (length == funcprefix##_rb_size(rb)) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } \ - rb->next = _RINGBUF_NEXT(rb, rb->next); \ - } \ - static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ - REAL_FATTR_NONNULL_ARG(1) REAL_FATTR_UNUSED; \ - static inline void funcprefix##_rb_remove(TypeName##RingBuffer *const rb, \ - const size_t idx) \ - { \ - assert(idx < funcprefix##_rb_size(rb)); \ - assert(idx < funcprefix##_rb_length(rb)); \ - RBType *const rmpos = funcprefix##_rb_idx_p(rb, idx); \ - rbfree(rmpos); \ - if (rmpos == rb->next - 1) { \ - rb->next--; \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ - } \ - } else if (rmpos == rb->first) { \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - if (rb->first == rb->next) { \ - rb->first = NULL; \ - rb->next = rb->buf; \ - } \ - } else if (rb->first < rb->next || rb->next == rb->buf) { \ - assert(rmpos > rb->first); \ - assert(rmpos <= _RINGBUF_PREV(rb, rb->next)); \ - memmove(rb->first + 1, rb->first, \ - (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } else if (rmpos < rb->next) { \ - memmove(rmpos, rmpos + 1, \ - (size_t)((uintptr_t)rb->next - (uintptr_t)rmpos)); \ - rb->next = _RINGBUF_PREV(rb, rb->next); \ - } else { \ - assert(rb->first < rb->buf_end); \ - memmove(rb->first + 1, rb->first, \ - (size_t)((uintptr_t)rmpos - (uintptr_t)rb->first)); \ - rb->first = _RINGBUF_NEXT(rb, rb->first); \ - } \ - } -- cgit From ab2aad509d6e4fc57a6afe056275405ec6451671 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Wed, 20 Dec 2023 17:22:19 +0100 Subject: refactor: follow style guide --- src/nvim/lib/queue.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src/nvim/lib') diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h index 0c4ab7e9ed..1f113a057a 100644 --- a/src/nvim/lib/queue.h +++ b/src/nvim/lib/queue.h @@ -23,9 +23,9 @@ #include "nvim/func_attr.h" -typedef struct _queue { - struct _queue *next; - struct _queue *prev; +typedef struct queue { + struct queue *next; + struct queue *prev; } QUEUE; // Public macros. -- cgit From 1813661a6197c76ea6621284570aca1d56597099 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Thu, 4 Jan 2024 15:38:16 +0100 Subject: refactor(IWYU): fix headers Remove `export` pramgas from defs headers as it causes IWYU to believe that the definitions from the defs headers comes from main header, which is not what we really want. --- src/nvim/lib/queue.h | 106 ---------------------------------------------- src/nvim/lib/queue_defs.h | 106 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 106 insertions(+), 106 deletions(-) delete mode 100644 src/nvim/lib/queue.h create mode 100644 src/nvim/lib/queue_defs.h (limited to 'src/nvim/lib') diff --git a/src/nvim/lib/queue.h b/src/nvim/lib/queue.h deleted file mode 100644 index 1f113a057a..0000000000 --- a/src/nvim/lib/queue.h +++ /dev/null @@ -1,106 +0,0 @@ -// Queue implemented by circularly-linked list. -// -// Adapted from libuv. Simpler and more efficient than klist.h for implementing -// queues that support arbitrary insertion/removal. -// -// Copyright (c) 2013, Ben Noordhuis -// -// Permission to use, copy, modify, and/or distribute this software for any -// purpose with or without fee is hereby granted, provided that the above -// copyright notice and this permission notice appear in all copies. -// -// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES -// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF -// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR -// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES -// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN -// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF -// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - -#pragma once - -#include - -#include "nvim/func_attr.h" - -typedef struct queue { - struct queue *next; - struct queue *prev; -} QUEUE; - -// Public macros. -#define QUEUE_DATA(ptr, type, field) \ - ((type *)((char *)(ptr) - offsetof(type, field))) - -// Important note: the node currently being processed can be safely deleted. -// otherwise, mutating the list while QUEUE_FOREACH is iterating over its -// elements results in undefined behavior. -#define QUEUE_FOREACH(q, h, code) \ - (q) = (h)->next; \ - while ((q) != (h)) { \ - QUEUE *next = q->next; \ - code \ - (q) = next; \ - } - -// ffi.cdef is unable to swallow `bool` in place of `int` here. -static inline int QUEUE_EMPTY(const QUEUE *q) - REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; - -static inline int QUEUE_EMPTY(const QUEUE *const q) -{ - return q == q->next; -} - -#define QUEUE_HEAD(q) (q)->next - -static inline void QUEUE_INIT(QUEUE *q) - REAL_FATTR_ALWAYS_INLINE; - -static inline void QUEUE_INIT(QUEUE *const q) -{ - q->next = q; - q->prev = q; -} - -static inline void QUEUE_ADD(QUEUE *h, QUEUE *n) - REAL_FATTR_ALWAYS_INLINE; - -static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) -{ - h->prev->next = n->next; - n->next->prev = h->prev; - h->prev = n->prev; - h->prev->next = h; -} - -static inline void QUEUE_INSERT_HEAD(QUEUE *h, QUEUE *q) - REAL_FATTR_ALWAYS_INLINE; - -static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) -{ - q->next = h->next; - q->prev = h; - q->next->prev = q; - h->next = q; -} - -static inline void QUEUE_INSERT_TAIL(QUEUE *h, QUEUE *q) - REAL_FATTR_ALWAYS_INLINE; - -static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) -{ - q->next = h; - q->prev = h->prev; - q->prev->next = q; - h->prev = q; -} - -static inline void QUEUE_REMOVE(QUEUE *q) - REAL_FATTR_ALWAYS_INLINE; - -static inline void QUEUE_REMOVE(QUEUE *const q) -{ - q->prev->next = q->next; - q->next->prev = q->prev; -} diff --git a/src/nvim/lib/queue_defs.h b/src/nvim/lib/queue_defs.h new file mode 100644 index 0000000000..1f113a057a --- /dev/null +++ b/src/nvim/lib/queue_defs.h @@ -0,0 +1,106 @@ +// Queue implemented by circularly-linked list. +// +// Adapted from libuv. Simpler and more efficient than klist.h for implementing +// queues that support arbitrary insertion/removal. +// +// Copyright (c) 2013, Ben Noordhuis +// +// Permission to use, copy, modify, and/or distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +#pragma once + +#include + +#include "nvim/func_attr.h" + +typedef struct queue { + struct queue *next; + struct queue *prev; +} QUEUE; + +// Public macros. +#define QUEUE_DATA(ptr, type, field) \ + ((type *)((char *)(ptr) - offsetof(type, field))) + +// Important note: the node currently being processed can be safely deleted. +// otherwise, mutating the list while QUEUE_FOREACH is iterating over its +// elements results in undefined behavior. +#define QUEUE_FOREACH(q, h, code) \ + (q) = (h)->next; \ + while ((q) != (h)) { \ + QUEUE *next = q->next; \ + code \ + (q) = next; \ + } + +// ffi.cdef is unable to swallow `bool` in place of `int` here. +static inline int QUEUE_EMPTY(const QUEUE *q) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_PURE REAL_FATTR_WARN_UNUSED_RESULT; + +static inline int QUEUE_EMPTY(const QUEUE *const q) +{ + return q == q->next; +} + +#define QUEUE_HEAD(q) (q)->next + +static inline void QUEUE_INIT(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_INIT(QUEUE *const q) +{ + q->next = q; + q->prev = q; +} + +static inline void QUEUE_ADD(QUEUE *h, QUEUE *n) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_ADD(QUEUE *const h, QUEUE *const n) +{ + h->prev->next = n->next; + n->next->prev = h->prev; + h->prev = n->prev; + h->prev->next = h; +} + +static inline void QUEUE_INSERT_HEAD(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_INSERT_HEAD(QUEUE *const h, QUEUE *const q) +{ + q->next = h->next; + q->prev = h; + q->next->prev = q; + h->next = q; +} + +static inline void QUEUE_INSERT_TAIL(QUEUE *h, QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_INSERT_TAIL(QUEUE *const h, QUEUE *const q) +{ + q->next = h; + q->prev = h->prev; + q->prev->next = q; + h->prev = q; +} + +static inline void QUEUE_REMOVE(QUEUE *q) + REAL_FATTR_ALWAYS_INLINE; + +static inline void QUEUE_REMOVE(QUEUE *const q) +{ + q->prev->next = q->next; + q->next->prev = q->prev; +} -- cgit