Xenomai  3.0.5
syncobj.h
1 /*
2  * Copyright (C) 2008 Philippe Gerum <rpm@xenomai.org>.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * Lesser General Public License for more details.
13 
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
17  */
18 
19 #ifndef _COPPERPLATE_SYNCOBJ_H
20 #define _COPPERPLATE_SYNCOBJ_H
21 
22 #include <pthread.h>
23 #include <time.h>
24 #include <boilerplate/list.h>
25 #include <boilerplate/lock.h>
26 #include <copperplate/reference.h>
27 
28 /* syncobj->flags */
29 #define SYNCOBJ_FIFO 0x0
30 #define SYNCOBJ_PRIO 0x1
31 #define SYNCOBJ_LOCKED 0x2
32 
33 /* threadobj->wait_status */
34 #define SYNCOBJ_FLUSHED 0x1
35 #define SYNCOBJ_SIGNALED 0x2
36 #define SYNCOBJ_DRAINWAIT 0x4
37 
38 #define SYNCOBJ_MAGIC 0xf9f99f9f
39 
40 struct threadobj;
41 
42 struct syncstate {
43  int state;
44 };
45 
46 #ifdef CONFIG_XENO_COBALT
47 
48 #include <boilerplate/atomic.h>
49 #include <cobalt/uapi/monitor.h>
50 
51 struct syncobj_corespec {
52  cobalt_monitor_t monitor;
53 };
54 
55 #else /* CONFIG_XENO_MERCURY */
56 
57 struct syncobj_corespec {
58  pthread_mutex_t lock;
59  pthread_cond_t drain_sync;
60 };
61 
62 #endif /* CONFIG_XENO_MERCURY */
63 
64 struct syncobj {
65  unsigned int magic;
66  int flags;
67  int wait_count;
68  struct listobj grant_list;
69  int grant_count;
70  struct listobj drain_list;
71  int drain_count;
72  struct syncobj_corespec core;
73  fnref_type(void (*)(struct syncobj *sobj)) finalizer;
74 };
75 
76 #define syncobj_for_each_grant_waiter(sobj, pos) \
77  list_for_each_entry(pos, &(sobj)->grant_list, wait_link)
78 
79 #define syncobj_for_each_grant_waiter_safe(sobj, pos, tmp) \
80  list_for_each_entry_safe(pos, tmp, &(sobj)->grant_list, wait_link)
81 
82 #define syncobj_for_each_drain_waiter(sobj, pos) \
83  list_for_each_entry(pos, &(sobj)->drain_list, wait_link)
84 
85 #define syncobj_for_each_drain_waiter_safe(sobj, pos, tmp) \
86  list_for_each_entry_safe(pos, tmp, &(sobj)->drain_list, wait_link)
87 
88 void __syncobj_cleanup_wait(struct syncobj *sobj,
89  struct threadobj *thobj);
90 
91 #ifdef CONFIG_XENO_DEBUG
92 
93 static inline void __syncobj_tag_locked(struct syncobj *sobj)
94 {
95  sobj->flags |= SYNCOBJ_LOCKED;
96 }
97 
98 static inline void __syncobj_tag_unlocked(struct syncobj *sobj)
99 {
100  assert(sobj->flags & SYNCOBJ_LOCKED);
101  sobj->flags &= ~SYNCOBJ_LOCKED;
102 }
103 
104 static inline void __syncobj_check_locked(struct syncobj *sobj)
105 {
106  assert(sobj->flags & SYNCOBJ_LOCKED);
107 }
108 
109 #else /* !CONFIG_XENO_DEBUG */
110 
111 static inline void __syncobj_tag_locked(struct syncobj *sobj)
112 {
113 }
114 
115 static inline void __syncobj_tag_unlocked(struct syncobj *sobj)
116 {
117 }
118 
119 static inline void __syncobj_check_locked(struct syncobj *sobj)
120 {
121 }
122 
123 #endif /* !CONFIG_XENO_DEBUG */
124 
125 #ifdef __cplusplus
126 extern "C" {
127 #endif
128 
129 int __syncobj_broadcast_drain(struct syncobj *sobj, int reason);
130 
131 int __syncobj_broadcast_grant(struct syncobj *sobj, int reason);
132 
133 int syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
134  fnref_type(void (*)(struct syncobj *sobj)) finalizer) __must_check;
135 
136 int syncobj_wait_grant(struct syncobj *sobj,
137  const struct timespec *timeout,
138  struct syncstate *syns) __must_check;
139 
140 struct threadobj *syncobj_grant_one(struct syncobj *sobj);
141 
142 void syncobj_grant_to(struct syncobj *sobj,
143  struct threadobj *thobj);
144 
145 struct threadobj *syncobj_peek_grant(struct syncobj *sobj);
146 
147 struct threadobj *syncobj_peek_drain(struct syncobj *sobj);
148 
149 int syncobj_lock(struct syncobj *sobj,
150  struct syncstate *syns) __must_check;
151 
152 void syncobj_unlock(struct syncobj *sobj,
153  struct syncstate *syns);
154 
155 int syncobj_wait_drain(struct syncobj *sobj,
156  const struct timespec *timeout,
157  struct syncstate *syns) __must_check;
158 
159 int syncobj_destroy(struct syncobj *sobj,
160  struct syncstate *syns);
161 
162 void syncobj_uninit(struct syncobj *sobj);
163 
164 static inline int syncobj_grant_wait_p(struct syncobj *sobj)
165 {
166  __syncobj_check_locked(sobj);
167 
168  return !list_empty(&sobj->grant_list);
169 }
170 
171 static inline int syncobj_count_grant(struct syncobj *sobj)
172 {
173  __syncobj_check_locked(sobj);
174 
175  return sobj->grant_count;
176 }
177 
178 static inline int syncobj_count_drain(struct syncobj *sobj)
179 {
180  __syncobj_check_locked(sobj);
181 
182  return sobj->drain_count;
183 }
184 
185 static inline int syncobj_drain_wait_p(struct syncobj *sobj)
186 {
187  __syncobj_check_locked(sobj);
188 
189  return !list_empty(&sobj->drain_list);
190 }
191 
192 static inline int syncobj_drain(struct syncobj *sobj)
193 {
194  int ret = 0;
195 
196  __syncobj_check_locked(sobj);
197 
198  if (sobj->drain_count > 0)
199  ret = __syncobj_broadcast_drain(sobj, SYNCOBJ_SIGNALED);
200 
201  return ret;
202 }
203 
204 static inline int syncobj_grant_all(struct syncobj *sobj)
205 {
206  int ret = 0;
207 
208  __syncobj_check_locked(sobj);
209 
210  if (sobj->grant_count > 0)
211  ret = __syncobj_broadcast_grant(sobj, SYNCOBJ_SIGNALED);
212 
213  return ret;
214 }
215 
216 static inline int syncobj_flush(struct syncobj *sobj)
217 {
218  __syncobj_check_locked(sobj);
219 
220  if (sobj->grant_count > 0)
221  __syncobj_broadcast_grant(sobj, SYNCOBJ_FLUSHED);
222 
223  if (sobj->drain_count > 0)
224  __syncobj_broadcast_drain(sobj, SYNCOBJ_FLUSHED);
225 
226  return sobj->wait_count;
227 }
228 
229 #ifdef __cplusplus
230 }
231 #endif
232 
233 #endif /* _COPPERPLATE_SYNCOBJ_H */