$search
00001 /*************************************************************************** 00002 tag: Peter Soetens Mon Jun 10 14:42:55 CEST 2002 fosi.h 00003 00004 fosi.h - description 00005 ------------------- 00006 begin : Mon June 10 2002 00007 copyright : (C) 2002 Peter Soetens 00008 email : peter.soetens@mech.kuleuven.ac.be 00009 00010 *************************************************************************** 00011 * * 00012 * This program is free software; you can redistribute it and/or modify * 00013 * it under the terms of the GNU General Public License as published by * 00014 * the Free Software Foundation; either version 2 of the License, or * 00015 * (at your option) any later version. * 00016 * * 00017 ***************************************************************************/ 00018 00019 00027 #ifndef __FOSI_H 00028 #define __FOSI_H 00029 00030 #define HAVE_FOSI_API 00031 00032 #ifdef __cplusplus 00033 extern "C" 00034 { 00035 #endif 00036 00037 #ifndef _XOPEN_SOURCE 00038 #define _XOPEN_SOURCE 600 // use all Posix features. 00039 #endif 00040 00041 #include <stdio.h> 00042 #include <semaphore.h> 00043 #include <pthread.h> 00044 #include <errno.h> 00045 #include <string.h> 00046 #include <limits.h> 00047 #include <float.h> 00048 #include <assert.h> 00049 #include "../oro_limits.h" 00050 00051 // Time Related 00052 #include <sys/time.h> 00053 #include <time.h> 00054 #include <unistd.h> 00055 00056 00057 typedef long long NANO_TIME; 00058 typedef long long TICK_TIME; 00059 typedef struct timespec TIME_SPEC; 00060 00061 00062 static const TICK_TIME InfiniteTicks = LLONG_MAX; 00063 static const NANO_TIME InfiniteNSecs = LLONG_MAX; 00064 static const double InfiniteSeconds = DBL_MAX; 00065 00066 #define ORO_WAIT_ABS 0 00068 #define ORO_WAIT_REL 1 00071 typedef struct { 00072 pthread_t thread; 00073 pthread_attr_t attr; 00074 00075 TIME_SPEC periodMark; 00076 NANO_TIME period; 00077 00078 char* name; 00079 00080 int priority; 00081 int wait_policy; 00082 pid_t pid; 00083 } RTOS_TASK; 00084 00085 00086 #define ORO_SCHED_RT SCHED_FIFO 00087 #define ORO_SCHED_OTHER SCHED_OTHER 00090 // high-resolution time to timespec 00091 // hrt is in ticks 00092 static inline TIME_SPEC ticks2timespec(TICK_TIME hrt) 00093 { 00094 TIME_SPEC timevl; 00095 timevl.tv_sec = hrt / 1000000000LL; 00096 timevl.tv_nsec = hrt % 1000000000LL; 00097 return timevl; 00098 } 00099 00100 static inline NANO_TIME rtos_get_time_ns( void ) 00101 { 00102 00103 TIME_SPEC tv; 00104 clock_gettime(CLOCK_REALTIME, &tv); 00105 // we can not include the C++ Time.hpp header ! 00106 #ifdef __cplusplus 00107 return NANO_TIME( tv.tv_sec ) * 1000000000LL + NANO_TIME( tv.tv_nsec ); 00108 #else 00109 return ( NANO_TIME ) ( tv.tv_sec * 1000000000LL ) + ( NANO_TIME ) ( tv.tv_nsec ); 00110 #endif 00111 } 00112 00117 static inline NANO_TIME rtos_get_time_ticks() 00118 { 00119 return rtos_get_time_ns(); 00120 } 00121 00122 static inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp ) 00123 { 00124 // return usleep(rqtp->tv_nsec/1000L); 00125 return nanosleep( rqtp, rmtp ); 00126 } 00127 00133 static inline 00134 long long nano2ticks( long long nano ) 00135 { 00136 return nano; 00137 } 00138 00139 static inline 00140 long long ticks2nano( long long count ) 00141 { 00142 return count; 00143 } 00144 00145 typedef sem_t rt_sem_t; 00146 00147 static inline int rtos_sem_init(rt_sem_t* m, int value ) 00148 { 00149 return sem_init(m, 0, value); 00150 } 00151 00152 static inline int rtos_sem_destroy(rt_sem_t* m ) 00153 { 00154 return sem_destroy(m); 00155 } 00156 00157 static inline int rtos_sem_signal(rt_sem_t* m ) 00158 { 00159 return sem_post(m); 00160 } 00161 00162 static inline int rtos_sem_wait(rt_sem_t* m ) 00163 { 00164 return sem_wait(m); 00165 } 00166 00167 static inline int rtos_sem_trywait(rt_sem_t* m ) 00168 { 00169 return sem_trywait(m); 00170 } 00171 00172 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay ) 00173 { 00174 TIME_SPEC timevl, delayvl; 00175 clock_gettime(CLOCK_REALTIME, &timevl); 00176 delayvl = ticks2timespec(delay); 00177 00178 // add current time with delay, detect&correct overflows. 00179 timevl.tv_sec += delayvl.tv_sec; 00180 timevl.tv_nsec += delayvl.tv_nsec; 00181 if ( timevl.tv_nsec >= 1000000000) { 00182 ++timevl.tv_sec; 00183 timevl.tv_nsec -= 1000000000; 00184 } 00185 00186 assert( 0 <= timevl.tv_nsec); 00187 assert( timevl.tv_nsec < 1000000000 ); 00188 00191 return sem_timedwait( m, &timevl); 00192 } 00193 00194 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME abs_time ) 00195 { 00196 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00197 return sem_timedwait( m, &arg_time); 00198 } 00199 00200 static inline int rtos_sem_value(rt_sem_t* m ) 00201 { 00202 int val = 0; 00203 if ( sem_getvalue(m, &val) == 0) 00204 return val; 00205 return -1; 00206 } 00207 00208 // Mutex functions 00209 00210 typedef pthread_mutex_t rt_mutex_t; 00211 typedef pthread_mutex_t rt_rec_mutex_t; 00212 00213 static inline int rtos_mutex_init(rt_mutex_t* m) 00214 { 00215 return pthread_mutex_init(m, 0 ); 00216 } 00217 00218 static inline int rtos_mutex_destroy(rt_mutex_t* m ) 00219 { 00220 return pthread_mutex_destroy(m); 00221 } 00222 00223 static inline int rtos_mutex_rec_init(rt_mutex_t* m) 00224 { 00225 pthread_mutexattr_t ma_t; 00226 pthread_mutexattr_init(&ma_t); 00227 pthread_mutexattr_settype(&ma_t,PTHREAD_MUTEX_RECURSIVE_NP); 00228 return pthread_mutex_init(m, &ma_t ); 00229 } 00230 00231 static inline int rtos_mutex_rec_destroy(rt_mutex_t* m ) 00232 { 00233 return pthread_mutex_destroy(m); 00234 } 00235 00236 static inline int rtos_mutex_lock( rt_mutex_t* m) 00237 { 00238 return pthread_mutex_lock(m); 00239 } 00240 00241 static inline int rtos_mutex_rec_lock( rt_mutex_t* m) 00242 { 00243 return pthread_mutex_lock(m); 00244 } 00245 00246 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time) 00247 { 00248 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00249 return pthread_mutex_timedlock(m, &arg_time); 00250 } 00251 00252 static inline int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time) 00253 { 00254 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00255 return pthread_mutex_timedlock(m, &arg_time); 00256 } 00257 00258 static inline int rtos_mutex_trylock( rt_mutex_t* m) 00259 { 00260 return pthread_mutex_trylock(m); 00261 } 00262 00263 static inline int rtos_mutex_rec_trylock( rt_mutex_t* m) 00264 { 00265 return pthread_mutex_trylock(m); 00266 } 00267 00268 static inline int rtos_mutex_unlock( rt_mutex_t* m) 00269 { 00270 return pthread_mutex_unlock(m); 00271 } 00272 00273 static inline int rtos_mutex_rec_unlock( rt_mutex_t* m) 00274 { 00275 return pthread_mutex_unlock(m); 00276 } 00277 00278 static inline void rtos_enable_rt_warning() 00279 { 00280 } 00281 00282 static inline void rtos_disable_rt_warning() 00283 { 00284 } 00285 00286 typedef pthread_cond_t rt_cond_t; 00287 00288 static inline int rtos_cond_init(rt_cond_t *cond) 00289 { 00290 return pthread_cond_init(cond, NULL); 00291 } 00292 00293 static inline int rtos_cond_destroy(rt_cond_t *cond) 00294 { 00295 return pthread_cond_destroy(cond); 00296 } 00297 00298 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex) 00299 { 00300 return pthread_cond_wait(cond, mutex); 00301 } 00302 00303 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time) 00304 { 00305 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00306 return pthread_cond_timedwait(cond, mutex, &arg_time); 00307 } 00308 00309 static inline int rtos_cond_broadcast(rt_cond_t *cond) 00310 { 00311 return pthread_cond_broadcast(cond); 00312 } 00313 00314 #define rtos_printf printf 00315 00316 #ifdef __cplusplus 00317 } 00318 00319 #endif 00320 #endif