base/include/rtai_sem.h

Go to the documentation of this file.
00001 /** 00002 * @ingroup lxrt 00003 * @file 00004 * 00005 * @author Paolo Mantegazza 00006 * 00007 * @note Copyright &copy; 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it> 00008 * 00009 * This program is free software; you can redistribute it and/or 00010 * modify it under the terms of the GNU General Public License as 00011 * published by the Free Software Foundation; either version 2 of the 00012 * License, or (at your option) any later version. 00013 * 00014 * This program is distributed in the hope that it will be useful, 00015 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00017 * GNU General Public License for more details. 00018 * 00019 * You should have received a copy of the GNU General Public License 00020 * along with this program; if not, write to the Free Software 00021 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 00022 */ 00023 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 0x3f83ebb // nam2num("rtsem") 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,(unsigned long name, int value, int type)) 00233 { 00234 struct { unsigned long name; int value, type; } arg = { name, value, type }; 00235 return (SEM *)rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).v[LOW]; 00236 } 00237 00238 /** 00239 * @ingroup lxrt 00240 * Initialize a counting semaphore. 00241 * 00242 * Allocates and initializes a semaphore to be referred by @a name. 00243 * 00244 * @param name name of the semaphore. 00245 * 00246 * @param value is the initial value of the semaphore 00247 * 00248 * It is important to remark that the returned task pointer cannot be used 00249 * directly, they are for kernel space data, but just passed as arguments when 00250 * needed. 00251 * 00252 * @return a pointer to the semaphore to be used in related calls or 0 if an 00253 * error has occured. 00254 */ 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; long 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 00326 /** 00327 * @ingroup lxrt 00328 * Initialize a condition variable. 00329 * 00330 * Allocates and initializes a condition variable to be referred by @a name. 00331 * 00332 * @param name name of the condition variable. 00333 * 00334 * It is important to remark that the returned pointer cannot be used 00335 * directly, it is for kernel space data, but just passed as arguments when 00336 * needed. 00337 * 00338 * @return a pointer to the condition variable to be used in related calls or 0 00339 * if an error has occured. 00340 */ 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 */

Generated on Thu Nov 20 11:49:50 2008 for RTAI API by doxygen 1.3.8