# rtai_sem.h

Go to the documentation of this file.

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