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
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039 #include "../ThreadInterface.hpp"
00040 #include "fosi.h"
00041 #include "../fosi_internal_interface.hpp"
00042 #include "../../Logger.hpp"
00043 #include <cassert>
00044 #include <iostream>
00045 #include <cstdlib>
00046 using namespace std;
00047
00048
00049
00050
00051 #define INTERNAL_QUAL
00052
00053 namespace RTT
00054 { namespace os {
00055
00056 void ErrorHandler(LPTSTR lpszFunction)
00057 {
00058
00059
00060 LPVOID lpMsgBuf;
00061 LPVOID lpDisplayBuf;
00062 DWORD dw = GetLastError();
00063
00064 FormatMessage(
00065 FORMAT_MESSAGE_ALLOCATE_BUFFER |
00066 FORMAT_MESSAGE_FROM_SYSTEM |
00067 FORMAT_MESSAGE_IGNORE_INSERTS,
00068 NULL,
00069 dw,
00070 MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
00071 (LPTSTR) &lpMsgBuf,
00072 0, NULL );
00073
00074
00075
00076 lpDisplayBuf = (LPVOID)LocalAlloc(LMEM_ZEROINIT,
00077 (lstrlen((LPCTSTR) lpMsgBuf) + lstrlen((LPCTSTR) lpszFunction) + 40) * sizeof(TCHAR));
00078
00079
00080
00081
00082
00083 MessageBox(NULL, (LPCTSTR) lpDisplayBuf, TEXT("Error"), MB_OK);
00084
00085
00086
00087 LocalFree(lpMsgBuf);
00088 LocalFree(lpDisplayBuf);
00089 }
00090
00091
00092 struct ThreadWrapperData {
00093 void* (*realThread)(void*);
00094 void* realData;
00095 };
00096
00097 DWORD WINAPI ThreadWrapper(void* threadData)
00098 {
00099 ThreadWrapperData* threadWrapperData =
00100 (ThreadWrapperData*) threadData;
00101
00102 void* (*realThread)(void*) = threadWrapperData->realThread;
00103 void* realData = threadWrapperData->realData;
00104 delete threadWrapperData;
00105
00106 return (DWORD) realThread(realData);
00107 }
00108
00109
00110
00111 INTERNAL_QUAL int rtos_task_create_main(RTOS_TASK* main_task)
00112 {
00113 const char* name = "main";
00114 main_task->wait_policy = ORO_WAIT_ABS;
00115 main_task->name = strcpy( (char*)malloc( (strlen(name) + 1) * sizeof(char)), name);
00116 main_task->threadId = GetCurrentThreadId();
00117 main_task->handle = 0;
00118
00119
00120
00121
00122
00123
00124
00125 return 0;
00126 }
00127
00128 INTERNAL_QUAL int rtos_task_delete_main(RTOS_TASK* main_task)
00129 {
00130
00131
00132 free(main_task->name);
00133 return 0;
00134 }
00135
00136
00137 INTERNAL_QUAL int rtos_task_create(RTOS_TASK* task,
00138 int priority,
00139 unsigned cpu_affinity,
00140 const char * name,
00141 int sched_type,
00142 size_t stack_size,
00143 void * (*start_routine)(void *),
00144 ThreadInterface* obj)
00145 {
00146
00147
00148
00149 task->wait_policy = ORO_WAIT_ABS;
00150 if (name == 0 || strlen(name) == 0)
00151 name = "Thread";
00152 task->name = strncpy((char*) malloc((strlen(name) + 1)
00153 * sizeof(char)), name, strlen(name) + 1);
00154
00155 ThreadWrapperData* data = new ThreadWrapperData;
00156 data->realThread = start_routine;
00157 data->realData = obj;
00158
00159 task->handle = CreateThread(NULL, 2*1000*1000, ThreadWrapper, data, 0,
00160 &task->threadId);
00161
00162 if (task->handle == NULL)
00163 {
00164 ErrorHandler(TEXT("CreateThread"));
00165 ExitProcess(3);
00166 }
00167
00168 SetThreadPriority(task->handle, priority);
00169
00170 return 0;
00171 }
00172
00173 INTERNAL_QUAL void rtos_task_yield(RTOS_TASK* mytask) {
00174
00175
00176 Sleep(0);
00177 }
00178
00179 INTERNAL_QUAL int rtos_task_is_self(const RTOS_TASK* task) {
00180 DWORD self = GetCurrentThreadId();
00181 if ( self == task->threadId )
00182 return 1;
00183 return 0;
00184 }
00185
00186 INTERNAL_QUAL int rtos_task_set_scheduler(RTOS_TASK* task, int sched_type) {
00187
00188
00189
00190
00191 if ( task && task->handle != NULL && rtos_task_check_scheduler( &sched_type) == -1 )
00192 return -1;
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202 task->sched_type = sched_type;
00203 return 0;
00204 }
00205
00206 INTERNAL_QUAL int rtos_task_get_scheduler(const RTOS_TASK* task) {
00207 return task->sched_type;
00208 }
00209
00210 INTERNAL_QUAL unsigned int rtos_task_get_pid(const RTOS_TASK* task)
00211 {
00212 return 0;
00213 }
00214
00215 INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK* mytask, NANO_TIME nanosecs )
00216 {
00217
00218 mytask->period = nanosecs;
00219
00220 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00221 }
00222
00223 INTERNAL_QUAL void rtos_task_set_period( RTOS_TASK* mytask, NANO_TIME nanosecs )
00224 {
00225 mytask->period = nanosecs;
00226 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00227 }
00228
00229 INTERNAL_QUAL NANO_TIME rtos_task_get_period(const RTOS_TASK* t) {
00230 return t->period;
00231 }
00232
00233 INTERNAL_QUAL void rtos_task_set_wait_period_policy( RTOS_TASK* task, int policy )
00234 {
00235 task->wait_policy = policy;
00236 }
00237
00238 INTERNAL_QUAL int rtos_task_wait_period( RTOS_TASK* task )
00239 {
00240 if ( task->period == 0 )
00241 return 0;
00242
00243
00244
00245 NANO_TIME timeRemaining = task->periodMark - rtos_get_time_ns();
00246
00247 if ( timeRemaining > 0 ) {
00248 TIME_SPEC ts( ticks2timespec( timeRemaining ) );
00249 rtos_nanosleep( &ts , NULL );
00250 }
00251
00252
00253
00254
00255 if (task->wait_policy == ORO_WAIT_ABS)
00256 task->periodMark += task->period;
00257 else
00258 task->periodMark = rtos_get_time_ns() + task->period;
00259
00260 return 0;
00261 }
00262
00263 INTERNAL_QUAL void rtos_task_delete(RTOS_TASK* mytask) {
00264
00265
00266
00267
00268 WaitForSingleObject( mytask->handle, INFINITE );
00269
00270 CloseHandle(mytask->handle);
00271 free(mytask->name);
00272 mytask->name = NULL;
00273 mytask->handle = NULL;
00274
00275
00276 };
00277
00278 INTERNAL_QUAL int rtos_task_check_scheduler(int* scheduler)
00279 {
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298 return 0;
00299 }
00300
00301 INTERNAL_QUAL int rtos_task_check_priority(int* scheduler, int* priority)
00302 {
00303 int ret = 0;
00304
00305
00306
00307 if (*priority <= -15){
00308 log(Warning) << "Forcing priority ("<<*priority<<") of thread with !SCHED_OTHER policy to -15." <<endlog();
00309 *priority = -15;
00310 ret = -1;
00311 }
00312 if (*priority > 15){
00313 log(Warning) << "Forcing priority ("<<*priority<<") of thread with !SCHED_OTHER policy to 15." <<endlog();
00314 *priority = 15;
00315 ret = -1;
00316 }
00317 return ret;
00318 }
00319
00320 INTERNAL_QUAL int rtos_task_set_priority(RTOS_TASK * task, int priority)
00321 {
00322
00323
00324 SetThreadPriority(task->handle, priority);
00325 return 0;
00326 }
00327
00328 INTERNAL_QUAL int rtos_task_get_priority(const RTOS_TASK *t)
00329 {
00330 return GetThreadPriority(t->handle);
00331 }
00332
00333 INTERNAL_QUAL int rtos_task_set_cpu_affinity(RTOS_TASK * task, unsigned cpu_affinity)
00334 {
00335 return -1;
00336 }
00337
00338 INTERNAL_QUAL unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
00339 {
00340 return ~0;
00341 }
00342
00343 INTERNAL_QUAL const char * rtos_task_get_name(const RTOS_TASK* t)
00344 {
00345
00346
00347
00348
00349
00350
00351
00352
00353 return t->name;
00354 }
00355
00356 }
00357 }
00358 #undef INTERNAL_QUAL