Motr  M0
list.h
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2012-2020 Seagate Technology LLC and/or its Affiliates
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  * For any questions about this software or licensing,
18  * please email opensource@seagate.com or cortx-questions@seagate.com.
19  *
20  */
21 
22 
23 #pragma once
24 
25 #ifndef __MOTR_LIB_LIST_H__
26 #define __MOTR_LIB_LIST_H__
27 
28 #include "lib/misc.h" /* offsetof */
29 
39 struct m0_list_link {
48 } M0_XCA_RECORD M0_XCA_DOMAIN(be);
49 
58 M0_INTERNAL void m0_list_link_init(struct m0_list_link *link);
59 
65 M0_INTERNAL void m0_list_link_fini(struct m0_list_link *link);
66 
67 M0_INTERNAL bool m0_list_link_invariant(const struct m0_list_link *link);
68 
72 struct m0_list {
81 } M0_XCA_RECORD M0_XCA_DOMAIN(be);
82 
83 /*
84  It is necessary that m0_list and m0_list_link structures have exactly the
85  same layout as.
86  */
87 
89  offsetof(struct m0_list_link, ll_next));
91  offsetof(struct m0_list_link, ll_prev));
92 
96 M0_INTERNAL void m0_list_init(struct m0_list *head);
97 
101 M0_INTERNAL void m0_list_fini(struct m0_list *head);
102 
108 M0_INTERNAL bool m0_list_is_empty(const struct m0_list *head);
109 
113 M0_INTERNAL bool m0_list_contains(const struct m0_list *list,
114  const struct m0_list_link *link);
115 
122 M0_INTERNAL bool m0_list_invariant(const struct m0_list *list);
123 
124 M0_INTERNAL size_t m0_list_length(const struct m0_list *list);
125 
136 M0_INTERNAL void m0_list_add(struct m0_list *head, struct m0_list_link *next);
137 
147 M0_INTERNAL void m0_list_add_tail(struct m0_list *head,
148  struct m0_list_link *next);
149 
156 M0_INTERNAL void m0_list_add_after(struct m0_list_link *anchor,
157  struct m0_list_link *next);
158 
165 M0_INTERNAL void m0_list_add_before(struct m0_list_link *anchor,
166  struct m0_list_link *next);
167 
171 M0_INTERNAL void m0_list_del(struct m0_list_link *old);
172 
176 M0_INTERNAL void m0_list_move(struct m0_list *head, struct m0_list_link *next);
177 
181 M0_INTERNAL void m0_list_move_tail(struct m0_list *head,
182  struct m0_list_link *next);
183 
191 static inline struct m0_list_link *m0_list_first(const struct m0_list *head)
192 {
193  return head->l_head !=
194  (struct m0_list_link *)head ?
195  head->l_head : (struct m0_list_link *)NULL;
196 }
197 
198 
207 M0_INTERNAL bool m0_list_link_is_in(const struct m0_list_link *link);
208 
209 M0_INTERNAL bool m0_list_link_is_last(const struct m0_list_link *link,
210  const struct m0_list *head);
211 
212 M0_INTERNAL size_t m0_list_length(const struct m0_list *list);
213 
217 #define m0_list_entry(link, type, member) \
218  container_of(link, type, member)
219 
226 #define m0_list_for_each(head, pos) \
227  for (pos = (head)->l_head; pos != (void *)(head); \
228  pos = (pos)->ll_next)
229 
235 #define m0_list_for_each_entry(head, pos, type, member) \
236  for (pos = m0_list_entry((head)->l_head, type, member); \
237  &(pos->member) != (void *)head; \
238  pos = m0_list_entry((pos)->member.ll_next, type, member))
239 
247 #define m0_list_for_each_entry_safe(head, pos, next, type, member) \
248  for (pos = m0_list_entry((head)->l_head, type, member), \
249  next = m0_list_entry((pos)->member.ll_next, type, member); \
250  &(pos)->member != (void *)head; \
251  pos = next, \
252  next = m0_list_entry((next)->member.ll_next, type, member))
253 
279 #define m0_list_forall(var, head, ...) \
280 ({ \
281  struct m0_list_link *var; \
282  \
283  m0_list_for_each(head, var) { \
284  if (!({ __VA_ARGS__ ; })) \
285  break; \
286  } \
287  var == (void *)head; \
288 })
289 
313 #define m0_list_entry_forall(var, head, type, member, ...) \
314 ({ \
315  type *var; \
316  type *next; \
317  \
318  m0_list_for_each_entry_safe(head, var, next, type, member) { \
319  if (!({ __VA_ARGS__ ; })) \
320  break; \
321  } \
322  &var->member == (void *)head; \
323 })
324 
334 #define m0_list_teardown(head, pos, type, member) \
335  while (!m0_list_is_empty((head)) && \
336  ((pos) = m0_list_entry((head)->l_head, type, member)) && \
337  (m0_list_del(&(pos)->member), true))
338 
340 #endif /* __MOTR_LIB_LIST_H__ */
341 
342 /*
343  * Local variables:
344  * c-indentation-style: "K&R"
345  * c-basic-offset: 8
346  * tab-width: 8
347  * fill-column: 80
348  * scroll-step: 1
349  * End:
350  */
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 *list)
Definition: list.c:70
M0_INTERNAL void m0_list_add(struct m0_list *head, struct m0_list_link *next)
Definition: list.c:113
static struct m0_list list
Definition: list.c:144
#define NULL
Definition: misc.h:38
M0_INTERNAL void m0_list_add_before(struct m0_list_link *anchor, struct m0_list_link *next)
Definition: list.c:133
M0_INTERNAL void m0_list_init(struct m0_list *head)
Definition: list.c:29
struct m0_list_link * l_tail
Definition: list.h:80
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
enum m0_be_list_op M0_XCA_DOMAIN
struct m0_list_link * ll_prev
Definition: list.h:194
static int head(struct m0_sm *mach)
Definition: sm.c:468
struct m0_list_link * l_tail
Definition: list.h:75
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
struct m0_list_link * l_head
Definition: list.h:71
static int next[]
Definition: cp.c:248
struct m0_list_link * ll_next
Definition: list.h:190
M0_INTERNAL bool m0_list_contains(const struct m0_list *list, const struct m0_list_link *link)
Definition: list.c:87
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 *next)
Definition: list.c:126
M0_INTERNAL void m0_list_move(struct m0_list *head, struct m0_list_link *next)
Definition: list.c:154
M0_INTERNAL void m0_list_move_tail(struct m0_list *head, struct m0_list_link *next)
Definition: list.c:161
M0_BASSERT(offsetof(struct m0_list, l_head)==offsetof(struct m0_list_link, ll_next))
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
static struct m0_list_link * m0_list_first(const struct m0_list *head)
Definition: list.h:191
M0_INTERNAL void m0_list_add_tail(struct m0_list *head, struct m0_list_link *next)
Definition: list.c:119
#define offsetof(typ, memb)
Definition: misc.h:29
static struct m0_be_ut_backend be
Definition: service_ut.c:59