Motr  M0
queue.c
Go to the documentation of this file.
1 /* -*- C -*- */
2 /*
3  * Copyright (c) 2011-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 #include "lib/queue.h"
24 #include "lib/assert.h"
25 #include "lib/misc.h" /* NULL */
26 
46 #define EOQ ((struct m0_queue_link *)8)
47 
48 const struct m0_queue M0_QUEUE_INIT = {
49  .q_head = EOQ,
50  .q_tail = EOQ
51 };
52 
53 M0_INTERNAL void m0_queue_init(struct m0_queue *q)
54 {
55  q->q_head = q->q_tail = EOQ;
57 }
58 
59 M0_INTERNAL void m0_queue_fini(struct m0_queue *q)
60 {
63 }
64 
65 M0_INTERNAL bool m0_queue_is_empty(const struct m0_queue *q)
66 {
68  return q->q_head == EOQ;
69 }
70 
71 M0_INTERNAL void m0_queue_link_init(struct m0_queue_link *ql)
72 {
73  ql->ql_next = NULL;
74 }
75 
76 M0_INTERNAL void m0_queue_link_fini(struct m0_queue_link *ql)
77 {
79 }
80 
81 M0_INTERNAL bool m0_queue_link_is_in(const struct m0_queue_link *ql)
82 {
83  return ql->ql_next != NULL;
84 }
85 
86 M0_INTERNAL bool m0_queue_contains(const struct m0_queue *q,
87  const struct m0_queue_link *ql)
88 {
89  struct m0_queue_link *scan;
90 
92  for (scan = q->q_head; scan != EOQ; scan = scan->ql_next) {
93  M0_ASSERT(scan != NULL);
94  if (scan == ql)
95  return true;
96  }
97  return false;
98 }
99 
100 M0_INTERNAL size_t m0_queue_length(const struct m0_queue *q)
101 {
102  size_t length;
103  struct m0_queue_link *scan;
104 
106 
107  for (length = 0, scan = q->q_head; scan != EOQ; scan = scan->ql_next)
108  ++length;
109  return length;
110 }
111 
112 M0_INTERNAL struct m0_queue_link *m0_queue_get(struct m0_queue *q)
113 {
114  struct m0_queue_link *head;
115 
116  /* invariant is checked on entry to m0_queue_is_empty() */
117  if (m0_queue_is_empty(q))
118  head = NULL;
119  else {
120  head = q->q_head;
121  q->q_head = head->ql_next;
122  if (q->q_head == EOQ)
123  q->q_tail = EOQ;
124  head->ql_next = NULL;
125  }
127  return head;
128 
129 }
130 
131 M0_INTERNAL void m0_queue_put(struct m0_queue *q, struct m0_queue_link *ql)
132 {
133  /* invariant is checked on entry to m0_queue_is_empty() */
134  if (m0_queue_is_empty(q))
135  q->q_head = ql;
136  else
137  q->q_tail->ql_next = ql;
138  q->q_tail = ql;
139  ql->ql_next = EOQ;
141 }
142 
143 M0_INTERNAL bool m0_queue_invariant(const struct m0_queue *q)
144 {
145  struct m0_queue_link *scan;
146 
147  if ((q->q_head == EOQ) != (q->q_tail == EOQ))
148  return false;
149  if (q->q_head == NULL || q->q_tail == NULL)
150  return false;
151 
152  for (scan = q->q_head; scan != EOQ; scan = scan->ql_next) {
153  if (scan == NULL || scan == EOQ)
154  return false;
155  }
156  if (q->q_head != EOQ && q->q_tail->ql_next != EOQ)
157  return false;
158  return true;
159 }
160 
163 /*
164  * Local variables:
165  * c-indentation-style: "K&R"
166  * c-basic-offset: 8
167  * tab-width: 8
168  * fill-column: 80
169  * scroll-step: 1
170  * End:
171  */
static struct m0_semaphore q
Definition: rwlock.c:55
#define NULL
Definition: misc.h:38
Definition: queue.h:43
M0_INTERNAL bool m0_queue_is_empty(const struct m0_queue *q)
Definition: queue.c:65
static int head(struct m0_sm *mach)
Definition: sm.c:468
#define M0_ASSERT_EX(cond)
M0_INTERNAL void m0_queue_link_fini(struct m0_queue_link *ql)
Definition: queue.c:76
#define M0_ASSERT(cond)
M0_INTERNAL void m0_queue_link_init(struct m0_queue_link *ql)
Definition: queue.c:71
const struct m0_queue M0_QUEUE_INIT
Definition: queue.c:48
M0_INTERNAL bool m0_queue_contains(const struct m0_queue *q, const struct m0_queue_link *ql)
Definition: queue.c:86
M0_INTERNAL struct m0_queue_link * m0_queue_get(struct m0_queue *q)
Definition: queue.c:112
struct m0_queue_link * q_head
Definition: queue.h:45
M0_INTERNAL void m0_queue_put(struct m0_queue *q, struct m0_queue_link *ql)
Definition: queue.c:131
M0_INTERNAL size_t m0_queue_length(const struct m0_queue *q)
Definition: queue.c:100
M0_INTERNAL void m0_queue_init(struct m0_queue *q)
Definition: queue.c:53
M0_INTERNAL bool m0_queue_invariant(const struct m0_queue *q)
Definition: queue.c:143
M0_INTERNAL void m0_queue_fini(struct m0_queue *q)
Definition: queue.c:59
static int scan(struct scanner *s)
Definition: beck.c:963
#define EOQ
Definition: queue.c:46
M0_INTERNAL bool m0_queue_link_is_in(const struct m0_queue_link *ql)
Definition: queue.c:81