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 singly-linked list.
9  */
10 
11 #ifndef FWK_SLIST_H
12 #define FWK_SLIST_H
13 
14 #include <fwk_attributes.h>
15 
16 #include <stdbool.h>
17 
18 /*!
19  * \addtogroup GroupLibFramework Framework
20  * \{
21  */
22 
23 /*!
24  * \addtogroup GroupLinkedList Linked Lists
25  * \{
26  */
27 
28 /*!
29  * \brief Singly-linked list.
30  *
31  * \internal
32  * \note This structure can be safely used in the place of ::fwk_slist_node.
33  */
34 struct fwk_slist {
35     /*! Pointer to the list head */
36     struct fwk_slist_node *head;
37 
38     /*! Pointer to the list tail */
39     struct fwk_slist_node *tail;
40 };
41 
42 /*!
43  * \brief Singly-linked list node.
44  */
45 struct fwk_slist_node {
46     /*! Pointer to the next node in the list */
47     struct fwk_slist_node *next;
48 };
49 
50 /*!
51  * @cond
52  */
53 
54 /*
55  * Initialize a singly-linked list.
56  *
57  * For internal use only.
58  * See fwk_list_init(list, new) for the public interface.
59  */
60 void __fwk_slist_init(struct fwk_slist *list) FWK_LEAF FWK_NOTHROW
61     FWK_NONNULL(1) FWK_WRITE_ONLY1(1);
62 
63 /*
64  * Retrieve the node at the head of a singly-linked list.
65  *
66  * For internal use only.
67  * See fwk_list_head(list) for the public interface.
68  */
69 struct fwk_slist_node *__fwk_slist_head(const struct fwk_slist *list)
70     FWK_PURE FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_READ_ONLY1(1);
71 
72 /*
73  * Test whether a singly-linked list is empty or not.
74  *
75  * For internal use only.
76  * See fwk_list_is_empty(list) for the public interface.
77  */
78 bool __fwk_slist_is_empty(const struct fwk_slist *list) FWK_PURE FWK_LEAF
79     FWK_NOTHROW FWK_NONNULL(1) FWK_READ_ONLY1(1);
80 
81 /*
82  * Add a new node to the head of a singly-linked list.
83  *
84  * For internal use only.
85  * See fwk_list_push_head(list, new) for the public interface.
86  */
87 void __fwk_slist_push_head(struct fwk_slist *list, struct fwk_slist_node *new)
88     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_WRITE1(1)
89         FWK_READ_WRITE1(2);
90 
91 /*
92  * Add a new node to the end of a singly-linked list.
93  *
94  * For internal use only.
95  * See fwk_list_push_tail(list, new) for the public interface.
96  */
97 void __fwk_slist_push_tail(struct fwk_slist *list, struct fwk_slist_node *new)
98     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_WRITE1(1)
99         FWK_READ_WRITE1(2);
100 
101 /*
102  * Remove and return the head node from a singly-linked list.
103  *
104  * For internal use only.
105  * See fwk_list_pop_head(list) for the public interface.
106  */
107 struct fwk_slist_node *__fwk_slist_pop_head(struct fwk_slist *list) FWK_LEAF
108     FWK_NOTHROW FWK_NONNULL(1) FWK_READ_WRITE1(1);
109 
110 /*
111  * Get the next node from a singly-linked list.
112  *
113  * For internal use only.
114  * See fwk_list_next(list, node) for the public interface.
115  */
116 struct fwk_slist_node *__fwk_slist_next(
117     const struct fwk_slist *list,
118     const struct fwk_slist_node *node) FWK_PURE FWK_LEAF FWK_NOTHROW
119     FWK_NONNULL(1) FWK_NONNULL(2) FWK_UNTOUCHED(1) FWK_READ_ONLY1(2);
120 
121 /*
122  * Remove a node from a singly-linked list.
123  *
124  * For internal use only.
125  * See fwk_list_remove(list, node) for the public interface.
126  */
127 void __fwk_slist_remove(struct fwk_slist *list, struct fwk_slist_node *node)
128     FWK_LEAF FWK_NOTHROW FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_WRITE1(1)
129         FWK_READ_ONLY1(2);
130 
131 /*
132  * Test if a node is in a singly-linked list.
133  *
134  * For internal use only.
135  * See fwk_list_contains(list, node) for the public interface.
136  */
137 bool __fwk_slist_contains(
138     const struct fwk_slist *list,
139     const struct fwk_slist_node *node) FWK_PURE FWK_LEAF FWK_NOTHROW
140     FWK_NONNULL(1) FWK_NONNULL(2) FWK_READ_ONLY1(1) FWK_READ_ONLY1(2);
141 
142 /*!
143  * @endcond
144  */
145 
146 /*!
147  * \}
148  */
149 
150 /*!
151  * \}
152  */
153 
154 #endif /* FWK_SLIST_H */
155