Xenomai API  2.5.6.1
include/nucleus/synch.h
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_ */
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines