win32/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  * This library is free software; you can redistribute it and/or *
12  * modify it under the terms of the GNU General Public *
13  * License as published by the Free Software Foundation; *
14  * version 2 of the License. *
15  * *
16  * As a special exception, you may use this file as part of a free *
17  * software library without restriction. Specifically, if other files *
18  * instantiate templates or use macros or inline functions from this *
19  * file, or you compile this file and link it with other files to *
20  * produce an executable, this file does not by itself cause the *
21  * resulting executable to be covered by the GNU General Public *
22  * License. This exception does not however invalidate any other *
23  * reasons why the executable file might be covered by the GNU General *
24  * Public License. *
25  * *
26  * This library is distributed in the hope that it will be useful, *
27  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
28  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
29  * General Public License for more details. *
30  * *
31  * You should have received a copy of the GNU General Public *
32  * License along with this library; if not, write to the Free Software *
33  * Foundation, Inc., 59 Temple Place, *
34  * Suite 330, Boston, MA 02111-1307 USA *
35  * *
36  ***************************************************************************/
37 
43 #ifndef __FOSI_H
44 #define __FOSI_H
45 
46 #define HAVE_FOSI_API
47 
48 #ifdef _MSC_VER
49 #include <cstdio>
50 #include <cstdlib>
51 #include <cerrno>
52 #include <cstring>
53 #include <climits>
54 #include <cfloat>
55 #include <cassert>
56 #else // MINGW32
57 #include <stdio.h>
58 #include <stdlib.h>
59 #include <errno.h>
60 #include <string.h>
61 #include <limits.h>
62 #include <float.h>
63 #include <assert.h>
64 #endif
65 
66 #include "../oro_limits.h"
67 #include "../../rtt-config.h"
68 
69  // Time Related
70 #ifdef _MSC_VER
71 #include <ctime>
72 #else // MINGW32
73 #include <sys/time.h>
74 #include <time.h>
75 #include <unistd.h>
76 #endif
77 
78 #ifdef __cplusplus
79 extern "C"
80 {
81 #endif
82 
83 #include "dlfcn.h"
84 
85  RTT_API unsigned int sleep(unsigned int seconds);
86 
87 #if __GNUC__ != 4
88  RTT_API int usleep(unsigned int us);
89 #endif
90 
91  typedef long long NANO_TIME;
92  typedef long long TICK_TIME;
93 
94  // TODO
95  const TICK_TIME InfiniteTicks = LLONG_MAX;
96  const NANO_TIME InfiniteNSecs = LLONG_MAX;
97  const double InfiniteSeconds = DBL_MAX;
98 
99 #define ORO_WAIT_ABS 0
101 #define ORO_WAIT_REL 1
104  typedef struct {
105  HANDLE handle;
106  DWORD threadId;
107 
108  NANO_TIME periodMark;
109  NANO_TIME period;
110 
111  int sched_type; // currently not used
112  int wait_policy;
113 
114  char* name;
115  } RTOS_TASK;
116 
117 #define ORO_SCHED_RT 0
118 #define ORO_SCHED_OTHER 1
120  //conflicts with another struct under MSVC
121  struct oro_timespec {
122  long tv_sec;
123  long tv_nsec;
124  };
125 
126  typedef struct oro_timespec TIME_SPEC;
127 
128  // high-resolution time to timespec
129  // hrt is in ticks
131  {
132  TIME_SPEC timevl;
133  timevl.tv_sec = (long)(hrt / 1000000000LL);
134  timevl.tv_nsec = (long)(hrt % 1000000000LL);
135  return timevl;
136  }
137 
139  {
140  LARGE_INTEGER freq;
141  LARGE_INTEGER ticks;
142  QueryPerformanceFrequency(&freq);
143  QueryPerformanceCounter(&ticks);
144 
145  return(NANO_TIME)(((double)ticks.QuadPart * 1000000000LL) / (double)freq.QuadPart);
146  }
147 
153  {
154  return rtos_get_time_ns();
155  }
156 
157  inline int win32_nanosleep(long long nano)
158  {
159  NANO_TIME start = rtos_get_time_ns();
160  timeBeginPeriod(1);
161  if (nano > 3000000L) Sleep((DWORD)(nano/1000000L) - 1);
162  timeEndPeriod(1);
163  while(rtos_get_time_ns() - start < nano) Sleep(0);
164  return 0;
165  }
166 
167  inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp )
168  {
169  return win32_nanosleep((NANO_TIME)rqtp->tv_sec * 1000000000LL + rqtp->tv_nsec);
170  }
171 
177  inline
178  long long nano2ticks( long long nano )
179  {
180  return nano;
181  }
182 
183  inline
184  long long ticks2nano( long long count )
185  {
186  return count;
187  }
188 
189  // Semaphore functions
190 
191  typedef HANDLE rt_sem_t;
192 
193  static inline int rtos_sem_init(rt_sem_t* m, int value )
194  {
195  *m = CreateSemaphore(NULL, value, 100000, NULL);
196  return (*m != NULL) ? 0 : -1;
197  }
198 
199  static inline int rtos_sem_destroy(rt_sem_t* m )
200  {
201  CloseHandle(*m);
202  return 0;
203  }
204 
205  static inline int rtos_sem_signal(rt_sem_t* m )
206  {
207  return (ReleaseSemaphore(*m, 1, NULL) == 0) ? -1 : 0;
208  }
209 
210  static inline int rtos_sem_wait(rt_sem_t* m )
211  {
212  return (WaitForSingleObject(*m, INFINITE) == WAIT_FAILED) ? -1 : 0;
213  }
214 
215  static inline int rtos_sem_trywait(rt_sem_t* m )
216  {
217  return (WaitForSingleObject(*m, 0) == WAIT_TIMEOUT) ? -1 : 0;
218  }
219 
220  static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
221  {
222  return (WaitForSingleObject(*m, (DWORD)(delay/1000000)) == WAIT_TIMEOUT) ? -1 : 0;
223  }
224 
225  static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME abs_time )
226  {
227  if (abs_time < rtos_get_time_ns()) return -1;
228  NANO_TIME delay = abs_time - rtos_get_time_ns();
229  return rtos_sem_wait_timed(m, delay);
230  }
231 
232  static inline int rtos_sem_value(rt_sem_t* m )
233  {
234  long previous;
235 
236  switch (WaitForSingleObject(*m, 0))
237  {
238  case WAIT_OBJECT_0:
239  if (!ReleaseSemaphore(*m, 1, &previous)) return -1;
240  return previous + 1;
241  case WAIT_TIMEOUT: return 0;
242  default:
243  return -1;
244  }
245  }
246 
247  // Mutex functions
248 
249  typedef CRITICAL_SECTION rt_mutex_t;
250  typedef CRITICAL_SECTION rt_rec_mutex_t;
251 
252  static inline int rtos_mutex_init(rt_mutex_t* m)
253  {
254  InitializeCriticalSection(m);
255  return 0;
256  }
257 
258  static inline int rtos_mutex_destroy(rt_mutex_t* m )
259  {
260  DeleteCriticalSection(m);
261  return 0;
262  }
263 
264  static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
265  {
266  return rtos_mutex_init(m);
267  }
268 
269  static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
270  {
271  return rtos_mutex_destroy(m);
272  }
273 
274  static inline int rtos_mutex_lock( rt_mutex_t* m)
275  {
276  EnterCriticalSection(m);
277  return 0;
278  }
279 
280  static inline int rtos_mutex_unlock( rt_mutex_t* m)
281  {
282  LeaveCriticalSection(m);
283  return 0;
284  }
285 
286  static inline int rtos_mutex_trylock( rt_mutex_t* m)
287  {
288  if(TryEnterCriticalSection(m) != 0) return 0;
289  return -1;
290  }
291 
292  static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
293  {
294  return rtos_mutex_trylock(m);
295  }
296 
297  static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
298  {
299  while (ticks2nano(rtos_get_time_ticks()) < abs_time)
300  if (rtos_mutex_trylock(m) == 0) return 0;
301  return -1;
302  }
303 
304  static inline int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
305  {
306  return rtos_mutex_lock_until(m, abs_time);
307  }
308 
309  static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
310  {
311  return rtos_mutex_lock(m);
312  }
313 
314  static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
315  {
316  return rtos_mutex_unlock(m);
317  }
318 
319  static inline void rtos_enable_rt_warning()
320  {
321  }
322 
323  static inline void rtos_disable_rt_warning()
324  {
325  }
326 
327  // Condition variable implementation (SetEvent solution from ACE framework)
328 
329  typedef struct
330  {
331  enum { SIGNAL = 0, BROADCAST = 1, MAX_EVENTS = 2 };
332 
333  HANDLE events_[MAX_EVENTS];
334 
335  // Count of the number of waiters.
336  unsigned int waiters_count_;
337  CRITICAL_SECTION waiters_count_lock_;
338 
339  } rt_cond_t;
340 
341  static inline int rtos_cond_init(rt_cond_t *cond)
342  {
343  // Initialize the count to 0.
344  cond->waiters_count_ = 0;
345 
346  // Create an auto-reset event.
347  cond->events_[rt_cond_t::SIGNAL] = CreateEvent (NULL, // no security
348  FALSE, // auto-reset event
349  FALSE, // non-signaled initially
350  NULL); // unnamed
351 
352  // Create a manual-reset event.
353  cond->events_[rt_cond_t::BROADCAST] = CreateEvent (NULL, // no security
354  TRUE, // manual-reset
355  FALSE, // non-signaled initially
356  NULL); // unnamed
357 
358  InitializeCriticalSection(&cond->waiters_count_lock_);
359  return 0;
360  }
361 
362  static inline int rtos_cond_destroy(rt_cond_t *cond)
363  {
364  CloseHandle(cond->events_[rt_cond_t::SIGNAL]);
365  CloseHandle(cond->events_[rt_cond_t::BROADCAST]);
366 
367  DeleteCriticalSection(&cond->waiters_count_lock_);
368 
369  return 0;
370  }
371 
372  static inline int rtos_cond_timedwait_internal(rt_cond_t *cond, rt_mutex_t *external_mutex, DWORD ms)
373  {
374  // Avoid race conditions.
375  EnterCriticalSection (&cond->waiters_count_lock_);
376  cond->waiters_count_++;
377  LeaveCriticalSection (&cond->waiters_count_lock_);
378 
379  // It's ok to release the <external_mutex> here since Win32
380  // manual-reset events maintain state when used with
381  // <SetEvent>. This avoids the "lost wakeup" bug...
382  LeaveCriticalSection (external_mutex);
383 
384  // Wait for either event to become signaled due to <pthread_cond_signal>
385  // being called or <pthread_cond_broadcast> being called.
386  timeBeginPeriod(1);
387  int result = WaitForMultipleObjects (2, cond->events_, FALSE, ms);
388  timeEndPeriod(1);
389 
390  EnterCriticalSection (&cond->waiters_count_lock_);
391  cond->waiters_count_--;
392  bool last_waiter = result == WAIT_OBJECT_0 + rt_cond_t::BROADCAST && cond->waiters_count_ == 0;
393  LeaveCriticalSection (&cond->waiters_count_lock_);
394 
395  // Some thread called <pthread_cond_broadcast>.
396  if (last_waiter)
397  // We're the last waiter to be notified or to stop waiting, so
398  // reset the manual event.
399  ResetEvent (cond->events_[rt_cond_t::BROADCAST]);
400 
401  // Reacquire the <external_mutex>.
402  EnterCriticalSection (external_mutex);
403 
404  return 0;
405  }
406 
407  static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
408  {
409  return rtos_cond_timedwait_internal(cond, mutex, (DWORD)(abs_time / 1000000));
410  }
411 
412  static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
413  {
414  return rtos_cond_timedwait_internal(cond, mutex, INFINITE);
415  }
416 
417  static inline int rtos_cond_broadcast(rt_cond_t *cond)
418  {
419  // Avoid race conditions.
420  EnterCriticalSection (&cond->waiters_count_lock_);
421  bool have_waiters = cond->waiters_count_ > 0;
422  LeaveCriticalSection (&cond->waiters_count_lock_);
423 
424  if (have_waiters) SetEvent (cond->events_[rt_cond_t::BROADCAST]);
425 
426  return 0;
427  }
428 
429  static inline int rtos_cond_signal (rt_cond_t *cond)
430  {
431  // Avoid race conditions.
432  EnterCriticalSection (&cond->waiters_count_lock_);
433  bool have_waiters = cond->waiters_count_ > 0;
434  LeaveCriticalSection (&cond->waiters_count_lock_);
435 
436  if (have_waiters) SetEvent (cond->events_[rt_cond_t::SIGNAL]);
437 
438  return 0;
439  }
440 
441 #define rtos_printf printf
442 
443 int setenv(const char *name, const char *value, int overwrite);
444 
445 #ifdef __cplusplus
446 }
447 
448 #endif
449 #endif
long long NANO_TIME
Definition: ecos/fosi.h:67
static void rtos_disable_rt_warning()
Definition: win32/fosi.h:323
static int rtos_mutex_rec_unlock(rt_rec_mutex_t *m)
Definition: win32/fosi.h:314
static int rtos_sem_wait_until(rt_sem_t *m, NANO_TIME abs_time)
Definition: win32/fosi.h:225
static int rtos_mutex_destroy(rt_mutex_t *m)
Definition: win32/fosi.h:258
int setenv(const char *name, const char *value, int overwrite)
Definition: fosi.cpp:64
static int rtos_mutex_rec_lock(rt_rec_mutex_t *m)
Definition: win32/fosi.h:309
static int rtos_sem_destroy(rt_sem_t *m)
Definition: win32/fosi.h:199
const double InfiniteSeconds
Definition: win32/fosi.h:97
static int rtos_mutex_rec_trylock(rt_rec_mutex_t *m)
Definition: win32/fosi.h:292
static int rtos_cond_timedwait_internal(rt_cond_t *cond, rt_mutex_t *external_mutex, DWORD ms)
Definition: win32/fosi.h:372
#define LLONG_MAX
Definition: oro_limits.h:47
static int rtos_sem_trywait(rt_sem_t *m)
Definition: win32/fosi.h:215
static int rtos_mutex_lock(rt_mutex_t *m)
Definition: win32/fosi.h:274
unsigned int waiters_count_
Definition: win32/fosi.h:336
int sched_type
Definition: win32/fosi.h:111
static int rtos_mutex_init(rt_mutex_t *m)
Definition: win32/fosi.h:252
static int rtos_cond_init(rt_cond_t *cond)
Definition: win32/fosi.h:341
struct cond_struct rt_cond_t
CRITICAL_SECTION rt_rec_mutex_t
Definition: win32/fosi.h:250
long long NANO_TIME
Definition: win32/fosi.h:91
long long TICK_TIME
Definition: win32/fosi.h:92
const NANO_TIME InfiniteNSecs
Definition: win32/fosi.h:96
int win32_nanosleep(long long nano)
Definition: win32/fosi.h:157
NANO_TIME rtos_get_time_ns(void)
Definition: win32/fosi.h:138
static int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
Definition: win32/fosi.h:412
TIME_SPEC ticks2timespec(TICK_TIME hrt)
Definition: win32/fosi.h:130
static int rtos_mutex_rec_init(rt_rec_mutex_t *m)
Definition: win32/fosi.h:264
static int rtos_sem_wait(rt_sem_t *m)
Definition: win32/fosi.h:210
cyg_tick_count_t TICK_TIME
Definition: ecos/fosi.h:68
static int rtos_mutex_trylock(rt_mutex_t *m)
Definition: win32/fosi.h:286
CRITICAL_SECTION rt_mutex_t
Definition: win32/fosi.h:249
static int rtos_mutex_unlock(rt_mutex_t *m)
Definition: win32/fosi.h:280
HANDLE handle
Definition: win32/fosi.h:105
HANDLE events_[MAX_EVENTS]
Definition: win32/fosi.h:333
static int rtos_sem_init(rt_sem_t *m, int value)
Definition: win32/fosi.h:193
long long nano2ticks(long long nano)
Definition: win32/fosi.h:178
static int rtos_cond_signal(rt_cond_t *cond)
Definition: win32/fosi.h:429
static int rtos_mutex_rec_destroy(rt_rec_mutex_t *m)
Definition: win32/fosi.h:269
static int rtos_sem_signal(rt_sem_t *m)
Definition: win32/fosi.h:205
TICK_TIME rtos_get_time_ticks()
Definition: win32/fosi.h:152
static int rtos_cond_broadcast(rt_cond_t *cond)
Definition: win32/fosi.h:417
RTT_API unsigned int sleep(unsigned int seconds)
Definition: fosi.cpp:51
HANDLE rt_sem_t
Definition: win32/fosi.h:191
long long ticks2nano(long long count)
Definition: win32/fosi.h:184
RTT_API int usleep(unsigned int us)
Definition: fosi.cpp:58
static int rtos_mutex_rec_lock_until(rt_mutex_t *m, NANO_TIME abs_time)
Definition: win32/fosi.h:304
const TICK_TIME InfiniteTicks
Definition: win32/fosi.h:95
DWORD threadId
Definition: win32/fosi.h:106
static int rtos_cond_destroy(rt_cond_t *cond)
Definition: win32/fosi.h:362
static int rtos_sem_wait_timed(rt_sem_t *m, NANO_TIME delay)
Definition: win32/fosi.h:220
CRITICAL_SECTION waiters_count_lock_
Definition: win32/fosi.h:337
static int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
Definition: win32/fosi.h:407
int rtos_nanosleep(const TIME_SPEC *rqtp, TIME_SPEC *rmtp)
Definition: win32/fosi.h:167
struct MyTask RTOS_TASK
static int rtos_mutex_lock_until(rt_mutex_t *m, NANO_TIME abs_time)
Definition: win32/fosi.h:297
struct timespec TIME_SPEC
Definition: ecos/fosi.h:109
cyg_sem_t rt_sem_t
Definition: ecos/fosi.h:143
static int rtos_sem_value(rt_sem_t *m)
Definition: win32/fosi.h:232
static void rtos_enable_rt_warning()
Definition: win32/fosi.h:319
cyg_mutex_t rt_mutex_t
Definition: ecos/fosi.h:197


rtt
Author(s): RTT Developers
autogenerated on Fri Oct 25 2019 03:59:33