Orocos Real-Time Toolkit  2.8.3
fosi.h
Go to the documentation of this file.
1 /***************************************************************************
2  tag: Peter Soetens Mon Jun 10 14:42:55 CEST 2002 fosi.h
3 
4  fosi.h - description
5  -------------------
6  begin : Mon June 10 2002
7  copyright : (C) 2002 Peter Soetens
8  email : peter.soetens@mech.kuleuven.ac.be
9 
10 ***************************************************************************
11 * *
12 * This program is free software; you can redistribute it and/or modify *
13 * it under the terms of the GNU General Public License as published by *
14 * the Free Software Foundation; either version 2 of the License, or *
15 * (at your option) any later version. *
16 * *
17 ***************************************************************************/
18 
19 
27 #ifndef __FOSI_H
28 #define __FOSI_H
29 
30 #define HAVE_FOSI_API
31 
32 #ifdef __cplusplus
33 extern "C"
34 {
35 #endif
36 
37 #ifndef _XOPEN_SOURCE
38 #define _XOPEN_SOURCE 600 // use all Posix features.
39 #endif
40 
41 #include <stdio.h>
42 #include <semaphore.h>
43 #include <pthread.h>
44 #include <errno.h>
45 #include <string.h>
46 #include <limits.h>
47 #include <float.h>
48 #include <assert.h>
49 #include "../oro_limits.h"
50 
51  // Time Related
52 #include <sys/time.h>
53 #include <time.h>
54 #include <unistd.h>
55 
56 
57  typedef long long NANO_TIME;
58  typedef long long TICK_TIME;
59  typedef struct timespec TIME_SPEC;
60 
61 
62  static const TICK_TIME InfiniteTicks = LLONG_MAX;
63  static const NANO_TIME InfiniteNSecs = LLONG_MAX;
64  static const double InfiniteSeconds = DBL_MAX;
65 
66 #define ORO_WAIT_ABS 0
68 #define ORO_WAIT_REL 1
71  typedef struct {
72  pthread_t thread;
73  pthread_attr_t attr;
74 
76  NANO_TIME period;
77 
78  char* name;
79 
80  int priority;
82  pid_t pid;
83  } RTOS_TASK;
84 
85 
86 #define ORO_SCHED_RT SCHED_FIFO
87 #define ORO_SCHED_OTHER SCHED_OTHER
90  // high-resolution time to timespec
91  // hrt is in ticks
92  static inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
93  {
94  TIME_SPEC timevl;
95  timevl.tv_sec = hrt / 1000000000LL;
96  timevl.tv_nsec = hrt % 1000000000LL;
97  return timevl;
98  }
99 
100  static inline NANO_TIME rtos_get_time_ns( void )
101  {
102  TIME_SPEC tv;
103  clock_gettime(CLOCK_MONOTONIC, &tv);
104  return ( NANO_TIME ) ( tv.tv_sec * 1000000000LL ) + ( NANO_TIME ) ( tv.tv_nsec );
105  }
106 
107  // internal use only, for rtos_mutex_trylock_for/rtos_mutex_rec_trylock_for!
108  static inline NANO_TIME rtos_get_realtime_ns( void )
109  {
110  TIME_SPEC tv;
111  clock_gettime(CLOCK_REALTIME, &tv);
112  return ( NANO_TIME ) ( tv.tv_sec * 1000000000LL ) + ( NANO_TIME ) ( tv.tv_nsec );
113  }
114 
119  static inline NANO_TIME rtos_get_time_ticks()
120  {
121  return rtos_get_time_ns();
122  }
123 
124  static inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp )
125  {
126  // return usleep(rqtp->tv_nsec/1000L);
127  return nanosleep( rqtp, rmtp );
128  }
129 
135  static inline
136  long long nano2ticks( long long nano )
137  {
138  return nano;
139  }
140 
141  static inline
142  long long ticks2nano( long long count )
143  {
144  return count;
145  }
146 
147  typedef sem_t rt_sem_t;
148 
149  static inline int rtos_sem_init(rt_sem_t* m, int value )
150  {
151  return sem_init(m, 0, value);
152  }
153 
154  static inline int rtos_sem_destroy(rt_sem_t* m )
155  {
156  return sem_destroy(m);
157  }
158 
159  static inline int rtos_sem_signal(rt_sem_t* m )
160  {
161  return sem_post(m);
162  }
163 
164  static inline int rtos_sem_wait(rt_sem_t* m )
165  {
166  return sem_wait(m);
167  }
168 
169  static inline int rtos_sem_trywait(rt_sem_t* m )
170  {
171  return sem_trywait(m);
172  }
173 
174  static inline int rtos_sem_value(rt_sem_t* m )
175  {
176  int val = 0;
177  if ( sem_getvalue(m, &val) == 0)
178  return val;
179  return -1;
180  }
181 
182  // Mutex functions
183 
184  typedef pthread_mutex_t rt_mutex_t;
185  typedef pthread_mutex_t rt_rec_mutex_t;
186 
187  static inline int rtos_mutex_init(rt_mutex_t* m)
188  {
189  return pthread_mutex_init(m, 0 );
190  }
191 
192  static inline int rtos_mutex_destroy(rt_mutex_t* m )
193  {
194  return pthread_mutex_destroy(m);
195  }
196 
197  static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
198  {
199  pthread_mutexattr_t attr;
200  int ret = pthread_mutexattr_init(&attr);
201  if (ret != 0) return ret;
202 
203  // make mutex recursive
204  ret = pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE_NP);
205  if (ret != 0) return ret;
206 
207  ret = pthread_mutex_init(m, &attr);
208 
209  pthread_mutexattr_destroy(&attr);
210  return ret;
211  }
212 
213  static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
214  {
215  return pthread_mutex_destroy(m);
216  }
217 
218  static inline int rtos_mutex_lock( rt_mutex_t* m)
219  {
220  return pthread_mutex_lock(m);
221  }
222 
223  static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
224  {
225  return pthread_mutex_lock(m);
226  }
227 
228  static inline int rtos_mutex_trylock_for( rt_mutex_t* m, NANO_TIME relative_time)
229  {
230  // pthread_mutex_timedlock() does not support relative timeouts, nor CLOCK_MONOTONIC.
231  // Workaround: add the relative time period to an absolute time retrieved
232  // by rtos_get_realtime_ns() using CLOCK_REALTIME (may be affected by time
233  // adjustments while waiting)
234  TIME_SPEC arg_time = ticks2timespec( rtos_get_realtime_ns() + relative_time );
235  return pthread_mutex_timedlock(m, &arg_time);
236  }
237 
238  static inline int rtos_mutex_rec_trylock_for( rt_rec_mutex_t* m, NANO_TIME relative_time)
239  {
240  // pthread_mutex_timedlock() does not support relative timeouts, nor CLOCK_MONOTONIC.
241  // Workaround: add the relative time period to an absolute time retrieved
242  // by rtos_get_realtime_ns() using CLOCK_REALTIME (may be affected by time
243  // adjustments while waiting)
244  TIME_SPEC arg_time = ticks2timespec( rtos_get_realtime_ns() + relative_time );
245  return pthread_mutex_timedlock(m, &arg_time);
246  }
247 
248  static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
249  {
250  // pthread_mutex_timedlock() does not accept an absolute CLOCK_MONOTONIC timestamp.
251  // Workaround: convert abs_time to a relative time using rtos_get_time_ns()
252  // and fall back to rtos_mutex_trylock_for().
253  NANO_TIME relative_time = abs_time - rtos_get_time_ns();
254  if (relative_time < 0) return ETIMEDOUT;
255  return rtos_mutex_trylock_for( m, relative_time );
256  }
257 
258  static inline int rtos_mutex_rec_lock_until( rt_rec_mutex_t* m, NANO_TIME abs_time)
259  {
260  // pthread_mutex_timedlock() does not accept an absolute CLOCK_MONOTONIC timestamp.
261  // Workaround: convert abs_time to a relative time using rtos_get_time_ns()
262  // and fall back to rtos_mutex_rec_trylock_for().
263  NANO_TIME relative_time = abs_time - rtos_get_time_ns();
264  if (relative_time < 0) return ETIMEDOUT;
265  return rtos_mutex_rec_trylock_for( m, relative_time );
266  }
267 
268  static inline int rtos_mutex_trylock( rt_mutex_t* m)
269  {
270  return pthread_mutex_trylock(m);
271  }
272 
273  static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
274  {
275  return pthread_mutex_trylock(m);
276  }
277 
278  static inline int rtos_mutex_unlock( rt_mutex_t* m)
279  {
280  return pthread_mutex_unlock(m);
281  }
282 
283  static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
284  {
285  return pthread_mutex_unlock(m);
286  }
287 
288  static inline void rtos_enable_rt_warning()
289  {
290  }
291 
292  static inline void rtos_disable_rt_warning()
293  {
294  }
295 
296  typedef pthread_cond_t rt_cond_t;
297 
298  static inline int rtos_cond_init(rt_cond_t *cond)
299  {
300  pthread_condattr_t attr;
301  int ret = pthread_condattr_init(&attr);
302  if (ret != 0) return ret;
303 
304  // set the clock selection condition variable attribute to CLOCK_MONOTONIC
305  ret = pthread_condattr_setclock(&attr, CLOCK_MONOTONIC);
306  if (ret != 0) {
307  pthread_condattr_destroy(&attr);
308  return ret;
309  }
310 
311  ret = pthread_cond_init(cond, &attr);
312  pthread_condattr_destroy(&attr);
313 
314  return ret;
315  }
316 
317  static inline int rtos_cond_destroy(rt_cond_t *cond)
318  {
319  return pthread_cond_destroy(cond);
320  }
321 
322  static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
323  {
324  return pthread_cond_wait(cond, mutex);
325  }
326 
327  static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
328  {
329  TIME_SPEC arg_time = ticks2timespec( abs_time );
330  return pthread_cond_timedwait(cond, mutex, &arg_time);
331  }
332 
333  static inline int rtos_cond_broadcast(rt_cond_t *cond)
334  {
335  return pthread_cond_broadcast(cond);
336  }
337 
338 #define rtos_printf printf
339 
340 #ifdef __cplusplus
341 }
342 
343 #endif
344 #endif
int rtos_mutex_init(rt_mutex_t *m)
long long NANO_TIME
Definition: fosi.h:55
int priority
Definition: fosi.h:80
const double InfiniteSeconds
Definition: fosi.h:60
int wait_policy
Definition: fosi.h:81
int rtos_mutex_rec_lock(rt_rec_mutex_t *m)
const TICK_TIME InfiniteTicks
Definition: fosi.h:58
pid_t pid
Definition: fosi.h:82
int rtos_cond_destroy(rt_cond_t *cond)
NANO_TIME rtos_get_time_ns(void)
Get "system" time in nanoseconds.
Definition: fosi.h:113
int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
Definition: fosi.h:180
const NANO_TIME InfiniteNSecs
Definition: fosi.h:59
#define LLONG_MAX
Definition: oro_limits.h:47
int rtos_mutex_rec_init(rt_rec_mutex_t *m)
int rtos_sem_trywait(rt_sem_t *m)
int rtos_mutex_rec_trylock(rt_rec_mutex_t *m)
int rtos_sem_signal(rt_sem_t *m)
int rtos_mutex_rec_trylock_for(rt_rec_mutex_t *m, NANO_TIME relative_time)
int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
pthread_t thread
Definition: fosi.h:72
int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
TIME_SPEC ticks2timespec(TICK_TIME hrt)
Definition: fosi.h:146
cyg_tick_count_t TICK_TIME
Definition: fosi.h:56
int rtos_mutex_unlock(rt_mutex_t *m)
int rtos_mutex_rec_unlock(rt_rec_mutex_t *m)
void rtos_disable_rt_warning()
Disallows the RTOS to print a warning when we violate real-time constraints.
TIME_SPEC periodMark
Definition: fosi.h:75
int rtos_sem_destroy(rt_sem_t *m)
pthread_cond_t rt_cond_t
Definition: fosi.h:296
int rtos_mutex_lock_until(rt_mutex_t *m, NANO_TIME abs_time)
#define CLOCK_REALTIME
Definition: fosi.h:79
int rtos_mutex_rec_lock_until(rt_rec_mutex_t *m, NANO_TIME abs_time)
int rtos_mutex_lock(rt_mutex_t *m)
TICK_TIME rtos_get_time_ticks(void)
Get "system" time in ticks FIXME see https://proj.fmtc.be/orocos-bugzilla/show_bug.cgi?id=60
Definition: fosi.h:118
int rtos_mutex_trylock(rt_mutex_t *m)
NANO_TIME ticks2nano(TICK_TIME count)
Time conversions from system ticks to nano seconds.
Definition: fosi.h:107
cyg_recursive_mutex_t rt_rec_mutex_t
Definition: fosi.h:186
int rtos_sem_init(rt_sem_t *m, int value)
All these should return zero in case of succes.
TICK_TIME nano2ticks(NANO_TIME nano)
Time conversions from nano seconds to system ticks.
Definition: fosi.h:100
int rtos_mutex_destroy(rt_mutex_t *m)
int rtos_sem_value(rt_sem_t *m)
int rtos_mutex_trylock_for(rt_mutex_t *m, NANO_TIME relative_time)
struct MyTask RTOS_TASK
void rtos_enable_rt_warning()
Allows the RTOS to print a warning when we violate real-time constraints.
struct timespec TIME_SPEC
Definition: fosi.h:97
int rtos_cond_init(rt_cond_t *cond)
int rtos_sem_wait(rt_sem_t *m)
int rtos_cond_broadcast(rt_cond_t *cond)
cyg_sem_t rt_sem_t
Definition: fosi.h:131
int rtos_mutex_rec_destroy(rt_rec_mutex_t *m)
cyg_mutex_t rt_mutex_t
Definition: fosi.h:185
pthread_attr_t attr
Definition: fosi.h:73