Orocos Real-Time Toolkit
2.5.0
|
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 } RTOS_TASK; 00083 00084 00085 #define ORO_SCHED_RT SCHED_FIFO 00086 #define ORO_SCHED_OTHER SCHED_OTHER 00089 // high-resolution time to timespec 00090 // hrt is in ticks 00091 static inline TIME_SPEC ticks2timespec(TICK_TIME hrt) 00092 { 00093 TIME_SPEC timevl; 00094 timevl.tv_sec = hrt / 1000000000LL; 00095 timevl.tv_nsec = hrt % 1000000000LL; 00096 return timevl; 00097 } 00098 00099 static inline NANO_TIME rtos_get_time_ns( void ) 00100 { 00101 00102 TIME_SPEC tv; 00103 clock_gettime(CLOCK_REALTIME, &tv); 00104 // we can not include the C++ Time.hpp header ! 00105 #ifdef __cplusplus 00106 return NANO_TIME( tv.tv_sec ) * 1000000000LL + NANO_TIME( tv.tv_nsec ); 00107 #else 00108 return ( NANO_TIME ) ( tv.tv_sec * 1000000000LL ) + ( NANO_TIME ) ( tv.tv_nsec ); 00109 #endif 00110 } 00111 00116 static inline NANO_TIME rtos_get_time_ticks() 00117 { 00118 return rtos_get_time_ns(); 00119 } 00120 00121 static inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp ) 00122 { 00123 // return usleep(rqtp->tv_nsec/1000L); 00124 return nanosleep( rqtp, rmtp ); 00125 } 00126 00132 static inline 00133 long long nano2ticks( long long nano ) 00134 { 00135 return nano; 00136 } 00137 00138 static inline 00139 long long ticks2nano( long long count ) 00140 { 00141 return count; 00142 } 00143 00144 typedef sem_t rt_sem_t; 00145 00146 static inline int rtos_sem_init(rt_sem_t* m, int value ) 00147 { 00148 return sem_init(m, 0, value); 00149 } 00150 00151 static inline int rtos_sem_destroy(rt_sem_t* m ) 00152 { 00153 return sem_destroy(m); 00154 } 00155 00156 static inline int rtos_sem_signal(rt_sem_t* m ) 00157 { 00158 return sem_post(m); 00159 } 00160 00161 static inline int rtos_sem_wait(rt_sem_t* m ) 00162 { 00163 return sem_wait(m); 00164 } 00165 00166 static inline int rtos_sem_trywait(rt_sem_t* m ) 00167 { 00168 return sem_trywait(m); 00169 } 00170 00171 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay ) 00172 { 00173 TIME_SPEC timevl, delayvl; 00174 clock_gettime(CLOCK_REALTIME, &timevl); 00175 delayvl = ticks2timespec(delay); 00176 00177 // add current time with delay, detect&correct overflows. 00178 timevl.tv_sec += delayvl.tv_sec; 00179 timevl.tv_nsec += delayvl.tv_nsec; 00180 if ( timevl.tv_nsec >= 1000000000) { 00181 ++timevl.tv_sec; 00182 timevl.tv_nsec -= 1000000000; 00183 } 00184 00185 assert( 0 <= timevl.tv_nsec); 00186 assert( timevl.tv_nsec < 1000000000 ); 00187 00190 return sem_timedwait( m, &timevl); 00191 } 00192 00193 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME abs_time ) 00194 { 00195 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00196 return sem_timedwait( m, &arg_time); 00197 } 00198 00199 static inline int rtos_sem_value(rt_sem_t* m ) 00200 { 00201 int val = 0; 00202 if ( sem_getvalue(m, &val) == 0) 00203 return val; 00204 return -1; 00205 } 00206 00207 // Mutex functions 00208 00209 typedef pthread_mutex_t rt_mutex_t; 00210 typedef pthread_mutex_t rt_rec_mutex_t; 00211 00212 static inline int rtos_mutex_init(rt_mutex_t* m) 00213 { 00214 return pthread_mutex_init(m, 0 ); 00215 } 00216 00217 static inline int rtos_mutex_destroy(rt_mutex_t* m ) 00218 { 00219 return pthread_mutex_destroy(m); 00220 } 00221 00222 static inline int rtos_mutex_rec_init(rt_mutex_t* m) 00223 { 00224 pthread_mutexattr_t ma_t; 00225 pthread_mutexattr_init(&ma_t); 00226 pthread_mutexattr_settype(&ma_t,PTHREAD_MUTEX_RECURSIVE_NP); 00227 return pthread_mutex_init(m, &ma_t ); 00228 } 00229 00230 static inline int rtos_mutex_rec_destroy(rt_mutex_t* m ) 00231 { 00232 return pthread_mutex_destroy(m); 00233 } 00234 00235 static inline int rtos_mutex_lock( rt_mutex_t* m) 00236 { 00237 return pthread_mutex_lock(m); 00238 } 00239 00240 static inline int rtos_mutex_rec_lock( rt_mutex_t* m) 00241 { 00242 return pthread_mutex_lock(m); 00243 } 00244 00245 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time) 00246 { 00247 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00248 return pthread_mutex_timedlock(m, &arg_time); 00249 } 00250 00251 static inline int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time) 00252 { 00253 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00254 return pthread_mutex_timedlock(m, &arg_time); 00255 } 00256 00257 static inline int rtos_mutex_trylock( rt_mutex_t* m) 00258 { 00259 return pthread_mutex_trylock(m); 00260 } 00261 00262 static inline int rtos_mutex_rec_trylock( rt_mutex_t* m) 00263 { 00264 return pthread_mutex_trylock(m); 00265 } 00266 00267 static inline int rtos_mutex_unlock( rt_mutex_t* m) 00268 { 00269 return pthread_mutex_unlock(m); 00270 } 00271 00272 static inline int rtos_mutex_rec_unlock( rt_mutex_t* m) 00273 { 00274 return pthread_mutex_unlock(m); 00275 } 00276 00277 static inline void rtos_enable_rt_warning() 00278 { 00279 } 00280 00281 static inline void rtos_disable_rt_warning() 00282 { 00283 } 00284 00285 typedef pthread_cond_t rt_cond_t; 00286 00287 static inline int rtos_cond_init(rt_cond_t *cond) 00288 { 00289 return pthread_cond_init(cond, NULL); 00290 } 00291 00292 static inline int rtos_cond_destroy(rt_cond_t *cond) 00293 { 00294 return pthread_cond_destroy(cond); 00295 } 00296 00297 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex) 00298 { 00299 return pthread_cond_wait(cond, mutex); 00300 } 00301 00302 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time) 00303 { 00304 TIME_SPEC arg_time = ticks2timespec( abs_time ); 00305 return pthread_cond_timedwait(cond, mutex, &arg_time); 00306 } 00307 00308 static inline int rtos_cond_broadcast(rt_cond_t *cond) 00309 { 00310 return pthread_cond_broadcast(cond); 00311 } 00312 00313 #define rtos_printf printf 00314 00315 #ifdef __cplusplus 00316 } 00317 00318 #endif 00319 #endif