Xenomai API
2.5.6.1
|
00001 /* 00002 * @note Copyright (C) 2001,2002,2003 Philippe Gerum <[email protected]>. 00003 * 00004 * Xenomai is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU General Public License as published 00006 * by the Free Software Foundation; either version 2 of the License, 00007 * or (at your option) any later version. 00008 * 00009 * Xenomai is distributed in the hope that it will be useful, but 00010 * WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU General Public License 00015 * along with Xenomai; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 00017 * 02111-1307, USA. 00018 * 00019 * \ingroup synch 00020 */ 00021 00022 #ifndef _XENO_NUCLEUS_SYNCH_H 00023 #define _XENO_NUCLEUS_SYNCH_H 00024 00025 #include <nucleus/queue.h> 00026 00027 /* Creation flags */ 00028 #define XNSYNCH_FIFO 0x0 00029 #define XNSYNCH_PRIO 0x1 00030 #define XNSYNCH_NOPIP 0x0 00031 #define XNSYNCH_PIP 0x2 00032 #define XNSYNCH_DREORD 0x4 00033 #define XNSYNCH_OWNER 0x8 00034 00035 #ifndef CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX 00036 #define CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX 0 00037 #endif /* CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX */ 00038 00039 #ifdef CONFIG_XENO_FASTSYNCH 00040 00041 /* Fast lock API */ 00042 static inline int xnsynch_fast_owner_check(xnarch_atomic_t *fastlock, 00043 xnhandle_t ownerh) 00044 { 00045 return (xnhandle_mask_spare(xnarch_atomic_get(fastlock)) == ownerh) ? 00046 0 : -EPERM; 00047 } 00048 00049 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock, 00050 xnhandle_t new_ownerh) 00051 { 00052 xnhandle_t lock_state = 00053 xnarch_atomic_cmpxchg(fastlock, XN_NO_HANDLE, new_ownerh); 00054 00055 if (likely(lock_state == XN_NO_HANDLE)) 00056 return 0; 00057 00058 if (xnhandle_mask_spare(lock_state) == new_ownerh) 00059 return -EBUSY; 00060 00061 return -EAGAIN; 00062 } 00063 00064 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock, 00065 xnhandle_t cur_ownerh) 00066 { 00067 return (xnarch_atomic_cmpxchg(fastlock, cur_ownerh, XN_NO_HANDLE) == 00068 cur_ownerh); 00069 } 00070 00071 #else /* !CONFIG_XENO_FASTSYNCH */ 00072 00073 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock, 00074 xnhandle_t new_ownerh) 00075 { 00076 return -ENOSYS; 00077 } 00078 00079 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock, 00080 xnhandle_t cur_ownerh) 00081 { 00082 return -1; 00083 } 00084 00085 #endif /* !CONFIG_XENO_FASTSYNCH */ 00086 00087 #if defined(__KERNEL__) || defined(__XENO_SIM__) 00088 00089 #define XNSYNCH_CLAIMED 0x10 /* Claimed by other thread(s) w/ PIP */ 00090 00091 #define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3 /* Corresponding bit in fast lock */ 00092 00093 /* Spare flags usable by upper interfaces */ 00094 #define XNSYNCH_SPARE0 0x01000000 00095 #define XNSYNCH_SPARE1 0x02000000 00096 #define XNSYNCH_SPARE2 0x04000000 00097 #define XNSYNCH_SPARE3 0x08000000 00098 #define XNSYNCH_SPARE4 0x10000000 00099 #define XNSYNCH_SPARE5 0x20000000 00100 #define XNSYNCH_SPARE6 0x40000000 00101 #define XNSYNCH_SPARE7 0x80000000 00102 00103 /* Statuses */ 00104 #define XNSYNCH_DONE 0 /* Resource available / operation complete */ 00105 #define XNSYNCH_WAIT 1 /* Calling thread blocked -- start rescheduling */ 00106 #define XNSYNCH_RESCHED 2 /* Force rescheduling */ 00107 00108 struct xnthread; 00109 struct xnsynch; 00110 struct xnmutex; 00111 00112 typedef struct xnsynch { 00113 00114 xnpholder_t link; /* Link in claim queues */ 00115 00116 #define link2synch(ln) container_of(ln, struct xnsynch, link) 00117 00118 xnflags_t status; /* Status word */ 00119 00120 xnpqueue_t pendq; /* Pending threads */ 00121 00122 struct xnthread *owner; /* Thread which owns the resource */ 00123 00124 #ifdef CONFIG_XENO_FASTSYNCH 00125 xnarch_atomic_t *fastlock; /* Pointer to fast lock word */ 00126 #endif /* CONFIG_XENO_FASTSYNCH */ 00127 00128 void (*cleanup)(struct xnsynch *synch); /* Cleanup handler */ 00129 00130 XNARCH_DECL_DISPLAY_CONTEXT(); 00131 00132 } xnsynch_t; 00133 00134 #define xnsynch_test_flags(synch,flags) testbits((synch)->status,flags) 00135 #define xnsynch_set_flags(synch,flags) setbits((synch)->status,flags) 00136 #define xnsynch_clear_flags(synch,flags) clrbits((synch)->status,flags) 00137 #define xnsynch_wait_queue(synch) (&((synch)->pendq)) 00138 #define xnsynch_nsleepers(synch) countpq(&((synch)->pendq)) 00139 #define xnsynch_pended_p(synch) (!emptypq_p(&((synch)->pendq))) 00140 #define xnsynch_owner(synch) ((synch)->owner) 00141 00142 #ifdef CONFIG_XENO_FASTSYNCH 00143 #define xnsynch_fastlock(synch) ((synch)->fastlock) 00144 #define xnsynch_fastlock_p(synch) ((synch)->fastlock != NULL) 00145 #define xnsynch_owner_check(synch, thread) \ 00146 xnsynch_fast_owner_check((synch)->fastlock, xnthread_handle(thread)) 00147 #else /* !CONFIG_XENO_FASTSYNCH */ 00148 #define xnsynch_fastlock(synch) ((xnarch_atomic_t *)NULL) 00149 #define xnsynch_fastlock_p(synch) 0 00150 #define xnsynch_owner_check(synch, thread) \ 00151 ((synch)->owner == thread ? 0 : -EPERM) 00152 #endif /* !CONFIG_XENO_FASTSYNCH */ 00153 00154 #define xnsynch_fast_is_claimed(fastlock) \ 00155 xnhandle_test_spare(fastlock, XNSYNCH_FLCLAIM) 00156 #define xnsynch_fast_set_claimed(fastlock, enable) \ 00157 (((fastlock) & ~XNSYNCH_FLCLAIM) | ((enable) ? XNSYNCH_FLCLAIM : 0)) 00158 #define xnsynch_fast_mask_claimed(fastlock) ((fastlock) & ~XNSYNCH_FLCLAIM) 00159 00160 #ifdef __cplusplus 00161 extern "C" { 00162 #endif 00163 00164 #if XENO_DEBUG(SYNCH_RELAX) 00165 00166 void xnsynch_detect_relaxed_owner(struct xnsynch *synch, 00167 struct xnthread *sleeper); 00168 00169 void xnsynch_detect_claimed_relax(struct xnthread *owner); 00170 00171 #else /* !XENO_DEBUG(SYNCH_RELAX) */ 00172 00173 static inline void xnsynch_detect_relaxed_owner(struct xnsynch *synch, 00174 struct xnthread *sleeper) 00175 { 00176 } 00177 00178 static inline void xnsynch_detect_claimed_relax(struct xnthread *owner) 00179 { 00180 } 00181 00182 #endif /* !XENO_DEBUG(SYNCH_RELAX) */ 00183 00184 void xnsynch_init(struct xnsynch *synch, xnflags_t flags, 00185 xnarch_atomic_t *fastlock); 00186 00187 #define xnsynch_destroy(synch) xnsynch_flush(synch, XNRMID) 00188 00189 static inline void xnsynch_set_owner(struct xnsynch *synch, 00190 struct xnthread *thread) 00191 { 00192 synch->owner = thread; 00193 } 00194 00195 static inline void xnsynch_register_cleanup(struct xnsynch *synch, 00196 void (*handler)(struct xnsynch *)) 00197 { 00198 synch->cleanup = handler; 00199 } 00200 00201 xnflags_t xnsynch_sleep_on(struct xnsynch *synch, 00202 xnticks_t timeout, 00203 xntmode_t timeout_mode); 00204 00205 struct xnthread *xnsynch_wakeup_one_sleeper(struct xnsynch *synch); 00206 00207 xnpholder_t *xnsynch_wakeup_this_sleeper(struct xnsynch *synch, 00208 xnpholder_t *holder); 00209 00210 xnflags_t xnsynch_acquire(struct xnsynch *synch, 00211 xnticks_t timeout, 00212 xntmode_t timeout_mode); 00213 00214 struct xnthread *xnsynch_release(struct xnsynch *synch); 00215 00216 struct xnthread *xnsynch_peek_pendq(struct xnsynch *synch); 00217 00218 int xnsynch_flush(struct xnsynch *synch, xnflags_t reason); 00219 00220 void xnsynch_release_all_ownerships(struct xnthread *thread); 00221 00222 void xnsynch_requeue_sleeper(struct xnthread *thread); 00223 00224 void xnsynch_forget_sleeper(struct xnthread *thread); 00225 00226 #ifdef __cplusplus 00227 } 00228 #endif 00229 00230 #endif /* __KERNEL__ || __XENO_SIM__ */ 00231 00232 #endif /* !_XENO_NUCLEUS_SYNCH_H_ */