Motr  M0
list.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2020 Seagate Technology LLC and/or its Affiliates
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  * For any questions about this software or licensing,
17  * please email opensource@seagate.com or cortx-questions@seagate.com.
18  *
19  */
20 
21 
22 #define M0_TRACE_SUBSYSTEM M0_TRACE_SUBSYS_LIB
23 #include "lib/trace.h"
24 #include "lib/assert.h"
25 #include "lib/list.h"
26 
29 M0_INTERNAL void m0_list_init(struct m0_list *head)
30 {
31  head->l_head = (struct m0_list_link *)head;
32  head->l_tail = (struct m0_list_link *)head;
33 }
34 M0_EXPORTED(m0_list_init);
35 
36 M0_INTERNAL void m0_list_fini(struct m0_list *head)
37 {
39 }
40 M0_EXPORTED(m0_list_fini);
41 
42 M0_INTERNAL bool m0_list_is_empty(const struct m0_list *head)
43 {
44  return head->l_head == (void *)head;
45 }
46 M0_EXPORTED(m0_list_is_empty);
47 
48 M0_INTERNAL bool m0_list_link_invariant(const struct m0_list_link *link)
49 {
50  struct m0_list_link *scan;
51 
52  if ((link->ll_next == link) != (link->ll_prev == link)) {
53  M0_LOG(M0_FATAL, "%p <- %p -> %p",
54  link->ll_prev, link, link->ll_next);
55  return false;
56  }
57 
58  for (scan = link->ll_next; scan != link; scan = scan->ll_next) {
59  if (scan->ll_next->ll_prev != scan ||
60  scan->ll_prev->ll_next != scan) {
61  M0_LOG(M0_FATAL, "%p -> %p <- %p -> %p <- %p",
62  scan->ll_prev->ll_next, scan->ll_prev,
63  scan, scan->ll_next, scan->ll_next->ll_prev);
64  return false;
65  }
66  }
67  return true;
68 }
69 
70 M0_INTERNAL bool m0_list_invariant(const struct m0_list *head)
71 {
72  return m0_list_link_invariant((void *)head);
73 }
74 
75 M0_INTERNAL size_t m0_list_length(const struct m0_list *list)
76 {
77  size_t length;
78  struct m0_list_link *scan;
79 
81  length = 0;
82  for (scan = list->l_head; scan != (void *)list; scan = scan->ll_next)
83  length++;
84  return length;
85 }
86 
87 M0_INTERNAL bool m0_list_contains(const struct m0_list *list,
88  const struct m0_list_link *link)
89 {
90  struct m0_list_link *scan;
91 
93  for (scan = list->l_head; scan != (void *)list; scan = scan->ll_next)
94  if (scan == link)
95  return true;
96  return false;
97 }
98 
99 static inline void __m0_list_add(struct m0_list_link *prev,
100  struct m0_list_link *next,
101  struct m0_list_link *new)
102 {
103  M0_ASSERT(prev->ll_next == next && next->ll_prev == prev);
105  new->ll_next = next;
106  new->ll_prev = prev;
107 
108  next->ll_prev = new;
109  prev->ll_next = new;
111 }
112 
113 M0_INTERNAL void m0_list_add(struct m0_list *head, struct m0_list_link *new)
114 {
115  __m0_list_add((void *)head, head->l_head, new);
116 }
117 M0_EXPORTED(m0_list_add);
118 
119 M0_INTERNAL void m0_list_add_tail(struct m0_list *head,
120  struct m0_list_link *new)
121 {
122  __m0_list_add(head->l_tail, (void *)head, new);
123 }
124 M0_EXPORTED(m0_list_add_tail);
125 
126 M0_INTERNAL void m0_list_add_after(struct m0_list_link *anchor,
127  struct m0_list_link *new)
128 {
129  __m0_list_add(anchor, anchor->ll_next, new);
130 }
131 M0_EXPORTED(m0_list_add_after);
132 
133 M0_INTERNAL void m0_list_add_before(struct m0_list_link *anchor,
134  struct m0_list_link *new)
135 {
136  __m0_list_add(anchor->ll_prev, anchor, new);
137 }
138 M0_EXPORTED(m0_list_add_before);
139 
140 static void __m0_list_del(struct m0_list_link *old)
141 {
143  old->ll_prev->ll_next = old->ll_next;
144  old->ll_next->ll_prev = old->ll_prev;
145 }
146 
147 M0_INTERNAL void m0_list_del(struct m0_list_link *old)
148 {
149  __m0_list_del(old);
150  m0_list_link_init(old);
151 }
152 M0_EXPORTED(m0_list_del);
153 
154 M0_INTERNAL void m0_list_move(struct m0_list *head, struct m0_list_link *old)
155 {
156  __m0_list_del(old);
157  m0_list_add(head, old);
159 }
160 
161 M0_INTERNAL void m0_list_move_tail(struct m0_list *head,
162  struct m0_list_link *old)
163 {
164  __m0_list_del(old);
165  m0_list_add_tail(head, old);
167 }
168 
169 M0_INTERNAL void m0_list_link_init(struct m0_list_link *link)
170 {
171  link->ll_prev = link;
172  link->ll_next = link;
173 }
174 M0_EXPORTED(m0_list_link_init);
175 
176 M0_INTERNAL void m0_list_link_fini(struct m0_list_link *link)
177 {
179 }
180 
181 M0_INTERNAL bool m0_list_link_is_in(const struct m0_list_link *link)
182 {
183  return link->ll_prev != link;
184 }
185 
186 M0_INTERNAL bool m0_list_link_is_last(const struct m0_list_link *link,
187  const struct m0_list *head)
188 {
189  return link->ll_next == (void *)head;
190 }
191 
192 #undef M0_TRACE_SUBSYSTEM
193 
196 /*
197  * Local variables:
198  * c-indentation-style: "K&R"
199  * c-basic-offset: 8
200  * tab-width: 8
201  * fill-column: 80
202  * scroll-step: 1
203  * End:
204  */
M0_INTERNAL void m0_list_link_fini(struct m0_list_link *link)
Definition: list.c:176
M0_INTERNAL bool m0_list_invariant(const struct m0_list *head)
Definition: list.c:70
M0_INTERNAL void m0_list_add(struct m0_list *head, struct m0_list_link *new)
Definition: list.c:113
static struct m0_list list
Definition: list.c:144
M0_INTERNAL void m0_list_add_before(struct m0_list_link *anchor, struct m0_list_link *new)
Definition: list.c:133
static void __m0_list_add(struct m0_list_link *prev, struct m0_list_link *next, struct m0_list_link *new)
Definition: list.c:99
M0_INTERNAL void m0_list_init(struct m0_list *head)
Definition: list.c:29
#define M0_LOG(level,...)
Definition: trace.h:167
M0_INTERNAL void m0_list_fini(struct m0_list *head)
Definition: list.c:36
M0_INTERNAL void m0_list_del(struct m0_list_link *old)
Definition: list.c:147
static int head(struct m0_sm *mach)
Definition: sm.c:468
#define M0_ASSERT_EX(cond)
M0_INTERNAL size_t m0_list_length(const struct m0_list *list)
Definition: list.c:75
struct m0_list_link * l_head
Definition: list.h:76
#define M0_ASSERT(cond)
static int next[]
Definition: cp.c:248
M0_INTERNAL bool m0_list_contains(const struct m0_list *list, const struct m0_list_link *link)
Definition: list.c:87
static void __m0_list_del(struct m0_list_link *old)
Definition: list.c:140
M0_INTERNAL bool m0_list_is_empty(const struct m0_list *head)
Definition: list.c:42
M0_INTERNAL bool m0_list_link_is_in(const struct m0_list_link *link)
Definition: list.c:181
Definition: list.h:72
M0_INTERNAL bool m0_list_link_invariant(const struct m0_list_link *link)
Definition: list.c:48
M0_INTERNAL void m0_list_add_after(struct m0_list_link *anchor, struct m0_list_link *new)
Definition: list.c:126
M0_INTERNAL void m0_list_move(struct m0_list *head, struct m0_list_link *old)
Definition: list.c:154
M0_INTERNAL void m0_list_move_tail(struct m0_list *head, struct m0_list_link *old)
Definition: list.c:161
M0_INTERNAL bool m0_list_link_is_last(const struct m0_list_link *link, const struct m0_list *head)
Definition: list.c:186
M0_INTERNAL void m0_list_link_init(struct m0_list_link *link)
Definition: list.c:169
M0_INTERNAL void m0_list_add_tail(struct m0_list *head, struct m0_list_link *new)
Definition: list.c:119
static int scan(struct scanner *s)
Definition: beck.c:963