00001
00024 #ifndef _RTAI_SEM_H
00025 #define _RTAI_SEM_H
00026
00027 #include <rtai_types.h>
00028 #include <rtai_nam2num.h>
00029
00030 #define RT_SEM_MAGIC 0xaabcdeff
00031
00032 #define SEM_TIMOUT (0xFffe)
00033
00034 #define SEM_ERR (0xFfff)
00035
00036 #if defined(__KERNEL__) && !defined(__cplusplus)
00037
00038 #include <rtai_sched.h>
00039
00040 typedef struct rt_semaphore {
00041 struct rt_queue queue;
00042 int magic;
00043 int type;
00044 int count;
00045 struct rt_task_struct *owndby;
00046 int qtype;
00047 } SEM;
00048
00049 #else
00050
00051 typedef struct rt_semaphore {
00052 int opaque;
00053 } SEM;
00054
00055 #endif
00056
00057 typedef SEM CND;
00058
00059 #ifdef __KERNEL__
00060
00061 #include <linux/errno.h>
00062
00063 typedef SEM psem_t;
00064
00065 typedef SEM pmutex_t;
00066
00067 #ifdef __cplusplus
00068 extern "C" {
00069 #endif
00070
00071 int __rtai_sem_init(void);
00072
00073 void __rtai_sem_exit(void);
00074
00075 void rt_typed_sem_init(SEM *sem,
00076 int value,
00077 int type);
00078
00079 SEM *_rt_typed_named_sem_init(unsigned long sem_name,
00080 int value,
00081 int type);
00082
00083 static inline SEM *rt_typed_named_sem_init(const char *sem_name,
00084 int value,
00085 int type) {
00086 return _rt_typed_named_sem_init(nam2num(sem_name), value, type);
00087 }
00088
00089 void rt_sem_init(SEM *sem,
00090 int value);
00091
00092 int rt_sem_delete(SEM *sem);
00093
00094 int rt_sem_signal(SEM *sem);
00095
00096 int rt_sem_broadcast(SEM *sem);
00097
00098 int rt_sem_wait(SEM *sem);
00099
00100 int rt_sem_wait_if(SEM *sem);
00101
00102 int rt_cntsem_wait_if_and_lock(SEM *sem);
00103
00104 int rt_sem_wait_until(SEM *sem,
00105 RTIME time);
00106
00107 int rt_sem_wait_timed(SEM *sem,
00108 RTIME delay);
00109
00110 int rt_sem_wait_barrier(SEM *sem);
00111
00112 int rt_sem_count(SEM *sem);
00113
00114 int rt_cond_signal(CND *cnd);
00115
00116 int rt_cond_wait(CND *cnd,
00117 SEM *mtx);
00118
00119 int rt_cond_wait_until(CND *cnd,
00120 SEM *mtx,
00121 RTIME time);
00122
00123 int rt_cond_wait_timed(CND *cnd,
00124 SEM *mtx,
00125 RTIME delay);
00126
00127 #define rt_named_sem_init(sem_name, value) rt_typed_named_sem_init(sem_name, value, CNT_SEM)
00128
00129 int rt_named_sem_delete(SEM *sem);
00130
00131 static inline int rt_psem_init(psem_t *sem, int pshared, unsigned int value)
00132 {
00133 if (value < SEM_TIMOUT) {
00134 rt_typed_sem_init(sem, value, pshared | PRIO_Q);
00135 return 0;
00136 }
00137 return -EINVAL;
00138 }
00139
00140 static inline int rt_psem_destroy(psem_t *sem)
00141 {
00142 if (rt_sem_wait_if(sem) >= 0) {
00143 rt_sem_signal(sem);
00144 return rt_sem_delete(sem);
00145 }
00146 return -EBUSY;
00147 }
00148
00149 static inline int rt_psem_wait(psem_t *sem) {
00150 return rt_sem_wait(sem) < SEM_TIMOUT ? 0 : -1;
00151 }
00152
00153 static inline int rt_psem_timedwait(psem_t *sem, struct timespec *abstime) {
00154 return rt_sem_wait_until(sem, timespec2count(abstime)) < SEM_TIMOUT ? 0 : -1;
00155 }
00156
00157 static inline int rt_psem_trywait(psem_t *sem) {
00158 return rt_sem_wait_if(sem) > 0 ? 0 : -EAGAIN;
00159 }
00160
00161 static inline int rt_psem_post(psem_t *sem) {
00162 return rt_sem_signal(sem);
00163 }
00164
00165 static inline int rt_psem_getvalue(psem_t *sem, int *sval)
00166 {
00167 if ((*sval = rt_sem_wait_if(sem)) > 0) {
00168 rt_sem_signal(sem);
00169 }
00170 return 0;
00171 }
00172
00173 static inline int rt_pmutex_init(pmutex_t *mutex, void *mutexattr)
00174 {
00175 rt_typed_sem_init(mutex, 1, RES_SEM);
00176 return 0;
00177 }
00178
00179 static inline int rt_pmutex_destroy(pmutex_t *mutex)
00180 {
00181 if (rt_sem_wait_if(mutex) > 0) {
00182 rt_sem_signal(mutex);
00183 return rt_sem_delete(mutex);
00184 }
00185 return -EBUSY;
00186 }
00187
00188 static inline int rt_pmutex_lock(pmutex_t *mutex) {
00189 return rt_sem_wait(mutex) < SEM_TIMOUT ? 0 : -EINVAL;
00190 }
00191
00192 static inline int rt_pmutex_trylock(pmutex_t *mutex) {
00193 return rt_sem_wait_if(mutex) > 0 ? 0 : -EBUSY;
00194 }
00195
00196 static inline int rt_pmutex_timedlock(pmutex_t *sem, struct timespec *abstime) {
00197 return rt_sem_wait_until(sem, timespec2count(abstime)) < SEM_TIMOUT ? 0 : -1;
00198 }
00199
00200 static inline int rt_pmutex_unlock(pmutex_t *mutex) {
00201 return rt_sem_signal(mutex);
00202 }
00203
00204 #define rt_mutex_init(mtx) rt_typed_sem_init(mtx, 1, RES_SEM)
00205 #define rt_mutex_delete(mtx) rt_sem_delete(mtx)
00206 #define rt_mutex_destroy(mtx) rt_sem_delete(mtx)
00207 #define rt_mutex_trylock(mtx) rt_sem_wait_if(mtx)
00208 #define rt_mutex_lock(mtx) rt_sem_wait(mtx)
00209 #define rt_mutex_timedlock(mtx, time) rt_sem_wait_until(mtx, time)
00210 #define rt_mutex_unlock(mtx) rt_sem_signal(mtx)
00211
00212 #define rt_cond_init(cnd) rt_typed_sem_init(cnd, 0, BIN_SEM | PRIO_Q)
00213 #define rt_cond_delete(cnd) rt_sem_delete(cnd)
00214 #define rt_cond_destroy(cnd) rt_sem_delete(cnd)
00215 #define rt_cond_broadcast(cnd) rt_sem_broadcast(cnd)
00216
00217 static inline int rt_cond_timedwait(CND *cnd, SEM *mtx, RTIME time) {
00218 return rt_cond_wait_until(cnd, mtx, time) < SEM_TIMOUT ? 0 : -1;
00219 }
00220
00221 #ifdef __cplusplus
00222 }
00223 #endif
00224
00225 #else
00226
00227 #include <rtai_lxrt.h>
00228
00229 #ifdef __cplusplus
00230 extern "C" {
00231 #endif
00232
00233 RTAI_PROTO(SEM *, rt_typed_sem_init,(int name, int value, int type))
00234 {
00235 struct { int name, value, type; } arg = { name, value, type };
00236 return (SEM *)rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).v[LOW];
00237 }
00238
00256 #define rt_sem_init(name, value) rt_typed_sem_init(name, value, CNT_SEM)
00257
00258 #define rt_named_sem_init(sem_name, value) \
00259 rt_typed_named_sem_init(sem_name, value, CNT_SEM)
00260
00261 RTAI_PROTO(int, rt_sem_delete,(SEM *sem))
00262 {
00263 struct { SEM *sem; } arg = { sem };
00264 return rtai_lxrt(BIDX, SIZARG, LXRT_SEM_DELETE, &arg).i[LOW];
00265 }
00266
00267 RTAI_PROTO(SEM *, rt_typed_named_sem_init,(const char *name, int value, int type))
00268 {
00269 struct { unsigned long name; int value, type; } arg = { nam2num(name), value, type };
00270 return (SEM *)rtai_lxrt(BIDX, SIZARG, NAMED_SEM_INIT, &arg).v[LOW];
00271 }
00272
00273 RTAI_PROTO(int, rt_named_sem_delete,(SEM *sem))
00274 {
00275 struct { SEM *sem; } arg = { sem };
00276 return rtai_lxrt(BIDX, SIZARG, NAMED_SEM_DELETE, &arg).i[LOW];
00277 }
00278
00279 RTAI_PROTO(int, rt_sem_signal,(SEM *sem))
00280 {
00281 struct { SEM *sem; } arg = { sem };
00282 return rtai_lxrt(BIDX, SIZARG, SEM_SIGNAL, &arg).i[LOW];
00283 }
00284
00285 RTAI_PROTO(int, rt_sem_broadcast,(SEM *sem))
00286 {
00287 struct { SEM *sem; } arg = { sem };
00288 return rtai_lxrt(BIDX, SIZARG, SEM_BROADCAST, &arg).i[LOW];
00289 }
00290
00291 RTAI_PROTO(int, rt_sem_wait,(SEM *sem))
00292 {
00293 struct { SEM *sem; } arg = { sem };
00294 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT, &arg).i[LOW];
00295 }
00296
00297 RTAI_PROTO(int, rt_sem_wait_if,(SEM *sem))
00298 {
00299 struct { SEM *sem; } arg = { sem };
00300 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT_IF, &arg).i[LOW];
00301 }
00302
00303 RTAI_PROTO(int, rt_sem_wait_until,(SEM *sem, RTIME time))
00304 {
00305 struct { SEM *sem; RTIME time; } arg = { sem, time };
00306 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT_UNTIL, &arg).i[LOW];
00307 }
00308
00309 RTAI_PROTO(int, rt_sem_wait_timed,(SEM *sem, RTIME delay))
00310 {
00311 struct { SEM *sem; RTIME delay; } arg = { sem, delay };
00312 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT_TIMED, &arg).i[LOW];
00313 }
00314
00315 RTAI_PROTO(int, rt_sem_wait_barrier,(SEM *sem))
00316 {
00317 struct { SEM *sem; } arg = { sem };
00318 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT_BARRIER, &arg).i[LOW];
00319 }
00320
00321 RTAI_PROTO(int, rt_sem_count,(SEM *sem))
00322 {
00323 struct { SEM *sem; } arg = { sem };
00324 return rtai_lxrt(BIDX, SIZARG, SEM_COUNT, &arg).i[LOW];
00325 }
00326
00342 #define rt_cond_init(name) rt_typed_sem_init(name, 0, BIN_SEM)
00343 #define rt_cond_delete(cnd) rt_sem_delete(cnd)
00344 #define rt_cond_destroy(cnd) rt_sem_delete(cnd)
00345 #define rt_cond_broadcast(cnd) rt_sem_broadcast(cnd)
00346 #define rt_cond_timedwait(cnd, mtx, time) rt_cond_wait_until(cnd, mtx, time)
00347
00348 RTAI_PROTO(int, rt_cond_signal,(CND *cnd))
00349 {
00350 struct { CND *cnd; } arg = { cnd };
00351 return rtai_lxrt(BIDX, SIZARG, COND_SIGNAL, &arg).i[LOW];
00352 }
00353
00354 RTAI_PROTO(int, rt_cond_wait,(CND *cnd, SEM *mutex))
00355 {
00356 struct { CND *cnd; SEM *mutex; } arg = { cnd, mutex };
00357 return rtai_lxrt(BIDX, SIZARG, COND_WAIT, &arg).i[LOW];
00358 }
00359
00360 RTAI_PROTO(int, rt_cond_wait_until,(CND *cnd, SEM *mutex, RTIME time))
00361 {
00362 struct { CND *cnd; SEM *mutex; RTIME time; } arg = { cnd, mutex, time };
00363 return rtai_lxrt(BIDX, SIZARG, COND_WAIT_UNTIL, &arg).i[LOW];
00364 }
00365
00366 RTAI_PROTO(int, rt_cond_wait_timed,(CND *cnd, SEM *mutex, RTIME delay))
00367 {
00368 struct { CND *cnd; SEM *mutex; RTIME delay; } arg = { cnd, mutex, delay };
00369 return rtai_lxrt(BIDX, SIZARG, COND_WAIT_TIMED, &arg).i[LOW];
00370 }
00371
00372 #ifdef __cplusplus
00373 }
00374 #endif
00375
00376 #endif
00377
00378 #endif