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 #ifndef CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX
00036 #define CONFIG_XENO_OPT_DEBUG_SYNCH_RELAX 0
00037 #endif
00038
00039 #ifdef CONFIG_XENO_FASTSYNCH
00040
00041
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
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
00086
00087 #if defined(__KERNEL__) || defined(__XENO_SIM__)
00088
00089 #define XNSYNCH_CLAIMED 0x10
00090
00091 #define XNSYNCH_FLCLAIM XN_HANDLE_SPARE3
00092
00093
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
00104 #define XNSYNCH_DONE 0
00105 #define XNSYNCH_WAIT 1
00106 #define XNSYNCH_RESCHED 2
00107
00108 struct xnthread;
00109 struct xnsynch;
00110 struct xnmutex;
00111
00112 typedef struct xnsynch {
00113
00114 xnpholder_t link;
00115
00116 #define link2synch(ln) container_of(ln, struct xnsynch, link)
00117
00118 xnflags_t status;
00119
00120 xnpqueue_t pendq;
00121
00122 struct xnthread *owner;
00123
00124 #ifdef CONFIG_XENO_FASTSYNCH
00125 xnarch_atomic_t *fastlock;
00126 #endif
00127
00128 void (*cleanup)(struct xnsynch *synch);
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
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
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
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
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
00231
00232 #endif