xref: /spdk/include/spdk/queue.h (revision a6dbe3721eb3b5990707fc3e378c95e505dd8ab5)
1 /*   SPDX-License-Identifier: BSD-3-Clause
2  *   Copyright (C) 2015 Intel Corporation.
3  *   All rights reserved.
4  */
5 
6 #ifndef SPDK_QUEUE_H
7 #define SPDK_QUEUE_H
8 
9 #ifdef __cplusplus
10 extern "C" {
11 #endif
12 
13 #include <sys/cdefs.h>
14 #include <sys/queue.h>
15 
16 /*
17  * The SPDK NVMe driver was originally ported from FreeBSD, which makes
18  *  use of features in FreeBSD's queue.h that do not exist on Linux.
19  *  Include a header with these additional features on Linux only.
20  */
21 #ifdef __linux__
22 #include "spdk/queue_extras.h"
23 #endif
24 
25 /*
26  * scan-build can't follow double pointers in queues and often assumes
27  * that removed elements are still on the list. We redefine TAILQ_REMOVE
28  * with extra asserts to silence it.
29  */
30 #ifdef __clang_analyzer__
31 #undef TAILQ_REMOVE
32 #define TAILQ_REMOVE(head, elm, field) do {				\
33 	__typeof__(elm) _elm;						\
34 	if (((elm)->field.tqe_next) != NULL)				\
35 		(elm)->field.tqe_next->field.tqe_prev =			\
36 		    (elm)->field.tqe_prev;				\
37 	else								\
38 		(head)->tqh_last = (elm)->field.tqe_prev;		\
39 	*(elm)->field.tqe_prev = (elm)->field.tqe_next;			\
40 	/* make sure the removed elm is not on the list anymore */	\
41 	TAILQ_FOREACH(_elm, head, field) {				\
42 		assert(_elm != elm);					\
43 	}								\
44 } while (0)
45 #endif
46 
47 #ifdef __cplusplus
48 }
49 #endif
50 
51 #endif
52