00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #ifndef _XENO_NUCLEUS_SYNCH_H
00023 #define _XENO_NUCLEUS_SYNCH_H
00024
00025 #include <nucleus/queue.h>
00026
00027
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 #ifdef CONFIG_XENO_FASTSYNCH
00036
00037
00038 static inline int xnsynch_fast_owner_check(xnarch_atomic_t *fastlock,
00039 xnhandle_t ownerh)
00040 {
00041 return (xnhandle_mask_spare(xnarch_atomic_get(fastlock)) == ownerh) ?
00042 0 : -EPERM;
00043 }
00044
00045 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock,
00046 xnhandle_t new_ownerh)
00047 {
00048 xnhandle_t lock_state =
00049 xnarch_atomic_cmpxchg(fastlock, XN_NO_HANDLE, new_ownerh);
00050
00051 if (likely(lock_state == XN_NO_HANDLE))
00052 return 0;
00053
00054 if (xnhandle_mask_spare(lock_state) == new_ownerh)
00055 return -EBUSY;
00056
00057 return -EAGAIN;
00058 }
00059
00060 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock,
00061 xnhandle_t cur_ownerh)
00062 {
00063 return (xnarch_atomic_cmpxchg(fastlock, cur_ownerh, XN_NO_HANDLE) ==
00064 cur_ownerh);
00065 }
00066
00067 #else
00068
00069 static inline int xnsynch_fast_acquire(xnarch_atomic_t *fastlock,
00070 xnhandle_t new_ownerh)
00071 {
00072 return -ENOSYS;
00073 }
00074
00075 static inline int xnsynch_fast_release(xnarch_atomic_t *fastlock,
00076 xnhandle_t cur_ownerh)
00077 {
00078 return -1;
00079 }
00080
00081 #endif
00082
00083 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00084
00085 #define XNSYNCH_CLAIMED 0x10
00086
00087 #define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3
00088
00089
00090 #define XNSYNCH_SPARE0 0x01000000
00091 #define XNSYNCH_SPARE1 0x02000000
00092 #define XNSYNCH_SPARE2 0x04000000
00093 #define XNSYNCH_SPARE3 0x08000000
00094 #define XNSYNCH_SPARE4 0x10000000
00095 #define XNSYNCH_SPARE5 0x20000000
00096 #define XNSYNCH_SPARE6 0x40000000
00097 #define XNSYNCH_SPARE7 0x80000000
00098
00099
00100 #define XNSYNCH_DONE 0
00101 #define XNSYNCH_WAIT 1
00102 #define XNSYNCH_RESCHED 2
00103
00104 struct xnthread;
00105 struct xnsynch;
00106 struct xnmutex;
00107
00108 typedef struct xnsynch {
00109
00110 xnpholder_t link;
00111
00112 #define link2synch(ln) container_of(ln, struct xnsynch, link)
00113
00114 xnflags_t status;
00115
00116 xnpqueue_t pendq;
00117
00118 struct xnthread *owner;
00119
00120 #ifdef CONFIG_XENO_FASTSYNCH
00121 xnarch_atomic_t *fastlock;
00122 #endif
00123
00124 void (*cleanup)(struct xnsynch *synch);
00125
00126 XNARCH_DECL_DISPLAY_CONTEXT();
00127
00128 } xnsynch_t;
00129
00130 #define xnsynch_test_flags(synch,flags) testbits((synch)->status,flags)
00131 #define xnsynch_set_flags(synch,flags) setbits((synch)->status,flags)
00132 #define xnsynch_clear_flags(synch,flags) clrbits((synch)->status,flags)
00133 #define xnsynch_wait_queue(synch) (&((synch)->pendq))
00134 #define xnsynch_nsleepers(synch) countpq(&((synch)->pendq))
00135 #define xnsynch_pended_p(synch) (!emptypq_p(&((synch)->pendq)))
00136 #define xnsynch_owner(synch) ((synch)->owner)
00137
00138 #ifdef CONFIG_XENO_FASTSYNCH
00139 #define xnsynch_fastlock(synch) ((synch)->fastlock)
00140 #define xnsynch_fastlock_p(synch) ((synch)->fastlock != NULL)
00141 #define xnsynch_owner_check(synch, thread) \
00142 xnsynch_fast_owner_check((synch)->fastlock, xnthread_handle(thread))
00143 #else
00144 #define xnsynch_fastlock(synch) ((xnarch_atomic_t *)NULL)
00145 #define xnsynch_fastlock_p(synch) 0
00146 #define xnsynch_owner_check(synch, thread) \
00147 ((synch)->owner == thread ? 0 : -EPERM)
00148 #endif
00149
00150 #define xnsynch_fast_is_claimed(fastlock) \
00151 xnhandle_test_spare(fastlock, XNSYNCH_FLCLAIM)
00152 #define xnsynch_fast_set_claimed(fastlock, enable) \
00153 (((fastlock) & ~XNSYNCH_FLCLAIM) | ((enable) ? XNSYNCH_FLCLAIM : 0))
00154 #define xnsynch_fast_mask_claimed(fastlock) ((fastlock) & ~XNSYNCH_FLCLAIM)
00155
00156 #ifdef __cplusplus
00157 extern "C" {
00158 #endif
00159
00160 #ifdef CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX
00161
00162 void xnsynch_detect_relaxed_owner(struct xnsynch *synch,
00163 struct xnthread *sleeper);
00164
00165 void xnsynch_detect_claimed_relax(struct xnthread *owner);
00166
00167 #else
00168
00169 static inline void xnsynch_detect_relaxed_owner(struct xnsynch *synch,
00170 struct xnthread *sleeper)
00171 {
00172 }
00173
00174 static inline void xnsynch_detect_claimed_relax(struct xnthread *owner)
00175 {
00176 }
00177
00178 #endif
00179
00180 void xnsynch_init(struct xnsynch *synch, xnflags_t flags,
00181 xnarch_atomic_t *fastlock);
00182
00183 #define xnsynch_destroy(synch) xnsynch_flush(synch, XNRMID)
00184
00185 static inline void xnsynch_set_owner(struct xnsynch *synch,
00186 struct xnthread *thread)
00187 {
00188 synch->owner = thread;
00189 }
00190
00191 static inline void xnsynch_register_cleanup(struct xnsynch *synch,
00192 void (*handler)(struct xnsynch *))
00193 {
00194 synch->cleanup = handler;
00195 }
00196
00197 xnflags_t xnsynch_sleep_on(struct xnsynch *synch,
00198 xnticks_t timeout,
00199 xntmode_t timeout_mode);
00200
00201 struct xnthread *xnsynch_wakeup_one_sleeper(struct xnsynch *synch);
00202
00203 xnpholder_t *xnsynch_wakeup_this_sleeper(struct xnsynch *synch,
00204 xnpholder_t *holder);
00205
00206 xnflags_t xnsynch_acquire(struct xnsynch *synch,
00207 xnticks_t timeout,
00208 xntmode_t timeout_mode);
00209
00210 struct xnthread *xnsynch_release(struct xnsynch *synch);
00211
00212 struct xnthread *xnsynch_peek_pendq(struct xnsynch *synch);
00213
00214 int xnsynch_flush(struct xnsynch *synch, xnflags_t reason);
00215
00216 void xnsynch_release_all_ownerships(struct xnthread *thread);
00217
00218 void xnsynch_requeue_sleeper(struct xnthread *thread);
00219
00220 void xnsynch_forget_sleeper(struct xnthread *thread);
00221
00222 #ifdef __cplusplus
00223 }
00224 #endif
00225
00226 #endif
00227
00228 #endif