Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00025 #ifndef __FOSI_H
00026 #define __FOSI_H
00027
00028 #define HAVE_FOSI_API
00029
00030 #ifdef _MSC_VER
00031 #include <cstdio>
00032 #include <cstdlib>
00033 #include <cerrno>
00034 #include <cstring>
00035 #include <climits>
00036 #include <cfloat>
00037 #include <cassert>
00038 #else // MINGW32
00039 #include <stdio.h>
00040 #include <stdlib.h>
00041 #include <errno.h>
00042 #include <string.h>
00043 #include <limits.h>
00044 #include <float.h>
00045 #include <assert.h>
00046 #endif
00047
00048 #include "../oro_limits.h"
00049 #include "../../rtt-config.h"
00050
00051
00052 #ifdef _MSC_VER
00053 #include <ctime>
00054 #else // MINGW32
00055 #include <sys/time.h>
00056 #include <time.h>
00057 #include <unistd.h>
00058 #endif
00059
00060 #ifdef __cplusplus
00061 extern "C"
00062 {
00063 #endif
00064
00065 #include "dlfcn.h"
00066
00067 RTT_API unsigned int sleep(unsigned int seconds);
00068
00069 #if __GNUC__ != 4
00070 RTT_API int usleep(unsigned int us);
00071 #endif
00072
00073 typedef long long NANO_TIME;
00074 typedef long long TICK_TIME;
00075
00076
00077 const TICK_TIME InfiniteTicks = LLONG_MAX;
00078 const NANO_TIME InfiniteNSecs = LLONG_MAX;
00079 const double InfiniteSeconds = DBL_MAX;
00080
00081 #define ORO_WAIT_ABS 0
00083 #define ORO_WAIT_REL 1
00086 typedef struct {
00087 HANDLE handle;
00088 DWORD threadId;
00089
00090 NANO_TIME periodMark;
00091 NANO_TIME period;
00092
00093 int sched_type;
00094 int wait_policy;
00095
00096 char* name;
00097 } RTOS_TASK;
00098
00099 #define ORO_SCHED_RT 0
00100 #define ORO_SCHED_OTHER 1
00102 //conflicts with another struct under MSVC
00103 struct oro_timespec {
00104 long tv_sec;
00105 long tv_nsec;
00106 };
00107
00108 typedef struct oro_timespec TIME_SPEC;
00109
00110
00111
00112 inline TIME_SPEC ticks2timespec(TICK_TIME hrt)
00113 {
00114 TIME_SPEC timevl;
00115 timevl.tv_sec = (long)(hrt / 1000000000LL);
00116 timevl.tv_nsec = (long)(hrt % 1000000000LL);
00117 return timevl;
00118 }
00119
00120 inline NANO_TIME rtos_get_time_ns( void )
00121 {
00122 LARGE_INTEGER freq;
00123 LARGE_INTEGER ticks;
00124 QueryPerformanceFrequency(&freq);
00125 QueryPerformanceCounter(&ticks);
00126
00127 return(NANO_TIME)(((double)ticks.QuadPart * 1000000000LL) / (double)freq.QuadPart);
00128 }
00129
00134 inline TICK_TIME rtos_get_time_ticks()
00135 {
00136 return rtos_get_time_ns();
00137 }
00138
00139 inline int win32_nanosleep(long long nano)
00140 {
00141 NANO_TIME start = rtos_get_time_ns();
00142 timeBeginPeriod(1);
00143 if (nano > 3000000L) Sleep((DWORD)(nano/1000000L) - 1);
00144 timeEndPeriod(1);
00145 while(rtos_get_time_ns() - start < nano) Sleep(0);
00146 return 0;
00147 }
00148
00149 inline int rtos_nanosleep( const TIME_SPEC * rqtp, TIME_SPEC * rmtp )
00150 {
00151 return win32_nanosleep((NANO_TIME)rqtp->tv_sec * 1000000000LL + rqtp->tv_nsec);
00152 }
00153
00159 inline
00160 long long nano2ticks( long long nano )
00161 {
00162 return nano;
00163 }
00164
00165 inline
00166 long long ticks2nano( long long count )
00167 {
00168 return count;
00169 }
00170
00171
00172
00173 typedef HANDLE rt_sem_t;
00174
00175 static inline int rtos_sem_init(rt_sem_t* m, int value )
00176 {
00177 *m = CreateSemaphore(NULL, value, 100000, NULL);
00178 return (*m != NULL) ? 0 : -1;
00179 }
00180
00181 static inline int rtos_sem_destroy(rt_sem_t* m )
00182 {
00183 CloseHandle(*m);
00184 return 0;
00185 }
00186
00187 static inline int rtos_sem_signal(rt_sem_t* m )
00188 {
00189 return (ReleaseSemaphore(*m, 1, NULL) == 0) ? -1 : 0;
00190 }
00191
00192 static inline int rtos_sem_wait(rt_sem_t* m )
00193 {
00194 return (WaitForSingleObject(*m, INFINITE) == WAIT_FAILED) ? -1 : 0;
00195 }
00196
00197 static inline int rtos_sem_trywait(rt_sem_t* m )
00198 {
00199 return (WaitForSingleObject(*m, 0) == WAIT_TIMEOUT) ? -1 : 0;
00200 }
00201
00202 static inline int rtos_sem_wait_timed(rt_sem_t* m, NANO_TIME delay )
00203 {
00204 return (WaitForSingleObject(*m, (DWORD)(delay/1000000)) == WAIT_TIMEOUT) ? -1 : 0;
00205 }
00206
00207 static inline int rtos_sem_wait_until(rt_sem_t* m, NANO_TIME abs_time )
00208 {
00209 if (abs_time < rtos_get_time_ns()) return -1;
00210 NANO_TIME delay = abs_time - rtos_get_time_ns();
00211 return rtos_sem_wait_timed(m, delay);
00212 }
00213
00214 static inline int rtos_sem_value(rt_sem_t* m )
00215 {
00216 long previous;
00217
00218 switch (WaitForSingleObject(*m, 0))
00219 {
00220 case WAIT_OBJECT_0:
00221 if (!ReleaseSemaphore(*m, 1, &previous)) return -1;
00222 return previous + 1;
00223 case WAIT_TIMEOUT: return 0;
00224 default:
00225 return -1;
00226 }
00227 }
00228
00229
00230
00231 typedef CRITICAL_SECTION rt_mutex_t;
00232 typedef CRITICAL_SECTION rt_rec_mutex_t;
00233
00234 static inline int rtos_mutex_init(rt_mutex_t* m)
00235 {
00236 InitializeCriticalSection(m);
00237 return 0;
00238 }
00239
00240 static inline int rtos_mutex_destroy(rt_mutex_t* m )
00241 {
00242 DeleteCriticalSection(m);
00243 return 0;
00244 }
00245
00246 static inline int rtos_mutex_rec_init(rt_rec_mutex_t* m)
00247 {
00248 return rtos_mutex_init(m);
00249 }
00250
00251 static inline int rtos_mutex_rec_destroy(rt_rec_mutex_t* m )
00252 {
00253 return rtos_mutex_destroy(m);
00254 }
00255
00256 static inline int rtos_mutex_lock( rt_mutex_t* m)
00257 {
00258 EnterCriticalSection(m);
00259 return 0;
00260 }
00261
00262 static inline int rtos_mutex_unlock( rt_mutex_t* m)
00263 {
00264 LeaveCriticalSection(m);
00265 return 0;
00266 }
00267
00268 static inline int rtos_mutex_trylock( rt_mutex_t* m)
00269 {
00270 if(TryEnterCriticalSection(m) != 0) return 0;
00271 return -1;
00272 }
00273
00274 static inline int rtos_mutex_rec_trylock( rt_rec_mutex_t* m)
00275 {
00276 return rtos_mutex_trylock(m);
00277 }
00278
00279 static inline int rtos_mutex_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
00280 {
00281 while (ticks2nano(rtos_get_time_ticks()) < abs_time)
00282 if (rtos_mutex_trylock(m) == 0) return 0;
00283 return -1;
00284 }
00285
00286 static inline int rtos_mutex_rec_lock_until( rt_mutex_t* m, NANO_TIME abs_time)
00287 {
00288 return rtos_mutex_lock_until(m, abs_time);
00289 }
00290
00291 static inline int rtos_mutex_rec_lock( rt_rec_mutex_t* m)
00292 {
00293 return rtos_mutex_lock(m);
00294 }
00295
00296 static inline int rtos_mutex_rec_unlock( rt_rec_mutex_t* m)
00297 {
00298 return rtos_mutex_unlock(m);
00299 }
00300
00301 static inline void rtos_enable_rt_warning()
00302 {
00303 }
00304
00305 static inline void rtos_disable_rt_warning()
00306 {
00307 }
00308
00309
00310
00311 typedef struct
00312 {
00313 enum { SIGNAL = 0, BROADCAST = 1, MAX_EVENTS = 2 };
00314
00315 HANDLE events_[MAX_EVENTS];
00316
00317
00318 unsigned int waiters_count_;
00319 CRITICAL_SECTION waiters_count_lock_;
00320
00321 } rt_cond_t;
00322
00323 static inline int rtos_cond_init(rt_cond_t *cond)
00324 {
00325
00326 cond->waiters_count_ = 0;
00327
00328
00329 cond->events_[rt_cond_t::SIGNAL] = CreateEvent (NULL,
00330 FALSE,
00331 FALSE,
00332 NULL);
00333
00334
00335 cond->events_[rt_cond_t::BROADCAST] = CreateEvent (NULL,
00336 TRUE,
00337 FALSE,
00338 NULL);
00339
00340 InitializeCriticalSection(&cond->waiters_count_lock_);
00341 return 0;
00342 }
00343
00344 static inline int rtos_cond_destroy(rt_cond_t *cond)
00345 {
00346 CloseHandle(cond->events_[rt_cond_t::SIGNAL]);
00347 CloseHandle(cond->events_[rt_cond_t::BROADCAST]);
00348
00349 DeleteCriticalSection(&cond->waiters_count_lock_);
00350
00351 return 0;
00352 }
00353
00354 static inline int rtos_cond_timedwait_internal(rt_cond_t *cond, rt_mutex_t *external_mutex, DWORD ms)
00355 {
00356
00357 EnterCriticalSection (&cond->waiters_count_lock_);
00358 cond->waiters_count_++;
00359 LeaveCriticalSection (&cond->waiters_count_lock_);
00360
00361
00362
00363
00364 LeaveCriticalSection (external_mutex);
00365
00366
00367
00368 timeBeginPeriod(1);
00369 int result = WaitForMultipleObjects (2, cond->events_, FALSE, ms);
00370 timeEndPeriod(1);
00371
00372 EnterCriticalSection (&cond->waiters_count_lock_);
00373 cond->waiters_count_--;
00374 bool last_waiter = result == WAIT_OBJECT_0 + rt_cond_t::BROADCAST && cond->waiters_count_ == 0;
00375 LeaveCriticalSection (&cond->waiters_count_lock_);
00376
00377
00378 if (last_waiter)
00379
00380
00381 ResetEvent (cond->events_[rt_cond_t::BROADCAST]);
00382
00383
00384 EnterCriticalSection (external_mutex);
00385
00386 return 0;
00387 }
00388
00389 static inline int rtos_cond_timedwait(rt_cond_t *cond, rt_mutex_t *mutex, NANO_TIME abs_time)
00390 {
00391 return rtos_cond_timedwait_internal(cond, mutex, (DWORD)(abs_time / 1000000));
00392 }
00393
00394 static inline int rtos_cond_wait(rt_cond_t *cond, rt_mutex_t *mutex)
00395 {
00396 return rtos_cond_timedwait_internal(cond, mutex, INFINITE);
00397 }
00398
00399 static inline int rtos_cond_broadcast(rt_cond_t *cond)
00400 {
00401
00402 EnterCriticalSection (&cond->waiters_count_lock_);
00403 bool have_waiters = cond->waiters_count_ > 0;
00404 LeaveCriticalSection (&cond->waiters_count_lock_);
00405
00406 if (have_waiters) SetEvent (cond->events_[rt_cond_t::BROADCAST]);
00407
00408 return 0;
00409 }
00410
00411 static inline int rtos_cond_signal (rt_cond_t *cond)
00412 {
00413
00414 EnterCriticalSection (&cond->waiters_count_lock_);
00415 bool have_waiters = cond->waiters_count_ > 0;
00416 LeaveCriticalSection (&cond->waiters_count_lock_);
00417
00418 if (have_waiters) SetEvent (cond->events_[rt_cond_t::SIGNAL]);
00419
00420 return 0;
00421 }
00422
00423 #define rtos_printf printf
00424
00425 int setenv(const char *name, const char *value, int overwrite);
00426
00427 #ifdef __cplusplus
00428 }
00429
00430 #endif
00431 #endif