00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046 #ifndef _xenomai_mutex_h
00047 #define _xenomai_mutex_h
00048
00049 #include <xenomai/pod.h>
00050 #include <xenomai/synch.h>
00051
00052 struct xnthread;
00053
00054 typedef struct xnmutex {
00055
00056 xnsynch_t synchbase;
00057
00058 atomic_counter_t lockcnt;
00059
00060 } xnmutex_t;
00061
00062 #ifdef __cplusplus
00063 extern "C" {
00064 #endif
00065
00066 void xnmutex_forget_sleeper(struct xnthread *sleeper);
00067
00068 void xnmutex_sleepon_inner(xnmutex_t *mutex,
00069 struct xnthread *thread);
00070
00071 void xnmutex_wakeup_inner(xnmutex_t *mutex,
00072 int flags);
00073
00074 static inline int xnmutex_owner_p (xnmutex_t *mutex) {
00075
00076
00077
00078 return (xnarch_atomic_get(&mutex->lockcnt) < 1 &&
00079 mutex->synchbase.owner == nkpod->sched.runthread);
00080 }
00081
00082 static inline int xnmutex_clear_lock (xnmutex_t *mutex,
00083 atomic_counter_t *pcounter) {
00084
00085
00086
00087 int s = 0;
00088
00089 if (xnmutex_owner_p(mutex)) {
00090 *pcounter = mutex->lockcnt;
00091 if (xnsynch_nsleepers(&mutex->synchbase) > 0) {
00092
00093
00094 xnarch_atomic_inc(pcounter);
00095 xnarch_atomic_set(&mutex->lockcnt,0);
00096
00097 xnmutex_wakeup_inner(mutex,XNPOD_NOSWITCH);
00098 s = -1;
00099 } else {
00100 xnarch_atomic_set(&mutex->lockcnt,1);
00101 s = 1;
00102 }
00103 }
00104
00105 return s;
00106 }
00107
00108 static inline void xnmutex_set_lock (xnmutex_t *mutex,
00109 atomic_counter_t *pcounter) {
00110
00111 xnthread_t *runthread = nkpod->sched.runthread;
00112
00113
00114
00115 if (xnarch_atomic_dec_and_test(&mutex->lockcnt)) {
00116
00117 xnsynch_set_owner(&mutex->synchbase,runthread);
00118 } else {
00119 if (xnsynch_owner(&mutex->synchbase) != runthread) {
00120
00121 xnmutex_sleepon_inner(mutex,runthread);
00122 }
00123 }
00124
00125
00126 if (xnsynch_nsleepers(&mutex->synchbase) > 0)
00127 xnarch_atomic_dec(pcounter);
00128
00129 xnarch_atomic_set(&mutex->lockcnt,xnarch_atomic_get(pcounter));
00130 }
00131
00132
00133
00134 void xnmutex_init(xnmutex_t *mutex);
00135
00136 static inline void xnmutex_lock (xnmutex_t *mutex) {
00137
00138 xnthread_t *runthread = nkpod->sched.runthread;
00139 spl_t s;
00140
00141 splhigh(s);
00142
00143 if (xnarch_atomic_dec_and_test(&mutex->lockcnt)) {
00144
00145 xnsynch_set_owner(&mutex->synchbase,runthread);
00146 } else {
00147 if (xnsynch_owner(&mutex->synchbase) != runthread) {
00148
00149 xnmutex_sleepon_inner(mutex,runthread);
00150 }
00151 }
00152
00153 splexit(s);
00154 }
00155
00156 static inline void xnmutex_unlock (xnmutex_t *mutex) {
00157
00158 if (xnarch_atomic_inc_and_test(&mutex->lockcnt)) {
00159 if (xnsynch_nsleepers(&mutex->synchbase) > 0) {
00160
00161 xnmutex_wakeup_inner(mutex,0);
00162 }
00163 }
00164 }
00165
00166 #ifdef __cplusplus
00167 }
00168 #endif
00169
00170 #endif