1 /* ************************************************************************
2  * Copyright 2013 Advanced Micro Devices, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  * ************************************************************************/
16 
17 
18 #include <stddef.h>
19 #include <list.h>
20 #include <assert.h>
21 
22 static __inline
listAddAfter(ListNode * prev,ListNode * node)23 void listAddAfter(ListNode *prev, ListNode *node)
24 {
25     ListNode *next = prev->next;
26 
27     prev->next = node;
28     node->prev = prev;
29     node->next = next;
30     next->prev = node;
31 }
32 
33 void
listAddToTail(ListHead * head,ListNode * node)34 listAddToTail(ListHead *head, ListNode *node)
35 {
36     listAddAfter(head->prev, node);
37 }
38 
39 void
listAddToHead(ListHead * head,ListNode * node)40 listAddToHead(ListHead *head, ListNode *node)
41 {
42     listAddAfter(head, node);
43 }
44 
45 void
listDel(ListNode * node)46 listDel(ListNode *node)
47 {
48 #ifdef DEBUG
49     // check if it's not really the list head
50     assert(node->next != node->prev);
51 #endif
52 
53     node->prev->next = node->next;
54     node->next->prev = node->prev;
55 }
56 
57 ListNode
listDelFromTail(ListHead * head)58 *listDelFromTail(ListHead *head)
59 {
60     ListNode *node = head->prev;
61 
62     listDel(node);
63 
64     return node;
65 }
66 
67 void
listDoForEach(ListHead * head,ListAction act)68 listDoForEach(ListHead *head, ListAction act)
69 {
70     ListNode *node;
71 
72     for (node = listNodeFirst(head); node != head; node = node->next) {
73         act(node);
74     }
75 }
76 
77 void
listDoForEachSafe(ListHead * head,ListAction act)78 listDoForEachSafe(ListHead *head, ListAction act)
79 {
80     ListNode *node, *save;
81 
82     for (node = listNodeFirst(head), save = node->next; node != head;
83          node = save, save = node->next) {
84 
85         act(node);
86     }
87 }
88 
89 void
listDoForEachPriv(const ListHead * head,ListPrivAction act,void * actPriv)90 listDoForEachPriv(const ListHead *head, ListPrivAction act, void *actPriv)
91 {
92     ListNode *node;
93 
94     for (node = listNodeFirst(head); node != head; node = node->next) {
95         act(node, actPriv);
96     }
97 }
98 
99 void
listDoForEachPrivSafe(const ListHead * head,ListPrivAction act,void * actPriv)100 listDoForEachPrivSafe(const ListHead *head, ListPrivAction act, void *actPriv)
101 {
102     ListNode *node, *save;
103 
104     for (node = listNodeFirst(head), save = node->next; node != head;
105          node = save, save = node->next) {
106 
107         act(node, actPriv);
108     }
109 }
110 
111 ListNode
listNodeSearch(const ListHead * head,const void * key,ListCmpFn cmp)112 *listNodeSearch(const ListHead *head, const void *key, ListCmpFn cmp)
113 {
114     ListNode *node;
115 
116     for (node = listNodeFirst(head); node != head; node = node->next) {
117         if (!cmp(node, key)) {
118             break;
119         }
120     }
121 
122     return (node == head) ? NULL : node;
123 }
124 
125 size_t
listLength(const ListHead * head)126 listLength(const ListHead *head)
127 {
128     size_t length = 0;
129     ListNode *node;
130 
131     for (node= listNodeFirst(head); node != head; node = node->next) {
132         length++;
133     }
134 
135     return length;
136 }
137