1 /*
2  * Arm SCP/MCP Software
3  * Copyright (c) 2015-2021, Arm Limited and Contributors. All rights reserved.
4  *
5  * SPDX-License-Identifier: BSD-3-Clause
6  *
7  * Description:
8  *     Intrusive circular doubly-linked list.
9  */
10 
11 #ifndef FWK_DLIST_H
12 #define FWK_DLIST_H
13 
14 #include <fwk_slist.h>
15 
16 /*!
17  * \addtogroup GroupLibFramework Framework
18  * \{
19  */
20 
21 /*!
22  * \addtogroup GroupLinkedList Linked Lists
23  * \{
24  */
25 
26 /*!
27  * \brief Doubly-linked list.
28  *
29  * \internal
30  * \note This structure can be safely used in the place of ::fwk_slist,
31  *      ::fwk_slist_node, or ::fwk_dlist_node.
32  */
33 struct fwk_dlist {
34     /*! Pointer to the list head */
35     struct fwk_dlist_node *head;
36 
37     /*! Pointer to the list tail */
38     struct fwk_dlist_node *tail;
39 };
40 
41 /*!
42  * \brief Doubly-linked list node.
43  *
44  * \internal
45  * \note This structure can be safely used in the place of ::fwk_slist_node.
46  */
47 struct fwk_dlist_node {
48     /*! Pointer to the next node in the list */
49     struct fwk_dlist_node *next;
50 
51     /*! Pointer to the previous node in the list */
52     struct fwk_dlist_node *prev;
53 };
54 
55 /*!
56  * @cond
57  */
58 
59 /*
60  * Add a new node to the head of a doubly-linked list.
61  *
62  * For internal use only.
63  * See fwk_list_push_head(list, new) for the public interface.
64  */
65 void __fwk_dlist_push_head(struct fwk_dlist *list, struct fwk_dlist_node *new)
66     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_WRITE1(1)
67         FWK_READ_WRITE1(2);
68 
69 /*
70  * Add a new node to the end of a doubly-linked list.
71  *
72  * For internal use only.
73  * See fwk_list_push_tail(list, new) for the public interface.
74  */
75 void __fwk_dlist_push_tail(struct fwk_dlist *list, struct fwk_dlist_node *new)
76     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_WRITE1(1)
77         FWK_READ_WRITE1(2);
78 
79 /*
80  * Remove and return the head node from a doubly-linked list.
81  *
82  * For internal use only.
83  * See fwk_list_pop_head(list) for the public interface.
84  */
85 struct fwk_dlist_node *__fwk_dlist_pop_head(struct fwk_dlist *list) FWK_LEAF
86     FWK_NOTHROW FWK_NONNULL(1) FWK_READ_WRITE1(1);
87 
88 /*
89  * Remove a node from a doubly-linked list.
90  *
91  * For internal use only.
92  * See fwk_list_remove(list, node) for the public interface.
93  */
94 void __fwk_dlist_remove(struct fwk_dlist *list, struct fwk_dlist_node *node)
95     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1)
96         FWK_READ_WRITE1(2);
97 
98 /*
99  * Insert a node into a doubly-linked list.
100  *
101  * For internal use only.
102  * See fwk_list_insert(list, new, node) for the public interface.
103  */
104 void __fwk_dlist_insert(
105     struct fwk_dlist *list,
106     struct fwk_dlist_node *restrict new,
107     struct fwk_dlist_node *restrict node) FWK_LEAF FWK_NOTHROW FWK_NONNULL(1)
108     FWK_NONNULL(2) FWK_READ_WRITE1(1) FWK_READ_WRITE1(2) FWK_READ_WRITE1(3);
109 
110 /*!
111  * @endcond
112  */
113 
114 /*!
115  * \}
116  */
117 
118 /*!
119  * \}
120  */
121 
122 #endif /* FWK_DLIST_H */
123