19 #ifndef _COPPERPLATE_SYNCOBJ_H 20 #define _COPPERPLATE_SYNCOBJ_H 24 #include <boilerplate/list.h> 25 #include <boilerplate/lock.h> 26 #include <copperplate/reference.h> 29 #define SYNCOBJ_FIFO 0x0 30 #define SYNCOBJ_PRIO 0x1 31 #define SYNCOBJ_LOCKED 0x2 34 #define SYNCOBJ_FLUSHED 0x1 35 #define SYNCOBJ_SIGNALED 0x2 36 #define SYNCOBJ_DRAINWAIT 0x4 38 #define SYNCOBJ_MAGIC 0xf9f99f9f 46 #ifdef CONFIG_XENO_COBALT 48 #include <boilerplate/atomic.h> 49 #include <cobalt/uapi/monitor.h> 51 struct syncobj_corespec {
52 cobalt_monitor_t monitor;
57 struct syncobj_corespec {
59 pthread_cond_t drain_sync;
68 struct listobj grant_list;
70 struct listobj drain_list;
72 struct syncobj_corespec core;
73 fnref_type(
void (*)(
struct syncobj *sobj)) finalizer;
76 #define syncobj_for_each_grant_waiter(sobj, pos) \ 77 list_for_each_entry(pos, &(sobj)->grant_list, wait_link) 79 #define syncobj_for_each_grant_waiter_safe(sobj, pos, tmp) \ 80 list_for_each_entry_safe(pos, tmp, &(sobj)->grant_list, wait_link) 82 #define syncobj_for_each_drain_waiter(sobj, pos) \ 83 list_for_each_entry(pos, &(sobj)->drain_list, wait_link) 85 #define syncobj_for_each_drain_waiter_safe(sobj, pos, tmp) \ 86 list_for_each_entry_safe(pos, tmp, &(sobj)->drain_list, wait_link) 88 void __syncobj_cleanup_wait(
struct syncobj *sobj,
89 struct threadobj *thobj);
91 #ifdef CONFIG_XENO_DEBUG 93 static inline void __syncobj_tag_locked(
struct syncobj *sobj)
95 sobj->flags |= SYNCOBJ_LOCKED;
98 static inline void __syncobj_tag_unlocked(
struct syncobj *sobj)
100 assert(sobj->flags & SYNCOBJ_LOCKED);
101 sobj->flags &= ~SYNCOBJ_LOCKED;
104 static inline void __syncobj_check_locked(
struct syncobj *sobj)
106 assert(sobj->flags & SYNCOBJ_LOCKED);
111 static inline void __syncobj_tag_locked(
struct syncobj *sobj)
115 static inline void __syncobj_tag_unlocked(
struct syncobj *sobj)
119 static inline void __syncobj_check_locked(
struct syncobj *sobj)
129 int __syncobj_broadcast_drain(
struct syncobj *sobj,
int reason);
131 int __syncobj_broadcast_grant(
struct syncobj *sobj,
int reason);
133 int syncobj_init(
struct syncobj *sobj, clockid_t clk_id,
int flags,
134 fnref_type(
void (*)(
struct syncobj *sobj)) finalizer) __must_check;
136 int syncobj_wait_grant(
struct syncobj *sobj,
137 const struct timespec *timeout,
138 struct syncstate *syns) __must_check;
140 struct threadobj *syncobj_grant_one(
struct syncobj *sobj);
142 void syncobj_grant_to(
struct syncobj *sobj,
143 struct threadobj *thobj);
145 struct threadobj *syncobj_peek_grant(
struct syncobj *sobj);
147 struct threadobj *syncobj_peek_drain(
struct syncobj *sobj);
149 int syncobj_lock(
struct syncobj *sobj,
150 struct syncstate *syns) __must_check;
152 void syncobj_unlock(
struct syncobj *sobj,
153 struct syncstate *syns);
155 int syncobj_wait_drain(
struct syncobj *sobj,
156 const struct timespec *timeout,
157 struct syncstate *syns) __must_check;
159 int syncobj_destroy(
struct syncobj *sobj,
160 struct syncstate *syns);
162 void syncobj_uninit(
struct syncobj *sobj);
164 static inline int syncobj_grant_wait_p(
struct syncobj *sobj)
166 __syncobj_check_locked(sobj);
168 return !list_empty(&sobj->grant_list);
171 static inline int syncobj_count_grant(
struct syncobj *sobj)
173 __syncobj_check_locked(sobj);
175 return sobj->grant_count;
178 static inline int syncobj_count_drain(
struct syncobj *sobj)
180 __syncobj_check_locked(sobj);
182 return sobj->drain_count;
185 static inline int syncobj_drain_wait_p(
struct syncobj *sobj)
187 __syncobj_check_locked(sobj);
189 return !list_empty(&sobj->drain_list);
192 static inline int syncobj_drain(
struct syncobj *sobj)
196 __syncobj_check_locked(sobj);
198 if (sobj->drain_count > 0)
199 ret = __syncobj_broadcast_drain(sobj, SYNCOBJ_SIGNALED);
204 static inline int syncobj_grant_all(
struct syncobj *sobj)
208 __syncobj_check_locked(sobj);
210 if (sobj->grant_count > 0)
211 ret = __syncobj_broadcast_grant(sobj, SYNCOBJ_SIGNALED);
216 static inline int syncobj_flush(
struct syncobj *sobj)
218 __syncobj_check_locked(sobj);
220 if (sobj->grant_count > 0)
221 __syncobj_broadcast_grant(sobj, SYNCOBJ_FLUSHED);
223 if (sobj->drain_count > 0)
224 __syncobj_broadcast_drain(sobj, SYNCOBJ_FLUSHED);
226 return sobj->wait_count;