Orocos Real-Time Toolkit  2.9.0
fosi.h
Go to the documentation of this file.
1 /***************************************************************************
2  copyright : (C) 2008 Klaas Gadeyne
3  email : firstname dot lastname at gmail dot com
4 
5 ***************************************************************************
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 ***************************************************************************/
13 
14 
15 #ifndef __FOSI_H
16 #define __FOSI_H
17 
18 #define _DARWIN_C_SOURCE
19 
20 #define HAVE_FOSI_API
21 
22 #ifdef __cplusplus
23 extern "C"
24 {
25 #endif
26 
27 
28 #include <stdio.h>
29 #include <pthread.h>
30 #include <mach/mach_init.h>
31 #include <mach/task.h>
32 
33 #include <errno.h>
34 
35 #include <limits.h>
36 #include <float.h>
37 #include <assert.h>
38 
39  typedef long long NANO_TIME;
40  typedef long long TICK_TIME;
41 
42  static const TICK_TIME InfiniteTicks = LLONG_MAX;
43  static const NANO_TIME InfiniteNSecs = LLONG_MAX;
44  static const double InfiniteSeconds = DBL_MAX;
45 
46 #define ORO_WAIT_ABS 0
48 #define ORO_WAIT_REL 1
51  typedef struct {
52  pthread_t thread;
53  pthread_attr_t attr;
54 
55  NANO_TIME periodMark;
56  NANO_TIME period;
57 
58  char* name;
59 
60  int priority;
61  int wait_policy;
62  } RTOS_TASK;
63 
64 
65 #define ORO_SCHED_RT SCHED_FIFO
66 #define ORO_SCHED_OTHER SCHED_OTHER
68  /*
69  * Time Related stuff
70  */
71 #include <sys/time.h>
72 #include <time.h>
73 #include <unistd.h>
74 
75  typedef struct timespec TIME_SPEC;
76 
77 #ifndef CLOCK_REALTIME
78  /* fake clock_gettime for systems like darwin */
79  #define CLOCK_REALTIME 0
80  static inline int clock_gettime(int clk_id /*ignored*/, struct timespec *tp)
81  {
82  struct timeval now;
83  int rv = gettimeofday(&now, NULL);
84  if (rv != 0){
85  tp->tv_sec = 0;
86  tp->tv_nsec = 0;
87  return rv;
88  }
89  tp->tv_sec = now.tv_sec;
90  tp->tv_nsec = now.tv_usec * 1000;
91  return 0;
92  }
93 #endif
94 
95  // high-resolution time to timespec
96  static inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
97  {
98  TIME_SPEC timevl;
99  timevl.tv_sec = hrt / 1000000000LL;
100  timevl.tv_nsec = hrt % 1000000000LL;
101  return timevl;
102  }
103 
104  static inline NANO_TIME rtos_get_time_ns( void )
105  {
106  TIME_SPEC tv;
107  clock_gettime(CLOCK_REALTIME, &tv);
108  // we can not include the C++ Time.hpp header !
109 #ifdef __cplusplus
110  return NANO_TIME( tv.tv_sec ) * 1000000000LL + NANO_TIME( tv.tv_nsec );
111 #else
112  return ( NANO_TIME ) ( tv.tv_sec * 1000000000LL ) + ( NANO_TIME ) ( tv.tv_nsec );
113 #endif
114  }
115 
120  static inline NANO_TIME rtos_get_time_ticks()
121  {
122  return rtos_get_time_ns();
123  }
124 
125  static inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp )
126  {
127  // return usleep(rqtp->tv_nsec/1000L);
128  return nanosleep( rqtp, rmtp );
129  }
130 
131  static inline long long nano2ticks( long long nano )
132  {
133  return nano;
134  }
135 
136  static inline long long ticks2nano( long long count )
137  {
138  return count;
139  }
140 
141  /*
142  * Semaphore functions
143  * See
144  * http://developer.apple.com/documentation/Darwin/Conceptual/KernelProgramming/synchronization/chapter_15_section_2.html
145  */
146 #include <mach/semaphore.h>
147  typedef semaphore_t rt_sem_t;
148 
149  static inline int rtos_sem_init(rt_sem_t* m, int value )
150  {
151  return semaphore_create(mach_task_self(), m, SYNC_POLICY_FIFO, value);
152  }
153 
154  static inline int rtos_sem_destroy(rt_sem_t* m )
155  {
156  return semaphore_destroy(mach_task_self(), *m);
157  }
158 
159  static inline int rtos_sem_signal(rt_sem_t* m )
160  {
161  return semaphore_signal(*m);
162  }
163 
164  static inline int rtos_sem_wait(rt_sem_t* m )
165  {
166  return semaphore_wait(*m);
167  }
168 
169  static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
170  {
171  TIME_SPEC delayvl = ticks2timespec(delay);
172  mach_timespec_t mach_delayvl = {
173 #ifdef __cplusplus
174  static_cast<unsigned int>(delayvl.tv_sec),
175  static_cast<clock_res_t> (delayvl.tv_nsec)
176 #else
177  delayvl.tv_sec,
178  delayvl.tv_nsec
179 #endif
180  };
181 
182  return semaphore_timedwait( *m, mach_delayvl);
183  }
184 
185  static inline int rtos_sem_trywait(rt_sem_t* m )
186  {
187  return rtos_sem_wait_timed(m,0);
188  }
189 
190  static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME abs_time )
191  {
192  TIME_SPEC timevl, delayvl;
193  TIME_SPEC arg_time = ticks2timespec( abs_time );
194  clock_gettime(CLOCK_REALTIME, &timevl);
195 
197 
198  // calculate delay from abs_time
199  delayvl.tv_sec = arg_time.tv_sec - timevl.tv_sec;
200  delayvl.tv_nsec = arg_time.tv_nsec - timevl.tv_nsec;
201  // tv_nsec is signed long in 10.6 (see sys/_structs.h)
202  if ( delayvl.tv_nsec >= 1000000000) {
203  ++delayvl.tv_sec;
204  delayvl.tv_nsec -= 1000000000;
205  }
206  if ( delayvl.tv_nsec < 0) {
207  --delayvl.tv_sec;
208  delayvl.tv_nsec += 1000000000;
209  }
210 
211  assert( 0 <= delayvl.tv_sec);
212  assert( 0 <= delayvl.tv_nsec);
213  assert( delayvl.tv_nsec < 1000000000 );
214 
215  mach_timespec_t mach_delayvl = {
216 #ifdef __cplusplus
217  static_cast<unsigned int>(delayvl.tv_sec),
218  static_cast<clock_res_t> (delayvl.tv_nsec)
219 #else
220  delayvl.tv_sec,
221  delayvl.tv_nsec
222 #endif
223  };
224  int rc = semaphore_timedwait( *m, mach_delayvl);
225  // map to return values from gnulinux, and expected by the calling layer
226  return (KERN_OPERATION_TIMED_OUT == rc ? -1 : 0);
227  }
228 
229  // semaphore_value is not supported on darwin
230  /* static inline int rtos_sem_value(rt_sem_t* m ) */
231  /* { */
232  /* int val = 0; */
233  /* if ( sem_getvalue(m, &val) == 0) */
234  /* return val; */
235  /* return -1; */
236  /* } */
237 
238  // Mutex functions - support only those needed by TLSF
239  // opaque type
241  // type created by tlsf.c (must work in C, not C++ code)
243  int rtos_mutex_init(rt_mutex_t* m);
245  int rtos_mutex_lock( rt_mutex_t* m);
246  int rtos_mutex_unlock( rt_mutex_t* m);
247 
248  static inline void rtos_enable_rt_warning()
249  {
250  }
251 
252  static inline void rtos_disable_rt_warning()
253  {
254  }
255 
256 
257 #define rtos_printf printf
258 
259 #ifdef __cplusplus
260 }
261 
262 #endif
263 #endif
int rtos_mutex_init(rt_mutex_t *m)
long long NANO_TIME
Definition: fosi.h:55
const double InfiniteSeconds
Definition: fosi.h:60
const TICK_TIME InfiniteTicks
Definition: fosi.h:58
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_sem_trywait(rt_sem_t *m)
int rtos_sem_signal(rt_sem_t *m)
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)
void rtos_disable_rt_warning()
Disallows the RTOS to print a warning when we violate real-time constraints.
int rtos_sem_destroy(rt_sem_t *m)
#define CLOCK_REALTIME
Definition: fosi.h:79
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
NANO_TIME ticks2nano(TICK_TIME count)
Time conversions from system ticks to nano seconds.
Definition: fosi.h:107
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)
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_sem_wait(rt_sem_t *m)
cyg_sem_t rt_sem_t
Definition: fosi.h:131
cyg_mutex_t rt_mutex_t
Definition: fosi.h:185