Xenomai 3.3.2
Loading...
Searching...
No Matches
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
40struct threadobj;
41
42struct syncstate {
43 int state;
44};
45
46#ifdef CONFIG_XENO_COBALT
47
48#include <boilerplate/atomic.h>
49#include <cobalt/uapi/monitor.h>
50
51struct syncobj_corespec {
52 cobalt_monitor_t monitor;
53};
54
55#else /* CONFIG_XENO_MERCURY */
56
57struct syncobj_corespec {
58 pthread_mutex_t lock;
59 pthread_cond_t drain_sync;
60};
61
62#endif /* CONFIG_XENO_MERCURY */
63
64struct 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
88void __syncobj_cleanup_wait(struct syncobj *sobj,
89 struct threadobj *thobj);
90
91#ifdef CONFIG_XENO_DEBUG
92
93static inline void __syncobj_tag_locked(struct syncobj *sobj)
94{
95 sobj->flags |= SYNCOBJ_LOCKED;
96}
97
98static inline void __syncobj_tag_unlocked(struct syncobj *sobj)
99{
100 assert(sobj->flags & SYNCOBJ_LOCKED);
101 sobj->flags &= ~SYNCOBJ_LOCKED;
102}
103
104static inline void __syncobj_check_locked(struct syncobj *sobj)
105{
106 assert(sobj->flags & SYNCOBJ_LOCKED);
107}
108
109#else /* !CONFIG_XENO_DEBUG */
110
111static inline void __syncobj_tag_locked(struct syncobj *sobj)
112{
113}
114
115static inline void __syncobj_tag_unlocked(struct syncobj *sobj)
116{
117}
118
119static inline void __syncobj_check_locked(struct syncobj *sobj)
120{
121}
122
123#endif /* !CONFIG_XENO_DEBUG */
124
125#ifdef __cplusplus
126extern "C" {
127#endif
128
129int __syncobj_broadcast_drain(struct syncobj *sobj, int reason);
130
131int __syncobj_broadcast_grant(struct syncobj *sobj, int reason);
132
133int syncobj_init(struct syncobj *sobj, clockid_t clk_id, int flags,
134 fnref_type(void (*)(struct syncobj *sobj)) finalizer) __must_check;
135
136int syncobj_wait_grant(struct syncobj *sobj,
137 const struct timespec *timeout,
138 struct syncstate *syns) __must_check;
139
140struct threadobj *syncobj_grant_one(struct syncobj *sobj);
141
142void syncobj_grant_to(struct syncobj *sobj,
143 struct threadobj *thobj);
144
145struct threadobj *syncobj_peek_grant(struct syncobj *sobj);
146
147struct threadobj *syncobj_peek_drain(struct syncobj *sobj);
148
149int syncobj_lock(struct syncobj *sobj,
150 struct syncstate *syns) __must_check;
151
152void syncobj_unlock(struct syncobj *sobj,
153 struct syncstate *syns);
154
155int syncobj_wait_drain(struct syncobj *sobj,
156 const struct timespec *timeout,
157 struct syncstate *syns) __must_check;
158
159int syncobj_destroy(struct syncobj *sobj,
160 struct syncstate *syns);
161
162void syncobj_uninit(struct syncobj *sobj);
163
164static 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
171static inline int syncobj_count_grant(struct syncobj *sobj)
172{
173 __syncobj_check_locked(sobj);
174
175 return sobj->grant_count;
176}
177
178static inline int syncobj_count_drain(struct syncobj *sobj)
179{
180 __syncobj_check_locked(sobj);
181
182 return sobj->drain_count;
183}
184
185static 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
192static 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
204static 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
216static 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 */