2
* Copyright (c) 2001-2004 Jakub Jermar
5
* Redistribution and use in source and binary forms, with or without
6
* modification, are permitted provided that the following conditions
9
* - Redistributions of source code must retain the above copyright
10
* notice, this list of conditions and the following disclaimer.
11
* - Redistributions in binary form must reproduce the above copyright
12
* notice, this list of conditions and the following disclaimer in the
13
* documentation and/or other materials provided with the distribution.
14
* - The name of the author may not be used to endorse or promote products
15
* derived from this software without specific prior written permission.
17
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18
* IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21
* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22
* NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29
/** @addtogroup genericadt
38
#include <arch/types.h>
41
/** Doubly linked list head and link type. */
43
struct link *prev; /**< Pointer to the previous item in the list. */
44
struct link *next; /**< Pointer to the next item in the list. */
47
/** Declare and initialize statically allocated list.
49
* @param name Name of the new statically allocated list.
51
#define LIST_INITIALIZE(name) \
52
link_t name = { .prev = &name, .next = &name }
54
/** Initialize doubly-linked circular list link
56
* Initialize doubly-linked list link.
58
* @param link Pointer to link_t structure to be initialized.
60
static inline void link_initialize(link_t *link)
66
/** Initialize doubly-linked circular list
68
* Initialize doubly-linked circular list.
70
* @param head Pointer to link_t structure representing head of the list.
72
static inline void list_initialize(link_t *head)
78
/** Add item to the beginning of doubly-linked circular list
80
* Add item to the beginning of doubly-linked circular list.
82
* @param link Pointer to link_t structure to be added.
83
* @param head Pointer to link_t structure representing head of the list.
85
static inline void list_prepend(link_t *link, link_t *head)
87
link->next = head->next;
89
head->next->prev = link;
93
/** Add item to the end of doubly-linked circular list
95
* Add item to the end of doubly-linked circular list.
97
* @param link Pointer to link_t structure to be added.
98
* @param head Pointer to link_t structure representing head of the list.
100
static inline void list_append(link_t *link, link_t *head)
102
link->prev = head->prev;
104
head->prev->next = link;
108
/** Remove item from doubly-linked circular list
110
* Remove item from doubly-linked circular list.
112
* @param link Pointer to link_t structure to be removed from the list it is
115
static inline void list_remove(link_t *link)
117
link->next->prev = link->prev;
118
link->prev->next = link->next;
119
link_initialize(link);
122
/** Query emptiness of doubly-linked circular list
124
* Query emptiness of doubly-linked circular list.
126
* @param head Pointer to link_t structure representing head of the list.
128
static inline bool list_empty(link_t *head)
130
return head->next == head ? true : false;
134
/** Split or concatenate headless doubly-linked circular list
136
* Split or concatenate headless doubly-linked circular list.
138
* Note that the algorithm works both directions:
139
* concatenates splitted lists and splits concatenated lists.
141
* @param part1 Pointer to link_t structure leading the first (half of the
143
* @param part2 Pointer to link_t structure leading the second (half of the
146
static inline void headless_list_split_or_concat(link_t *part1, link_t *part2)
150
part1->prev->next = part2;
151
part2->prev->next = part1;
153
part1->prev = part2->prev;
158
/** Split headless doubly-linked circular list
160
* Split headless doubly-linked circular list.
162
* @param part1 Pointer to link_t structure leading the first half of the
164
* @param part2 Pointer to link_t structure leading the second half of the
167
static inline void headless_list_split(link_t *part1, link_t *part2)
169
headless_list_split_or_concat(part1, part2);
172
/** Concatenate two headless doubly-linked circular lists
174
* Concatenate two headless doubly-linked circular lists.
176
* @param part1 Pointer to link_t structure leading the first headless list.
177
* @param part2 Pointer to link_t structure leading the second headless list.
179
static inline void headless_list_concat(link_t *part1, link_t *part2)
181
headless_list_split_or_concat(part1, part2);
184
#define list_get_instance(link, type, member) \
185
((type *)(((uint8_t *)(link)) - ((uint8_t *)&(((type *)NULL)->member))))
187
extern bool list_member(const link_t *link, const link_t *head);
188
extern void list_concat(link_t *head1, link_t *head2);