Xenomai API  2.6.5
synch.h
1 /*
2  * @note Copyright (C) 2001,2002,2003 Philippe Gerum <[email protected]>.
3  *
4  * Xenomai is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published
6  * by the Free Software Foundation; either version 2 of the License,
7  * or (at your option) any later version.
8  *
9  * Xenomai is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with Xenomai; if not, write to the Free Software
16  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
17  * 02111-1307, USA.
18  *
19  * \ingroup synch
20  */
21 
22 #ifndef _XENO_NUCLEUS_SYNCH_H
23 #define _XENO_NUCLEUS_SYNCH_H
24 
25 #include <nucleus/queue.h>
26 
27 /* Creation flags */
28 #define XNSYNCH_FIFO 0x0
29 #define XNSYNCH_PRIO 0x1
30 #define XNSYNCH_NOPIP 0x0
31 #define XNSYNCH_PIP 0x2
32 #define XNSYNCH_DREORD 0x4
33 #define XNSYNCH_OWNER 0x8
34 
35 #ifndef CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX
36 #define CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX 0
37 #endif /* CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX */
38 
39 #ifdef CONFIG_XENO_FASTSYNCH
40 
41 /* Fast lock API */
42 static inline int xnsynch_fast_owner_check(xnarch_atomic_t *fastlock,
43  xnhandle_t ownerh)
44 {
45  return (xnhandle_mask_spare(xnarch_atomic_get(fastlock)) == ownerh) ?
46  0 : -EPERM;
47 }
48 
49 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock,
50  xnhandle_t new_ownerh)
51 {
52  xnhandle_t lock_state =
53  xnarch_atomic_cmpxchg(fastlock, XN_NO_HANDLE, new_ownerh);
54 
55  if (likely(lock_state == XN_NO_HANDLE))
56  return 0;
57 
58  if (xnhandle_mask_spare(lock_state) == new_ownerh)
59  return -EBUSY;
60 
61  return -EAGAIN;
62 }
63 
64 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock,
65  xnhandle_t cur_ownerh)
66 {
67  return (xnarch_atomic_cmpxchg(fastlock, cur_ownerh, XN_NO_HANDLE) ==
68  cur_ownerh);
69 }
70 
71 #else /* !CONFIG_XENO_FASTSYNCH */
72 
73 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock,
74  xnhandle_t new_ownerh)
75 {
76  return -ENOSYS;
77 }
78 
79 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock,
80  xnhandle_t cur_ownerh)
81 {
82  return -1;
83 }
84 
85 #endif /* !CONFIG_XENO_FASTSYNCH */
86 
87 #if defined(__KERNEL__) || defined(__XENO_SIM__)
88 
89 #define XNSYNCH_CLAIMED 0x10 /* Claimed by other thread(s) w/ PIP */
90 
91 #define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3 /* Corresponding bit in fast lock */
92 
93 /* Spare flags usable by upper interfaces */
94 #define XNSYNCH_SPARE0 0x01000000
95 #define XNSYNCH_SPARE1 0x02000000
96 #define XNSYNCH_SPARE2 0x04000000
97 #define XNSYNCH_SPARE3 0x08000000
98 #define XNSYNCH_SPARE4 0x10000000
99 #define XNSYNCH_SPARE5 0x20000000
100 #define XNSYNCH_SPARE6 0x40000000
101 #define XNSYNCH_SPARE7 0x80000000
102 
103 /* Statuses */
104 #define XNSYNCH_DONE 0 /* Resource available / operation complete */
105 #define XNSYNCH_WAIT 1 /* Calling thread blocked -- start rescheduling */
106 #define XNSYNCH_RESCHED 2 /* Force rescheduling */
107 
108 struct xnthread;
109 struct xnsynch;
110 struct xnmutex;
111 
112 typedef struct xnsynch {
113 
114  xnpholder_t link; /* Link in claim queues */
115 
116 #define link2synch(ln) container_of(ln, struct xnsynch, link)
117 
118  xnflags_t status; /* Status word */
119 
120  xnpqueue_t pendq; /* Pending threads */
121 
122  struct xnthread *owner; /* Thread which owns the resource */
123 
124 #ifdef CONFIG_XENO_FASTSYNCH
125  xnarch_atomic_t *fastlock; /* Pointer to fast lock word */
126 #endif /* CONFIG_XENO_FASTSYNCH */
127 
128  void (*cleanup)(struct xnsynch *synch); /* Cleanup handler */
129 
130  XNARCH_DECL_DISPLAY_CONTEXT();
131 
132 } xnsynch_t;
133 
134 #define xnsynch_test_flags(synch,flags) testbits((synch)->status,flags)
135 #define xnsynch_set_flags(synch,flags) setbits((synch)->status,flags)
136 #define xnsynch_clear_flags(synch,flags) clrbits((synch)->status,flags)
137 #define xnsynch_wait_queue(synch) (&((synch)->pendq))
138 #define xnsynch_nsleepers(synch) countpq(&((synch)->pendq))
139 #define xnsynch_pended_p(synch) (!emptypq_p(&((synch)->pendq)))
140 #define xnsynch_owner(synch) ((synch)->owner)
141 
142 #ifdef CONFIG_XENO_FASTSYNCH
143 #define xnsynch_fastlock(synch) ((synch)->fastlock)
144 #define xnsynch_fastlock_p(synch) ((synch)->fastlock != NULL)
145 #define xnsynch_owner_check(synch, thread) \
146  xnsynch_fast_owner_check((synch)->fastlock, xnthread_handle(thread))
147 #else /* !CONFIG_XENO_FASTSYNCH */
148 #define xnsynch_fastlock(synch) ((xnarch_atomic_t *)NULL)
149 #define xnsynch_fastlock_p(synch) 0
150 #define xnsynch_owner_check(synch, thread) \
151  ((synch)->owner == thread ? 0 : -EPERM)
152 #endif /* !CONFIG_XENO_FASTSYNCH */
153 
154 #define xnsynch_fast_is_claimed(fastlock) \
155  xnhandle_test_spare(fastlock, XNSYNCH_FLCLAIM)
156 #define xnsynch_fast_set_claimed(fastlock, enable) \
157  (((fastlock) & ~XNSYNCH_FLCLAIM) | ((enable) ? XNSYNCH_FLCLAIM : 0))
158 #define xnsynch_fast_mask_claimed(fastlock) ((fastlock) & ~XNSYNCH_FLCLAIM)
159 
160 #ifdef __cplusplus
161 extern "C" {
162 #endif
163 
164 #if XENO_DEBUG(SYNCH_RELAX)
165 
166 void xnsynch_detect_relaxed_owner(struct xnsynch *synch,
167  struct xnthread *sleeper);
168 
169 void xnsynch_detect_claimed_relax(struct xnthread *owner);
170 
171 #else /* !XENO_DEBUG(SYNCH_RELAX) */
172 
173 static inline void xnsynch_detect_relaxed_owner(struct xnsynch *synch,
174  struct xnthread *sleeper)
175 {
176 }
177 
178 static inline void xnsynch_detect_claimed_relax(struct xnthread *owner)
179 {
180 }
181 
182 #endif /* !XENO_DEBUG(SYNCH_RELAX) */
183 
184 void xnsynch_init(struct xnsynch *synch, xnflags_t flags,
185  xnarch_atomic_t *fastlock);
186 
187 #define xnsynch_destroy(synch) xnsynch_flush(synch, XNRMID)
188 
189 static inline void xnsynch_set_owner(struct xnsynch *synch,
190  struct xnthread *thread)
191 {
192  synch->owner = thread;
193 }
194 
195 static inline void xnsynch_register_cleanup(struct xnsynch *synch,
196  void (*handler)(struct xnsynch *))
197 {
198  synch->cleanup = handler;
199 }
200 
201 xnflags_t xnsynch_sleep_on(struct xnsynch *synch,
202  xnticks_t timeout,
203  xntmode_t timeout_mode);
204 
205 struct xnthread *xnsynch_wakeup_one_sleeper(struct xnsynch *synch);
206 
207 xnpholder_t *xnsynch_wakeup_this_sleeper(struct xnsynch *synch,
208  xnpholder_t *holder);
209 
210 xnflags_t xnsynch_acquire(struct xnsynch *synch,
211  xnticks_t timeout,
212  xntmode_t timeout_mode);
213 
214 struct xnthread *xnsynch_release(struct xnsynch *synch);
215 
216 struct xnthread *xnsynch_peek_pendq(struct xnsynch *synch);
217 
218 int xnsynch_flush(struct xnsynch *synch, xnflags_t reason);
219 
220 void xnsynch_release_all_ownerships(struct xnthread *thread);
221 
222 void xnsynch_requeue_sleeper(struct xnthread *thread);
223 
224 void xnsynch_forget_sleeper(struct xnthread *thread);
225 
226 #ifdef __cplusplus
227 }
228 #endif
229 
230 #endif /* __KERNEL__ || __XENO_SIM__ */
231 
232 #endif /* !_XENO_NUCLEUS_SYNCH_H_ */
struct xnthread * xnsynch_wakeup_one_sleeper(struct xnsynch *synch)
Give the resource ownership to the next waiting thread.
Definition: synch.c:237
xnflags_t xnsynch_sleep_on(struct xnsynch *synch, xnticks_t timeout, xntmode_t timeout_mode)
Sleep on an ownerless synchronization object.
Definition: synch.c:171
void xnsynch_release_all_ownerships(struct xnthread *thread)
Release all ownerships.
Definition: synch.c:981
void xnsynch_forget_sleeper(struct xnthread *thread)
Abort a wait for a resource.
Definition: synch.c:921
void xnsynch_init(struct xnsynch *synch, xnflags_t flags, xnarch_atomic_t *fastlock)
Initialize a synchronization object.
Definition: synch.c:102
xnflags_t xnsynch_acquire(struct xnsynch *synch, xnticks_t timeout, xntmode_t timeout_mode)
Acquire the ownership of a synchronization object.
Definition: synch.c:406
struct xnthread * xnsynch_peek_pendq(struct xnsynch *synch)
Access the thread leading a synch object wait queue.
Definition: synch.c:803
xnpholder_t * xnsynch_wakeup_this_sleeper(struct xnsynch *synch, xnpholder_t *holder)
Give the resource ownership to a given waiting thread.
Definition: synch.c:309
struct xnthread * xnsynch_release(struct xnsynch *synch)
Give the resource ownership to the next waiting thread.
Definition: synch.c:775
int xnsynch_flush(struct xnsynch *synch, xnflags_t reason)
Unblock all waiters pending on a resource.
Definition: synch.c:869
void xnsynch_requeue_sleeper(struct xnthread *thread)
Change a sleeper's priority.
Definition: synch.c:629