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>
51struct syncobj_corespec {
52 cobalt_monitor_t monitor;
57struct 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)
88void __syncobj_cleanup_wait(
struct syncobj *sobj,
89 struct threadobj *thobj);
91#ifdef CONFIG_XENO_DEBUG
93static inline void __syncobj_tag_locked(
struct syncobj *sobj)
95 sobj->flags |= SYNCOBJ_LOCKED;
98static inline void __syncobj_tag_unlocked(
struct syncobj *sobj)
100 assert(sobj->flags & SYNCOBJ_LOCKED);
101 sobj->flags &= ~SYNCOBJ_LOCKED;
104static inline void __syncobj_check_locked(
struct syncobj *sobj)
106 assert(sobj->flags & SYNCOBJ_LOCKED);
111static inline void __syncobj_tag_locked(
struct syncobj *sobj)
115static inline void __syncobj_tag_unlocked(
struct syncobj *sobj)
119static inline void __syncobj_check_locked(
struct syncobj *sobj)
129int __syncobj_broadcast_drain(
struct syncobj *sobj,
int reason);
131int __syncobj_broadcast_grant(
struct syncobj *sobj,
int reason);
133int syncobj_init(
struct syncobj *sobj, clockid_t clk_id,
int flags,
134 fnref_type(
void (*)(
struct syncobj *sobj)) finalizer) __must_check;
136int syncobj_wait_grant(
struct syncobj *sobj,
137 const struct timespec *timeout,
138 struct syncstate *syns) __must_check;
140struct threadobj *syncobj_grant_one(
struct syncobj *sobj);
142void syncobj_grant_to(
struct syncobj *sobj,
143 struct threadobj *thobj);
145struct threadobj *syncobj_peek_grant(
struct syncobj *sobj);
147struct threadobj *syncobj_peek_drain(
struct syncobj *sobj);
149int syncobj_lock(
struct syncobj *sobj,
150 struct syncstate *syns) __must_check;
152void syncobj_unlock(
struct syncobj *sobj,
153 struct syncstate *syns);
155int syncobj_wait_drain(
struct syncobj *sobj,
156 const struct timespec *timeout,
157 struct syncstate *syns) __must_check;
159int syncobj_destroy(
struct syncobj *sobj,
160 struct syncstate *syns);
162void syncobj_uninit(
struct syncobj *sobj);
164static inline int syncobj_grant_wait_p(
struct syncobj *sobj)
166 __syncobj_check_locked(sobj);
168 return !list_empty(&sobj->grant_list);
171static inline int syncobj_count_grant(
struct syncobj *sobj)
173 __syncobj_check_locked(sobj);
175 return sobj->grant_count;
178static inline int syncobj_count_drain(
struct syncobj *sobj)
180 __syncobj_check_locked(sobj);
182 return sobj->drain_count;
185static inline int syncobj_drain_wait_p(
struct syncobj *sobj)
187 __syncobj_check_locked(sobj);
189 return !list_empty(&sobj->drain_list);
192static 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);
204static 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);
216static 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;