base/include/rtai_posix.h

Go to the documentation of this file.
00001 /* 00002 * Copyright (C) 1999-2003 Paolo Mantegazza <mantegazza@aero.polimi.it> 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. 00017 * 00018 */ 00019 00020 #ifndef _RTAI_POSIX_H_ 00021 #define _RTAI_POSIX_H_ 00022 00023 #ifdef __KERNEL__ 00024 00025 #include <rtai_malloc.h> 00026 #include <rtai_rwl.h> 00027 #include <rtai_spl.h> 00028 #include <rtai_sem.h> 00029 00030 #define MAX_PRIO 99 00031 #define MIN_PRIO 1 00032 #define STACK_SIZE 8192 00033 #define RR_QUANTUM_NS 1000000 00034 00035 typedef struct rt_semaphore sem_t; 00036 00037 typedef struct rt_semaphore pthread_mutex_t; 00038 00039 typedef unsigned long pthread_mutexattr_t; 00040 00041 typedef struct rt_semaphore pthread_cond_t; 00042 00043 typedef unsigned long pthread_condattr_t; 00044 00045 typedef struct rt_semaphore pthread_barrier_t; 00046 00047 typedef int pthread_barrierattr_t; 00048 00049 typedef RWL pthread_rwlock_t; 00050 00051 typedef int pthread_rwlockattr_t; 00052 00053 typedef struct rt_spl_t pthread_spinlock_t; 00054 00055 typedef struct rt_task_struct *pthread_t; 00056 00057 typedef struct pthread_attr { 00058 00059 int stacksize; 00060 int policy; 00061 int rr_quantum_ns; 00062 int priority; 00063 00064 } pthread_attr_t; 00065 00066 typedef struct pthread_cookie { 00067 00068 RT_TASK task; 00069 SEM sem; 00070 void (*task_fun)(int); 00071 int arg; 00072 00073 } pthread_cookie_t; 00074 00075 #ifdef __cplusplus 00076 extern "C" { 00077 #endif /* __cplusplus */ 00078 00079 static inline int sem_init_rt(sem_t *sem, int pshared, unsigned int value) 00080 { 00081 if (value < SEM_TIMOUT) { 00082 rt_typed_sem_init(sem, value, pshared | PRIO_Q); 00083 return 0; 00084 } 00085 return -EINVAL; 00086 } 00087 00088 static inline int sem_destroy_rt(sem_t *sem) 00089 { 00090 if (rt_sem_wait_if(sem) >= 0) { 00091 rt_sem_signal(sem); 00092 return rt_sem_delete(sem); 00093 } 00094 return -EBUSY; 00095 } 00096 00097 static inline int sem_wait_rt(sem_t *sem) 00098 { 00099 return rt_sem_wait(sem) < SEM_TIMOUT ? 0 : -1; 00100 } 00101 00102 static inline int sem_trywait_rt(sem_t *sem) 00103 { 00104 return rt_sem_wait_if(sem) > 0 ? 0 : -EAGAIN; 00105 } 00106 00107 static inline int sem_timedwait_rt(sem_t *sem, const struct timespec *abstime) 00108 { 00109 return rt_sem_wait_until(sem, timespec2count(abstime)) < SEM_TIMOUT ? 0 : -1; 00110 } 00111 00112 static inline int sem_post_rt(sem_t *sem) 00113 { 00114 return rt_sem_signal(sem) < SEM_TIMOUT ? 0 : -ERANGE; 00115 } 00116 00117 static inline int sem_getvalue_rt(sem_t *sem, int *sval) 00118 { 00119 if ((*sval = rt_sem_wait_if(sem)) > 0) { 00120 rt_sem_signal(sem); 00121 } 00122 return 0; 00123 } 00124 00125 static inline int pthread_mutex_init_rt(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr) 00126 { 00127 rt_typed_sem_init(mutex, 1, RES_SEM); 00128 return 0; 00129 } 00130 00131 static inline int pthread_mutex_destroy_rt(pthread_mutex_t *mutex) 00132 { 00133 if (rt_sem_wait_if(mutex) > 0) { 00134 rt_sem_signal(mutex); 00135 return rt_sem_delete(mutex); 00136 } 00137 return -EBUSY; 00138 } 00139 00140 static inline int pthread_mutex_lock_rt(pthread_mutex_t *mutex) 00141 { 00142 return rt_sem_wait(mutex) < SEM_TIMOUT ? 0 : -EINVAL; 00143 } 00144 00145 static inline int pthread_mutex_timedlock_rt(pthread_mutex_t *mutex, const struct timespec *abstime) 00146 { 00147 return rt_sem_wait_until(mutex, timespec2count(abstime)) < SEM_TIMOUT ? 0 : -1; 00148 } 00149 00150 static inline int pthread_mutex_trylock_rt(pthread_mutex_t *mutex) 00151 { 00152 return rt_sem_wait_if(mutex) > 0 ? 0 : -EBUSY; 00153 } 00154 00155 static inline int pthread_mutex_unlock_rt(pthread_mutex_t *mutex) 00156 { 00157 return rt_sem_signal(mutex) > 0 ? 0 : -EINVAL; 00158 } 00159 00160 static inline int pthread_cond_init_rt(pthread_cond_t *cond, const pthread_condattr_t *cond_attr) 00161 { 00162 return sem_init_rt(cond, BIN_SEM, 0); 00163 } 00164 00165 static inline int pthread_cond_destroy_rt(pthread_cond_t *cond) 00166 { 00167 return sem_destroy_rt((sem_t *)cond); 00168 } 00169 00170 static inline int pthread_cond_signal_rt(pthread_cond_t *cond) 00171 { 00172 return rt_cond_signal((sem_t *)cond); 00173 } 00174 00175 static inline int pthread_cond_broadcast_rt(pthread_cond_t *cond) 00176 { 00177 return rt_sem_broadcast(cond); 00178 } 00179 00180 static inline int pthread_cond_wait_rt(pthread_cond_t *cond, pthread_mutex_t *mutex) 00181 { 00182 return rt_cond_wait(cond, mutex); 00183 } 00184 00185 static inline int pthread_cond_timedwait_rt(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime) 00186 { 00187 return rt_cond_wait_until(cond, mutex, timespec2count(abstime)) < SEM_TIMOUT ? 0 : -ETIMEDOUT; 00188 } 00189 00190 static inline int pthread_barrier_init_rt(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count) 00191 { 00192 return sem_init_rt(barrier, CNT_SEM, count); 00193 } 00194 00195 static inline int pthread_barrier_destroy_rt(pthread_barrier_t *barrier) 00196 { 00197 return sem_destroy_rt(barrier); 00198 } 00199 00200 static inline int pthread_barrier_wait_rt(pthread_barrier_t *barrier) 00201 { 00202 return rt_sem_wait_barrier(barrier); 00203 } 00204 00205 static inline int pthread_rwlock_init_rt(pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr) 00206 { 00207 return rt_rwl_init((RWL *)rwlock); 00208 } 00209 00210 static inline int pthread_rwlock_destroy_rt(pthread_rwlock_t *rwlock) 00211 { 00212 return rt_rwl_delete((RWL *)rwlock); 00213 } 00214 00215 static inline int pthread_rwlock_rdlock_rt(pthread_rwlock_t *rwlock) 00216 { 00217 return rt_rwl_rdlock((RWL *)rwlock); 00218 } 00219 00220 static inline int pthread_rwlock_tryrdlock_rt(pthread_rwlock_t *rwlock) 00221 { 00222 return rt_rwl_rdlock_if((RWL *)rwlock); 00223 } 00224 00225 static inline int pthread_rwlock_timedrdlock_rt(pthread_rwlock_t *rwlock, struct timespec *abstime) 00226 { 00227 return rt_rwl_rdlock_until((RWL *)rwlock, timespec2count(abstime)); 00228 } 00229 00230 static inline int pthread_rwlock_wrlock_rt(pthread_rwlock_t *rwlock) 00231 { 00232 return rt_rwl_wrlock((RWL *)rwlock); 00233 } 00234 00235 static inline int pthread_rwlock_trywrlock_rt(pthread_rwlock_t *rwlock) 00236 { 00237 return rt_rwl_wrlock_if((RWL *)rwlock); 00238 } 00239 00240 static inline int pthread_rwlock_timedwrlock_rt(pthread_rwlock_t *rwlock, struct timespec *abstime) 00241 { 00242 return rt_rwl_wrlock_until((RWL *)rwlock, timespec2count(abstime)); 00243 } 00244 00245 static inline int pthread_rwlock_unlock_rt(pthread_rwlock_t *rwlock) 00246 { 00247 return rt_rwl_unlock((RWL *)rwlock); 00248 } 00249 00250 static inline int pthread_spin_init_rt(pthread_spinlock_t *lock) 00251 { 00252 return rt_spl_init((SPL *)lock); 00253 } 00254 00255 static inline int pthread_spin_destroy_rt(pthread_spinlock_t *lock) 00256 { 00257 return rt_spl_delete((SPL *)lock); 00258 } 00259 00260 static inline int pthread_spin_lock_rt(pthread_spinlock_t *lock) 00261 { 00262 return rt_spl_lock((SPL *)lock); 00263 } 00264 00265 static inline int pthread_spin_trylock_rt(pthread_spinlock_t *lock) 00266 { 00267 return rt_spl_lock_if((SPL *)lock); 00268 } 00269 00270 static inline int pthread_spin_unlock_rt(pthread_spinlock_t *lock) 00271 { 00272 return rt_spl_unlock((SPL *)lock); 00273 } 00274 00275 static inline int get_max_priority_rt(int policy) 00276 { 00277 return MAX_PRIO; 00278 } 00279 00280 static inline int get_min_priority_rt(int policy) 00281 { 00282 return MIN_PRIO; 00283 } 00284 00285 static void posix_wrapper_fun(pthread_cookie_t *cookie) 00286 { 00287 cookie->task_fun(cookie->arg); 00288 rt_sem_broadcast(&cookie->sem); 00289 rt_sem_delete(&cookie->sem); 00290 rt_task_suspend(&cookie->task); 00291 } 00292 00293 static inline int pthread_create_rt(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine)(void *), void *arg) 00294 { 00295 pthread_cookie_t *cookie; 00296 cookie = (void *)rt_malloc(sizeof(pthread_cookie_t)); 00297 if (cookie) { 00298 (cookie->task).magic = 0; 00299 cookie->task_fun = (void *)start_routine; 00300 cookie->arg = (int)arg; 00301 if (!rt_task_init(&cookie->task, (void *)posix_wrapper_fun, (int)cookie, 00302 (attr) ? attr->stacksize : STACK_SIZE, (attr) ? attr->priority : RT_SCHED_LOWEST_PRIORITY, 1, 0)) { 00303 *thread = &cookie->task; 00304 rt_typed_sem_init(&cookie->sem, 0, BIN_SEM | FIFO_Q); 00305 rt_task_resume(&cookie->task); 00306 return 0; 00307 } 00308 } 00309 rt_free(cookie); 00310 return ENOMEM; 00311 } 00312 00313 static inline int pthread_yield_rt(void) 00314 { 00315 rt_task_yield(); 00316 return 0; 00317 } 00318 00319 static inline void pthread_exit_rt(void *retval) 00320 { 00321 RT_TASK *rt_task; 00322 rt_task = rt_whoami(); 00323 rt_sem_broadcast((SEM *)(rt_task + 1)); 00324 rt_sem_delete((SEM *)(rt_task + 1)); 00325 rt_task_suspend(rt_task); 00326 } 00327 00328 static inline int pthread_join_rt(pthread_t thread, void **thread_return) 00329 { 00330 int retval1, retval2; 00331 if (rt_whoami()->priority != RT_SCHED_LINUX_PRIORITY) 00332 retval1 = rt_sem_wait((SEM *)(thread + 1)); 00333 else { 00334 while ((retval1 = rt_sem_wait_if((SEM *)(thread + 1))) <= 0) { 00335 set_current_state(TASK_INTERRUPTIBLE); 00336 schedule_timeout(HZ/10); 00337 } 00338 } 00339 if (retval1 != 0xFFFF) 00340 retval1 = 0; 00341 retval2 = rt_task_delete(thread); 00342 rt_free(thread); 00343 return (retval1) ? retval1 : retval2; 00344 } 00345 00346 static inline int pthread_cancel_rt(pthread_t thread) 00347 { 00348 int retval; 00349 if (!thread) { 00350 thread = rt_whoami(); 00351 } 00352 retval = rt_task_delete(thread); 00353 rt_free(thread); 00354 return retval; 00355 } 00356 00357 static inline int pthread_equal_rt(pthread_t thread1,pthread_t thread2) 00358 { 00359 return thread1 == thread2; 00360 } 00361 00362 static inline pthread_t pthread_self_rt(void) 00363 { 00364 return rt_whoami(); 00365 } 00366 00367 static inline int pthread_attr_init_rt(pthread_attr_t *attr) 00368 { 00369 attr->stacksize = STACK_SIZE; 00370 attr->policy = SCHED_FIFO; 00371 attr->rr_quantum_ns = RR_QUANTUM_NS; 00372 attr->priority = 1; 00373 return 0; 00374 } 00375 00376 static inline int pthread_attr_destroy_rt(pthread_attr_t *attr) 00377 { 00378 return 0; 00379 } 00380 00381 static inline int pthread_attr_setschedparam_rt(pthread_attr_t *attr, const struct sched_param *param) 00382 { 00383 if(param->sched_priority < MIN_PRIO || param->sched_priority > MAX_PRIO) { 00384 return(EINVAL); 00385 } 00386 attr->priority = MAX_PRIO - param->sched_priority; 00387 return 0; 00388 } 00389 00390 static inline int pthread_attr_getschedparam_rt(const pthread_attr_t *attr, struct sched_param *param) 00391 { 00392 param->sched_priority = MAX_PRIO - attr->priority; 00393 return 0; 00394 } 00395 00396 static inline int pthread_attr_setschedpolicy_rt(pthread_attr_t *attr, int policy) 00397 { 00398 if(policy != SCHED_FIFO && policy != SCHED_RR) { 00399 return EINVAL; 00400 } 00401 if ((attr->policy = policy) == SCHED_RR) { 00402 rt_set_sched_policy(rt_whoami(), SCHED_RR, attr->rr_quantum_ns); 00403 } 00404 return 0; 00405 } 00406 00407 00408 static inline int pthread_attr_getschedpolicy_rt(const pthread_attr_t *attr, int *policy) 00409 { 00410 *policy = attr->policy; 00411 return 0; 00412 } 00413 00414 static inline int pthread_attr_setschedrr_rt(pthread_attr_t *attr, int rr_quantum_ns) 00415 { 00416 attr->rr_quantum_ns = rr_quantum_ns; 00417 return 0; 00418 } 00419 00420 00421 static inline int pthread_attr_getschedrr_rt(const pthread_attr_t *attr, int *rr_quantum_ns) 00422 { 00423 *rr_quantum_ns = attr->rr_quantum_ns; 00424 return 0; 00425 } 00426 00427 static inline int pthread_attr_setstacksize_rt(pthread_attr_t *attr, int stacksize) 00428 { 00429 attr->stacksize = stacksize; 00430 return 0; 00431 } 00432 00433 static inline int pthread_attr_getstacksize_rt(const pthread_attr_t *attr, int *stacksize) 00434 { 00435 *stacksize = attr->stacksize; 00436 return 0; 00437 } 00438 00439 static inline int pthread_attr_setstack_rt(pthread_attr_t *attr, void *stackaddr, int stacksize) 00440 { 00441 attr->stacksize = stacksize; 00442 return 0; 00443 } 00444 00445 static inline int pthread_attr_getstack_rt(const pthread_attr_t *attr, void **stackaddr, int *stacksize) 00446 { 00447 *stacksize = attr->stacksize; 00448 return 0; 00449 } 00450 00451 static inline void pthread_testcancel_rt(void) 00452 { 00453 rt_task_delete(rt_whoami()); 00454 pthread_exit_rt(NULL); 00455 } 00456 00457 static inline void clock_gettime_rt(int clockid, struct timespec *current_time) 00458 { 00459 count2timespec(rt_get_time(), current_time); 00460 } 00461 00462 static inline int nanosleep_rt(const struct timespec *rqtp, struct timespec *rmtp) 00463 { 00464 RTIME expire; 00465 if (rqtp->tv_nsec >= 1000000000L || rqtp->tv_nsec < 0 || rqtp->tv_sec < 00466 0) { 00467 return -EINVAL; 00468 } 00469 rt_sleep_until(expire = rt_get_time() + timespec2count(rqtp)); 00470 if ((expire -= rt_get_time()) > 0) { 00471 if (rmtp) { 00472 count2timespec(expire, rmtp); 00473 } 00474 return -EINTR; 00475 } 00476 return 0; 00477 } 00478 00479 /* 00480 * DO NOTHING FUNCTIONS 00481 */ 00482 00483 #define pthread_mutexattr_init_rt(attr) 00484 #define pthread_mutexattr_destroy_rt(attr) 00485 #define pthread_mutexattr_getpshared_rt(attr, pshared) 00486 #define pthread_mutexattr_setpshared_rt(attr, pshared) 00487 #define pthread_mutexattr_settype_rt(attr, kind) 00488 #define pthread_mutexattr_gettype_rt(attr, kind) 00489 00490 #define pthread_condattr_init_rt(attr) 00491 #define pthread_condattr_destroy_rt(attr) 00492 #define pthread_condattr_getpshared_rt(attr, pshared) 00493 #define pthread_condattr_setpshared_rt(attr, pshared) 00494 00495 #define pthread_barrierattr_getpshared_rt(attr, pshared) 00496 #define pthread_barrierattr_setpshared_rt(attr, pshared) 00497 #define pthread_barrierattr_getpshared_rt(attr, pshared) 00498 #define pthread_barrierattr_setpshared_rt(attr, pshared) 00499 00500 #define pthread_rwlockattr_init(attr) 00501 #define pthread_rwlockattr_destroy(attr) 00502 #define pthread_rwlockattr_getpshared( ttr, pshared) 00503 #define pthread_rwlockattr_setpshared(attr, pshared) 00504 #define pthread_rwlockattr_getkind_np(attr, pref) 00505 #define pthread_rwlockattr_setkind_np(attr, pref) 00506 00507 #define pthread_detach_rt(thread) 00508 #define pthread_attr_setdetachstate_rt(attr, detachstate) 00509 #define pthread_attr_getdetachstate_rt(attr, detachstate) 00510 #define pthread_setconcurrency_rt(level) 00511 #define pthread_getconcurrency_rt() 00512 #define pthread_attr_setinheritsched_rt(attr, inherit) 00513 #define pthread_attr_getinheritsched_rt(attr, inherit) 00514 #define pthread_attr_setscope_rt(attr, scope) 00515 #define pthread_attr_getscope_rt(attr, scope) 00516 #define pthread_attr_setguardsize_rt(attr, guardsize) 00517 #define pthread_attr_getguardsize_rt(attr, guardsize) 00518 #define pthread_attr_setstackaddr_rt(attr, stackaddr) 00519 #define pthread_attr_getstackaddr_rt(attr, stackaddr) 00520 #define pthread_setcancelstate_rt(state, oldstate) 00521 #define pthread_setcanceltype_rt(type, oldtype) 00522 00523 #ifdef __cplusplus 00524 } 00525 #endif /* __cplusplus */ 00526 00527 #else /* !__KERNEL__ */ 00528 00529 #include <errno.h> 00530 #include <fcntl.h> 00531 #include <unistd.h> 00532 #include <signal.h> 00533 #include <sys/types.h> 00534 #include <sys/stat.h> 00535 #include <semaphore.h> 00536 #include <pthread.h> 00537 #include <stdlib.h> 00538 00539 struct task_struct; 00540 00541 #undef SEM_VALUE_MAX 00542 #define SEM_VALUE_MAX (SEM_TIMOUT - 1) 00543 #define SEM_BINARY (0x7FFFFFFF) 00544 00545 #include <asm/rtai_atomic.h> 00546 #include <rtai_sem.h> 00547 00548 /* 00549 * SUPPORT STUFF 00550 */ 00551 00552 static inline int MAKE_SOFT(void) 00553 { 00554 if (rt_is_hard_real_time(rt_buddy())) { 00555 rt_make_soft_real_time(); 00556 return 1; 00557 } 00558 return 0; 00559 } 00560 00561 #define MAKE_HARD(hs) do { if (hs) rt_make_hard_real_time(); } while (0) 00562 00563 #ifdef __cplusplus 00564 extern "C" { 00565 #endif /* __cplusplus */ 00566 00567 RTAI_PROTO(void, count2timespec,(RTIME rt, struct timespec *t)) 00568 { 00569 t->tv_sec = (rt = count2nano(rt))/1000000000; 00570 t->tv_nsec = rt - t->tv_sec*1000000000LL; 00571 } 00572 00573 RTAI_PROTO(void, nanos2timespec,(RTIME rt, struct timespec *t)) 00574 { 00575 t->tv_sec = rt/1000000000; 00576 t->tv_nsec = rt - t->tv_sec*1000000000LL; 00577 } 00578 00579 RTAI_PROTO(RTIME, timespec2count,(const struct timespec *t)) 00580 { 00581 return nano2count(t->tv_sec*1000000000LL + t->tv_nsec); 00582 } 00583 00584 RTAI_PROTO(RTIME, timespec2nanos,(const struct timespec *t)) 00585 { 00586 return t->tv_sec*1000000000LL + t->tv_nsec; 00587 } 00588 00589 /* 00590 * FUNCTIONS MADE SAFELY USABLE IN HARD REAL TIME, BUT BREAKING HARD REAL TIME 00591 */ 00592 00593 RTAI_PROTO(sem_t *,sem_open_rt,(const char *name, int oflags, int value, int type)) 00594 { 00595 int hs, fd; 00596 sem_t *sem; 00597 hs = MAKE_SOFT(); 00598 if ((fd = open(name, O_RDONLY)) > 0) { 00599 read(fd, &sem, sizeof(int)); 00600 close(fd); 00601 atomic_inc((atomic_t *)(&((int *)sem)[1])); 00602 } else { 00603 struct { unsigned long name, value, type; } arg = { nam2num(name), value, (type == SEM_BINARY ? BIN_SEM : CNT_SEM) | PRIO_Q }; 00604 sem = (sem_t *)malloc(sizeof(sem_t)); 00605 if ((((int *)sem)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).i[LOW]) && (fd = open(name, O_WRONLY | O_CREAT))) { 00606 write(fd, &sem, sizeof(int)); 00607 close(fd); 00608 ((int *)sem)[1] = 1; 00609 } else { 00610 free(sem); 00611 sem = 0; 00612 } 00613 } 00614 MAKE_HARD(hs); 00615 return sem; 00616 } 00617 00618 RTAI_PROTO(int, sem_init_rt,(sem_t *sem, int pshared, unsigned int value)) 00619 { 00620 int hs; 00621 if (value <= SEM_VALUE_MAX) { 00622 struct { unsigned long name, value, type; } arg = { rt_get_name(0), value, (pshared == SEM_BINARY ? BIN_SEM : CNT_SEM) | PRIO_Q }; 00623 hs = MAKE_SOFT(); 00624 ((int *)sem)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).i[LOW]; 00625 ((int *)sem)[1] = 0; 00626 MAKE_HARD(hs); 00627 return 0; 00628 } 00629 errno = EINVAL; 00630 return -1; 00631 } 00632 00633 RTAI_PROTO(int, sem_close_rt,(sem_t *sem)) 00634 { 00635 int hs, cnt; 00636 char name[7]; 00637 struct { void *sem; } arg = { ((void **)sem)[0] }; 00638 if (rtai_lxrt(BIDX, SIZARG, SEM_WAIT_IF, &arg).i[LOW] < 0) { 00639 errno = EBUSY; 00640 return -1; 00641 } 00642 cnt = ((int *)sem)[1]; 00643 if (!cnt || (cnt && atomic_dec_and_test((atomic_t *)&((int *)sem)[1]))) { 00644 hs = MAKE_SOFT(); 00645 num2nam(rt_get_name(((void **)sem)[0]), name); 00646 rtai_lxrt(BIDX, SIZARG, LXRT_SEM_DELETE, &arg); 00647 if (cnt) { 00648 unlink(name); 00649 free((void *)sem); 00650 } 00651 MAKE_HARD(hs); 00652 } 00653 return 0; 00654 } 00655 00656 RTAI_PROTO(int, sem_destroy_rt,(sem_t *sem)) 00657 { 00658 return sem_close_rt(sem); 00659 } 00660 00661 RTAI_PROTO(int, pthread_create_rt,(pthread_t *thread, pthread_attr_t *attr, void *(*start_routine)(void *), void *arg)) 00662 { 00663 int hs, ret; 00664 hs = MAKE_SOFT(); 00665 ret = pthread_create(thread, attr, start_routine, arg); 00666 MAKE_HARD(hs); 00667 return ret; 00668 } 00669 00670 RTAI_PROTO(int, pthread_cancel_rt,(pthread_t thread)) 00671 { 00672 int hs, ret; 00673 hs = MAKE_SOFT(); 00674 ret = pthread_cancel(thread); 00675 MAKE_HARD(hs); 00676 return ret; 00677 } 00678 00679 #define pthread_cleanup_push_rt(routine, arg) \ 00680 do { \ 00681 {\ 00682 int __hs_hs_hs__; \ 00683 __hs_hs_hs__ = MAKE_SOFT(); \ 00684 pthread_cleanup_push(routine, arg); \ 00685 MAKE_HARD(__hs_hs_hs__); 00686 00687 #define pthread_cleanup_pop_rt(execute) \ 00688 __hs_hs_hs__ = MAKE_SOFT(); \ 00689 pthread_cleanup_pop(execute); \ 00690 MAKE_HARD(__hs_hs_hs__); \ 00691 } \ 00692 } while (0) 00693 00694 #define pthread_cleanup_push_defer_rt(routine, arg) \ 00695 do { \ 00696 {\ 00697 int __hs_hs_hs__; \ 00698 __hs_hs_hs__ = MAKE_SOFT(); \ 00699 pthread_cleanup_push_defer_np(routine, arg); \ 00700 MAKE_HARD(__hs_hs_hs__); 00701 00702 #define pthread_cleanup_pop_restore_rt(execute) \ 00703 __hs_hs_hs__ = MAKE_SOFT(); \ 00704 pthread_cleanup_pop_restore_np(execute); \ 00705 MAKE_HARD(__hs_hs_hs__); \ 00706 } \ 00707 } while (0) 00708 00709 RTAI_PROTO(int, pthread_sigmask_rt,(int how, const sigset_t *newmask, sigset_t *oldmask)) 00710 { 00711 int hs, ret; 00712 hs = MAKE_SOFT(); 00713 ret = pthread_sigmask(how, newmask, oldmask); 00714 MAKE_HARD(hs); 00715 return ret; 00716 } 00717 00718 RTAI_PROTO(int, pthread_kill_rt,(pthread_t thread, int signo)) 00719 { 00720 int hs, ret; 00721 hs = MAKE_SOFT(); 00722 ret = pthread_kill(thread, signo); 00723 MAKE_HARD(hs); 00724 return ret; 00725 } 00726 00727 00728 RTAI_PROTO(int, sigwait_rt,(const sigset_t *set, int *sig)) 00729 { 00730 int hs, ret; 00731 hs = MAKE_SOFT(); 00732 ret = sigwait(set, sig); 00733 MAKE_HARD(hs); 00734 return ret; 00735 } 00736 00737 RTAI_PROTO(pthread_mutex_t *, pthread_mutex_open_rt,(const char *name)) 00738 { 00739 int hs, fd; 00740 pthread_mutex_t *mutex; 00741 hs = MAKE_SOFT(); 00742 if ((fd = open(name, O_RDONLY)) > 0) { 00743 read(fd, &mutex, sizeof(int)); 00744 close(fd); 00745 atomic_inc((atomic_t *)(&((int *)mutex)[1])); 00746 } else { 00747 struct { unsigned long name, value, type; } arg = { nam2num(name), 1, RES_SEM }; 00748 mutex = (pthread_mutex_t *)malloc(sizeof(pthread_mutex_t)); 00749 if ((((int *)mutex)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).i[LOW]) && (fd = open(name, O_WRONLY | O_CREAT))) { 00750 write(fd, &mutex, sizeof(int)); 00751 close(fd); 00752 ((int *)mutex)[1] = 1; 00753 } else { 00754 free(mutex); 00755 mutex = 0; 00756 } 00757 } 00758 MAKE_HARD(hs); 00759 return mutex; 00760 } 00761 00762 RTAI_PROTO(int, pthread_mutex_init_rt,(pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)) 00763 { 00764 int hs; 00765 struct { unsigned long name, value, type; } arg = { rt_get_name(0), 1, RES_SEM }; 00766 hs = MAKE_SOFT(); 00767 ((int *)mutex)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_SEM_INIT, &arg).i[LOW]; 00768 ((int *)mutex)[1] = 0; 00769 MAKE_HARD(hs); 00770 return 0; 00771 } 00772 00773 RTAI_PROTO(int, pthread_mutex_close_rt,(pthread_mutex_t *mutex)) 00774 { 00775 int hs, cnt; 00776 char name[7]; 00777 struct { void *sem; } arg = { ((void **)mutex)[0] }; 00778 if (rtai_lxrt(BIDX, SIZARG, SEM_WAIT_IF, &arg).i[LOW] < 0) { 00779 return EBUSY; 00780 } 00781 cnt = ((int *)mutex)[1]; 00782 if (!cnt || (cnt && atomic_dec_and_test((atomic_t *)&((int *)mutex)[1]))) { 00783 hs = MAKE_SOFT(); 00784 num2nam(rt_get_name(((void **)mutex)[0]), name); 00785 rtai_lxrt(BIDX, SIZARG, LXRT_SEM_DELETE, &arg); 00786 if (cnt) { 00787 unlink(name); 00788 free((void *)mutex); 00789 } 00790 MAKE_HARD(hs); 00791 } 00792 return 0; 00793 } 00794 00795 RTAI_PROTO(int, pthread_mutex_destroy_rt,(pthread_mutex_t *mutex)) 00796 { 00797 return pthread_mutex_close_rt(mutex); 00798 } 00799 00800 RTAI_PROTO(pthread_cond_t *, pthread_cond_open_rt,(const char *name)) 00801 { 00802 return (pthread_cond_t *)sem_open_rt(name, 0, 0, SEM_BINARY); 00803 } 00804 00805 RTAI_PROTO(int, pthread_cond_init_rt,(pthread_cond_t *cond, pthread_condattr_t *cond_attr)) 00806 { 00807 return sem_init_rt((sem_t *)cond, SEM_BINARY, 0); 00808 } 00809 00810 RTAI_PROTO(int, pthread_cond_destroy_rt,(pthread_cond_t *cond)) 00811 { 00812 return sem_close_rt((sem_t *)cond); 00813 } 00814 00815 RTAI_PROTO(int, pthread_cond_close_rt,(pthread_cond_t *cond)) 00816 { 00817 return sem_close_rt((sem_t *)cond); 00818 } 00819 00820 #ifdef __USE_XOPEN2K 00821 RTAI_PROTO(pthread_barrier_t *, pthread_barrier_open_rt,(const char *name, unsigned int count)) 00822 { 00823 return (pthread_barrier_t *)sem_open_rt(name, 0, count, 0); 00824 } 00825 00826 RTAI_PROTO(int, pthread_barrier_init_rt,(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)) 00827 { 00828 return sem_init_rt((sem_t *)barrier, 0, count); 00829 } 00830 00831 RTAI_PROTO(int, pthread_barrier_destroy_rt,(pthread_barrier_t *barrier)) 00832 { 00833 return sem_close_rt((sem_t *)barrier); 00834 } 00835 00836 RTAI_PROTO(int, pthread_barrier_close_rt,(pthread_barrier_t *barrier)) 00837 { 00838 return sem_close_rt((sem_t *)barrier); 00839 } 00840 #endif 00841 00842 /* 00843 * DO NOTHING FUNCTIONS (IN RTAI HARD REAL TIME) 00844 */ 00845 00846 #define pthread_attr_setdetachstate_rt(attr, detachstate) 00847 #define pthread_detach_rt(thread) 00848 #define pthread_getconcurrency_rt() 00849 #define pthread_setconcurrency_rt(level) 00850 00851 #define pthread_mutexattr_init_rt(attr) 00852 #define pthread_mutexattr_destroy_rt(attr) 00853 #define pthread_mutexattr_getpshared_rt(attr, pshared) 00854 #define pthread_mutexattr_setpshared_rt(attr, pshared) 00855 #define pthread_mutexattr_settype_rt(attr, kind) 00856 #define pthread_mutexattr_gettype_rt(attr, kind) 00857 00858 #define pthread_condattr_init_rt(attr) 00859 #define pthread_condattr_destroy_rt(attr) 00860 #define pthread_condattr_getpshared_rt(attr, pshared) 00861 #define pthread_condattr_setpshared_rt(attr, pshared) 00862 #ifdef __USE_XOPEN2K 00863 #define pthread_barrierattr_getpshared_rt(attr, pshared) 00864 #define pthread_barrierattr_setpshared_rt(attr, pshared) 00865 #define pthread_barrierattr_getpshared_rt(attr, pshared) 00866 #define pthread_barrierattr_setpshared_rt(attr, pshared) 00867 #endif 00868 #define pthread_rwlockattr_init(attr) 00869 #define pthread_rwlockattr_destroy(attr) 00870 #define pthread_rwlockattr_getpshared( ttr, pshared) 00871 #define pthread_rwlockattr_setpshared(attr, pshared) 00872 #define pthread_rwlockattr_getkind_np(attr, pref) 00873 #define pthread_rwlockattr_setkind_np(attr, pref) 00874 00875 /* 00876 * FUNCTIONS (LIKELY) SAFELY USABLE IN HARD REAL TIME "AS THEY ARE", 00877 * BECAUSE MAKE SENSE IN THE INITIALIZATION PHASE ONLY, I.E. BEFORE 00878 * GOING HARD REAL TIME 00879 */ 00880 00881 #define pthread_self_rt pthread_self 00882 #define pthread_equal_rt pthread_equal 00883 #define pthread_attr_init_rt pthread_attr_init 00884 #define pthread_attr_destroy_rt pthread_attr_destroy 00885 #define pthread_attr_getdetachstate_rt pthread_attr_getdetachstate 00886 #define pthread_attr_setschedpolicy_rt pthread_attr_setschedpolicy 00887 #define pthread_attr_getschedpolicy_rt pthread_attr_getschedpolicy 00888 #define pthread_attr_setschedparam_rt pthread_attr_setschedparam 00889 #define pthread_attr_getschedparam_rt pthread_attr_getschedparam 00890 #define pthread_attr_setinheritsched_rt pthread_attr_setinheritsched 00891 #define pthread_attr_getinheritsched_rt pthread_attr_getinheritsched 00892 #define pthread_attr_setscope_rt pthread_attr_setscope 00893 #define pthread_attr_getscope_rt pthread_attr_getscope 00894 #ifdef __USE_UNIX98 00895 #define pthread_attr_setguardsize_rt pthread_attr_setguardsize 00896 #define pthread_attr_getguardsize_rt pthread_attr_getguardsize 00897 #endif 00898 #define pthread_attr_setstackaddr_rt pthread_attr_setstackaddr 00899 #define pthread_attr_getstackaddr_rt pthread_attr_getstackaddr 00900 #ifdef __USE_XOPEN2K 00901 #define pthread_attr_setstack_rt pthread_attr_setstack 00902 #define pthread_attr_getstack_rt pthread_attr_getstack 00903 #endif 00904 #define pthread_attr_setstacksize_rt pthread_attr_setstacksize 00905 #define pthread_attr_getstacksize_rt pthread_attr_getstacksize 00906 00907 /* 00908 * WORKING FUNCTIONS USABLE IN HARD REAL TIME, THIS IS THE REAL STUFF 00909 */ 00910 00911 #define pthread_setcancelstate_rt pthread_setcancelstate 00912 #define pthread_setcanceltype_rt pthread_setcanceltype 00913 00914 RTAI_PROTO(void, pthread_testcancel_rt,(void)) 00915 { 00916 int oldtype, oldstate; 00917 pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &oldstate); 00918 pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &oldtype); 00919 if (oldstate != PTHREAD_CANCEL_DISABLE && oldtype != PTHREAD_CANCEL_DEFERRED) { 00920 MAKE_SOFT(); 00921 rt_task_delete(rt_buddy()); 00922 pthread_exit(NULL); 00923 } 00924 pthread_setcanceltype(oldtype, &oldtype); 00925 pthread_setcancelstate(oldstate, &oldstate); 00926 } 00927 00928 extern int pthread_yield (void); 00929 RTAI_PROTO(int, pthread_yield_rt,(void)) 00930 { 00931 if (rt_is_hard_real_time(rt_buddy())) { 00932 struct { unsigned long dummy; } arg; 00933 rtai_lxrt(BIDX, SIZARG, YIELD, &arg); 00934 return 0; 00935 } 00936 return pthread_yield(); 00937 } 00938 00939 RTAI_PROTO(void, pthread_exit_rt,(void *retval)) 00940 { 00941 MAKE_SOFT(); 00942 rt_task_delete(rt_buddy()); 00943 pthread_exit(retval); 00944 } 00945 00946 RTAI_PROTO(int, pthread_join_rt,(pthread_t thread, void **thread_return)) 00947 { 00948 int hs, ret; 00949 hs = MAKE_SOFT(); 00950 ret = pthread_join(thread, thread_return); 00951 MAKE_HARD(hs); 00952 return ret; 00953 } 00954 00955 RTAI_PROTO(int, sem_wait_rt,(sem_t *sem)) 00956 { 00957 struct { void *sem; } arg = { ((void **)sem)[0] }; 00958 rtai_lxrt(BIDX, SIZARG, SEM_WAIT, &arg); 00959 return 0; 00960 } 00961 00962 RTAI_PROTO(int, sem_trywait_rt,(sem_t *sem)) 00963 { 00964 struct { void *sem; } arg = { ((void **)sem)[0] }; 00965 if (rtai_lxrt(BIDX, SIZARG, SEM_WAIT_IF, &arg).i[LOW] > 0) { 00966 return 0; 00967 } 00968 errno = EAGAIN; 00969 return -1; 00970 } 00971 00972 RTAI_PROTO(int, sem_timedwait_rt,(sem_t *sem, const struct timespec *abstime)) 00973 { 00974 struct { void *sem; RTIME until; } arg = { ((void **)sem)[0], timespec2count(abstime) }; 00975 return rtai_lxrt(BIDX, SIZARG, SEM_WAIT_UNTIL, &arg).i[LOW] < SEM_VALUE_MAX ? 0 : ETIMEDOUT; 00976 } 00977 00978 RTAI_PROTO(int, sem_post_rt,(sem_t *sem)) 00979 { 00980 struct { void *sem; } arg = { ((void **)sem)[0] }; 00981 return rtai_lxrt(BIDX, SIZARG, SEM_SIGNAL, &arg).i[LOW]; 00982 } 00983 00984 RTAI_PROTO(int, sem_getvalue_rt,(sem_t *sem, int *sval)) 00985 { 00986 struct { void *sem; } arg = { ((void **)sem)[0] }; 00987 *sval = rtai_lxrt(BIDX, SIZARG, SEM_COUNT, &arg).i[LOW]; 00988 return 0; 00989 } 00990 00991 RTAI_PROTO(int, pthread_mutex_lock_rt,(pthread_mutex_t *mutex)) 00992 { 00993 return sem_wait_rt((sem_t *)mutex); 00994 } 00995 00996 #ifdef __USE_XOPEN2K 00997 RTAI_PROTO(int, pthread_mutex_timedlock_rt,(pthread_mutex_t *mutex, const struct timespec *abstime)) 00998 { 00999 return sem_timedwait_rt((sem_t *)mutex, abstime); 01000 } 01001 #endif 01002 01003 RTAI_PROTO(int, pthread_mutex_trylock_rt,(pthread_mutex_t *mutex)) 01004 { 01005 return sem_trywait_rt((sem_t *)mutex); 01006 } 01007 01008 RTAI_PROTO(int, pthread_mutex_unlock_rt,(pthread_mutex_t *mutex)) 01009 { 01010 return sem_post_rt((sem_t *)mutex); 01011 } 01012 01013 RTAI_PROTO(int, pthread_cond_signal_rt,(pthread_cond_t *cond)) 01014 { 01015 struct { void *cond; } arg = { ((void **)cond)[0] }; 01016 return rtai_lxrt(BIDX, SIZARG, COND_SIGNAL, &arg).i[LOW]; 01017 } 01018 01019 RTAI_PROTO(int, pthread_cond_broadcast_rt,(pthread_cond_t *cond)) 01020 { 01021 struct { void *cond; } arg = { ((void **)cond)[0] }; 01022 return rtai_lxrt(BIDX, SIZARG, SEM_BROADCAST, &arg).i[LOW]; 01023 } 01024 01025 RTAI_PROTO(int, pthread_cond_wait_rt,(pthread_cond_t *cond, pthread_mutex_t *mutex)) 01026 { 01027 struct { void *cond; void *mutex; } arg = { ((void **)cond)[0], ((void **)mutex)[0] }; 01028 return rtai_lxrt(BIDX, SIZARG, COND_WAIT, &arg).i[LOW]; 01029 } 01030 01031 RTAI_PROTO(int, pthread_cond_timedwait_rt,(pthread_cond_t *cond, pthread_mutex_t *mutex, const struct timespec *abstime)) 01032 { 01033 struct { void *cond; void *mutex; RTIME time; } arg = { ((void **)cond)[0], ((void **)mutex)[0], timespec2count(abstime) }; 01034 return rtai_lxrt(BIDX, SIZARG, COND_WAIT_UNTIL, &arg).i[LOW] < SEM_TIMOUT ? 0 : -ETIMEDOUT; 01035 } 01036 01037 #ifdef __USE_XOPEN2K 01038 RTAI_PROTO(int, pthread_barrier_wait_rt,(pthread_barrier_t *barrier)) 01039 { 01040 struct { void *sem; } arg = { ((void **)barrier)[0] }; 01041 rtai_lxrt(BIDX, SIZARG, SEM_WAIT_BARRIER, &arg); 01042 return 0; 01043 } 01044 #endif 01045 01046 #ifdef __USE_UNIX98 01047 RTAI_PROTO(pthread_rwlock_t *, pthread_rwlock_open_rt,(const char *name)) 01048 { 01049 int hs, fd; 01050 pthread_rwlock_t *rwlock; 01051 hs = MAKE_SOFT(); 01052 if ((fd = open(name, O_RDONLY)) > 0) { 01053 read(fd, &rwlock, sizeof(int)); 01054 close(fd); 01055 atomic_inc((atomic_t *)(&((int *)rwlock)[1])); 01056 } else { 01057 struct { unsigned long name, value, type; } arg = { nam2num(name), 1, RES_SEM }; 01058 rwlock = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); 01059 if ((((int *)rwlock)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_RWL_INIT, &arg).i[LOW]) && (fd = open(name, O_WRONLY | O_CREAT))) { 01060 write(fd, &rwlock, sizeof(int)); 01061 close(fd); 01062 ((int *)rwlock)[1] = 1; 01063 } else { 01064 free(rwlock); 01065 rwlock = 0; 01066 } 01067 } 01068 MAKE_HARD(hs); 01069 return rwlock; 01070 } 01071 #endif /* __USE_UNIX98 */ 01072 01073 RTAI_PROTO(int, pthread_rwlock_init_rt,(pthread_rwlock_t *rwlock, pthread_rwlockattr_t *attr)) 01074 { 01075 int hs; 01076 struct { unsigned long name; } arg = { rt_get_name(0) }; 01077 hs = MAKE_SOFT(); 01078 ((int *)rwlock)[0] = rtai_lxrt(BIDX, SIZARG, LXRT_RWL_INIT, &arg).i[LOW]; 01079 ((int *)rwlock)[1] = 0; 01080 MAKE_HARD(hs); 01081 return 0; 01082 } 01083 01084 RTAI_PROTO(int, pthread_rwlock_close_rt,(pthread_rwlock_t *rwlock)) 01085 { 01086 int hs, cnt; 01087 char name[7]; 01088 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01089 if (rtai_lxrt(BIDX, SIZARG, RWL_WRLOCK_IF, &arg).i[LOW] < 0) { 01090 return EBUSY; 01091 } else { 01092 rtai_lxrt(BIDX, SIZARG, RWL_UNLOCK, &arg); 01093 if (rtai_lxrt(BIDX, SIZARG, RWL_RDLOCK_IF, &arg).i[LOW] < 0) { 01094 return EBUSY; 01095 } 01096 rtai_lxrt(BIDX, SIZARG, RWL_UNLOCK, &arg); 01097 } 01098 cnt = ((int *)rwlock)[1]; 01099 if (!cnt || (cnt && atomic_dec_and_test((atomic_t *)&((int *)rwlock)[1]))) { 01100 hs = MAKE_SOFT(); 01101 num2nam(rt_get_name(((void **)rwlock)[0]), name); 01102 rtai_lxrt(BIDX, SIZARG, LXRT_RWL_DELETE, &arg); 01103 if (cnt) { 01104 unlink(name); 01105 free((void *)rwlock); 01106 } 01107 MAKE_HARD(hs); 01108 } 01109 return 0; 01110 } 01111 01112 RTAI_PROTO(int, pthread_rwlock_destroy_rt,(pthread_rwlock_t *rwlock)) 01113 { 01114 return pthread_rwlock_close_rt(rwlock); 01115 } 01116 01117 RTAI_PROTO(int, pthread_rwlock_rdlock_rt,(pthread_rwlock_t *rwlock)) 01118 { 01119 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01120 return rtai_lxrt(BIDX, SIZARG, RWL_RDLOCK, &arg).i[LOW]; 01121 } 01122 01123 RTAI_PROTO(int, pthread_rwlock_tryrdlock_rt,(pthread_rwlock_t *rwlock)) 01124 { 01125 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01126 return rtai_lxrt(BIDX, SIZARG, RWL_RDLOCK_IF, &arg).i[LOW]; 01127 } 01128 01129 #ifdef __USE_XOPEN2K 01130 RTAI_PROTO(int, pthread_rwlock_timedrdlock_rt,(pthread_rwlock_t *rwlock, struct timespec *abstime)) 01131 { 01132 struct { void *rwlock; RTIME time; } arg = { ((void **)rwlock)[0], timespec2count(abstime) }; 01133 return rtai_lxrt(BIDX, SIZARG, RWL_RDLOCK_UNTIL, &arg).i[LOW]; 01134 } 01135 #endif 01136 01137 RTAI_PROTO(int, pthread_rwlock_wrlock_rt,(pthread_rwlock_t *rwlock)) 01138 { 01139 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01140 return rtai_lxrt(BIDX, SIZARG, RWL_WRLOCK, &arg).i[LOW]; 01141 } 01142 01143 RTAI_PROTO(int, pthread_rwlock_trywrlock_rt,(pthread_rwlock_t *rwlock)) 01144 { 01145 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01146 return rtai_lxrt(BIDX, SIZARG, RWL_WRLOCK_IF, &arg).i[LOW]; 01147 } 01148 01149 #ifdef __USE_XOPEN2K 01150 RTAI_PROTO(int, pthread_rwlock_timedwrlock_rt,(pthread_rwlock_t *rwlock, struct timespec *abstime)) 01151 { 01152 struct { void *rwlock; RTIME time; } arg = { ((void **)rwlock)[0], timespec2count(abstime) }; 01153 return rtai_lxrt(BIDX, SIZARG, RWL_WRLOCK_UNTIL, &arg).i[LOW]; 01154 } 01155 #endif 01156 01157 RTAI_PROTO(int, pthread_rwlock_unlock_rt,(pthread_rwlock_t *rwlock)) 01158 { 01159 struct { void *rwlock; } arg = { ((void **)rwlock)[0] }; 01160 return rtai_lxrt(BIDX, SIZARG, RWL_UNLOCK, &arg).i[LOW]; 01161 } 01162 01163 #ifdef __USE_XOPEN2K 01164 RTAI_PROTO(int, pthread_spin_init_rt,(pthread_spinlock_t *lock)) 01165 { 01166 return (((int *)lock)[0] = 0); 01167 } 01168 01169 RTAI_PROTO(int, pthread_spin_destroy_rt,(pthread_spinlock_t *lock)) 01170 { 01171 return ((int *)lock)[0] = 0; 01172 } 01173 01174 RTAI_PROTO(int, pthread_spin_lock_rt,(pthread_spinlock_t *lock)) 01175 { 01176 while (atomic_cmpxchg(&lock, 0, 1)); 01177 return 0; 01178 } 01179 01180 RTAI_PROTO(int, pthread_spin_trylock_rt,(pthread_spinlock_t *lock)) 01181 { 01182 if (atomic_cmpxchg(&lock, 0, 1)) { 01183 return EAGAIN; 01184 } 01185 return 0; 01186 } 01187 01188 RTAI_PROTO(int, pthread_spin_unlock_rt,(pthread_spinlock_t *lock)) 01189 { 01190 return ((int *)lock)[0] = 0; 01191 } 01192 #endif 01193 01194 RTAI_PROTO(void, clock_gettime_rt,(int clockid, struct timespec *current_time)) 01195 { 01196 count2timespec(rt_get_time(), current_time); 01197 } 01198 01199 RTAI_PROTO(int, nanosleep_rt,(const struct timespec *rqtp, struct timespec *rmtp)) 01200 { 01201 RTIME expire; 01202 if (rqtp->tv_nsec >= 1000000000L || rqtp->tv_nsec < 0 || rqtp->tv_sec < 0) { 01203 return -EINVAL; 01204 } 01205 rt_sleep_until(expire = rt_get_time() + timespec2count(rqtp)); 01206 if ((expire -= rt_get_time()) > 0) { 01207 if (rmtp) { 01208 count2timespec(expire, rmtp); 01209 } 01210 return -EINTR; 01211 } 01212 return 0; 01213 } 01214 01215 #ifdef __cplusplus 01216 } 01217 #endif /* __cplusplus */ 01218 01219 #endif /* !__KERNEL__ */ 01220 01221 #endif /* !_RTAI_POSIX_H_ */

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