blob: a69b3b7d96b4396d239150b691ef683f9c6d7d1d (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
|
/*
* Operating system kernel abstraction -- linked lists.
*
* Copyright (C) 2009-2010 Cambridge Silicon Radio Ltd.
*
* Refer to LICENSE.txt included with this source code for details on
* the license terms.
*/
#ifndef __OSKA_LIST_H
#define __OSKA_LIST_H
#ifdef __cplusplus
extern "C" {
#endif
/**
* @defgroup list Linked Lists
*
* Generic linked list implementations suitable for all platforms.
*
* - Circular, doubly-linked list (struct os_list).
*/
/**
* A list node.
*
* This list node structure should be the first field within any
* structure that is to be stored in a list.
*
* @see struct os_list
* @ingroup list
*/
struct os_list_node {
/**
* The pointer to the previous node in the list, or os_list_end()
* if the end of the list has been reached.
*/
struct os_list_node *prev;
/**
* The pointer to the next node in the list, or os_list_end() if
* the end of the list has been reached.
*/
struct os_list_node *next;
};
/**
* A circular, doubly-linked list of nodes.
*
* Structures to be stored in a list should contains a struct
* os_list_node as the \e first field.
* \code
* struct foo {
* struct os_list_node node;
* int bar;
* ...
* };
* \endcode
* Going to/from a struct foo to a list node is then simple.
* \code
* struct os_list_node *node;
* struct foo *foo;
* [...]
* node = &foo->node;
* foo = (struct foo *)node
* \endcode
* Lists must be initialized with os_list_init() before adding nodes
* with os_list_add_tail(). The node at the head of the list is
* obtained with os_list_head(). Nodes are removed from the list with
* os_list_del().
*
* A list can be interated from the head to the tail using:
* \code
* struct os_list_node *node;
* for (node = os_list_head(list); node != os_list_end(list); node = node->next) {
* struct foo *foo = (struct foo *)node;
* ...
* }
* \endcode
*
* In the above loop, the current list node cannot be removed (with
* os_list_del()). If this is required use this form of loop:
* \code
* struct os_list_node *node, *next;
* for (node = os_list_head(list), next = node->next;
* node != os_list_end(list);
* node = next, next = node->next) {
* struct foo *foo = (struct foo *)node;
* ...
* os_list_del(node);
* ...
* }
* \endcode
*
* @ingroup list
*/
struct os_list {
/**
* @internal
* The dummy node marking the end of the list.
*/
struct os_list_node head;
};
void os_list_init(struct os_list *list);
int os_list_empty(struct os_list *list);
void os_list_add_tail(struct os_list *list, struct os_list_node *node);
void os_list_del(struct os_list_node *node);
struct os_list_node *os_list_head(struct os_list *list);
struct os_list_node *os_list_end(struct os_list *list);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* #ifndef __OSKA_LIST_H */
|