Orocos Real-Time Toolkit  2.6.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     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