Orocos Real-Time Toolkit  2.5.0
fosi.h
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