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
00211 INTERNAL_QUAL void rtos_task_make_periodic(RTOS_TASK* mytask, NANO_TIME nanosecs )
00212 {
00213
00214 mytask->period = nanosecs;
00215
00216 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00217 }
00218
00219 INTERNAL_QUAL void rtos_task_set_period( RTOS_TASK* mytask, NANO_TIME nanosecs )
00220 {
00221 mytask->period = nanosecs;
00222 mytask->periodMark = rtos_get_time_ns() + nanosecs;
00223 }
00224
00225 INTERNAL_QUAL NANO_TIME rtos_task_get_period(const RTOS_TASK* t) {
00226 return t->period;
00227 }
00228
00229 INTERNAL_QUAL void rtos_task_set_wait_period_policy( RTOS_TASK* task, int policy )
00230 {
00231 task->wait_policy = policy;
00232 }
00233
00234 INTERNAL_QUAL int rtos_task_wait_period( RTOS_TASK* task )
00235 {
00236 if ( task->period == 0 )
00237 return 0;
00238
00239
00240
00241 NANO_TIME timeRemaining = task->periodMark - rtos_get_time_ns();
00242
00243 if ( timeRemaining > 0 ) {
00244 TIME_SPEC ts( ticks2timespec( timeRemaining ) );
00245 rtos_nanosleep( &ts , NULL );
00246 }
00247
00248
00249
00250
00251 if (task->wait_policy == ORO_WAIT_ABS)
00252 task->periodMark += task->period;
00253 else
00254 task->periodMark = rtos_get_time_ns() + task->period;
00255
00256 return 0;
00257 }
00258
00259 INTERNAL_QUAL void rtos_task_delete(RTOS_TASK* mytask) {
00260
00261
00262
00263
00264 WaitForSingleObject( mytask->handle, INFINITE );
00265
00266 CloseHandle(mytask->handle);
00267 free(mytask->name);
00268 mytask->name = NULL;
00269 mytask->handle = NULL;
00270
00271
00272 };
00273
00274 INTERNAL_QUAL int rtos_task_check_scheduler(int* scheduler)
00275 {
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294 return 0;
00295 }
00296
00297 INTERNAL_QUAL int rtos_task_check_priority(int* scheduler, int* priority)
00298 {
00299 int ret = 0;
00300
00301
00302
00303 if (*priority <= -15){
00304 log(Warning) << "Forcing priority ("<<*priority<<") of thread with !SCHED_OTHER policy to -15." <<endlog();
00305 *priority = -15;
00306 ret = -1;
00307 }
00308 if (*priority > 15){
00309 log(Warning) << "Forcing priority ("<<*priority<<") of thread with !SCHED_OTHER policy to 15." <<endlog();
00310 *priority = 15;
00311 ret = -1;
00312 }
00313 return ret;
00314 }
00315
00316 INTERNAL_QUAL int rtos_task_set_priority(RTOS_TASK * task, int priority)
00317 {
00318
00319
00320 SetThreadPriority(task->handle, priority);
00321 return 0;
00322 }
00323
00324 INTERNAL_QUAL int rtos_task_get_priority(const RTOS_TASK *t)
00325 {
00326 return GetThreadPriority(t->handle);
00327 }
00328
00329 INTERNAL_QUAL int rtos_task_set_cpu_affinity(RTOS_TASK * task, unsigned cpu_affinity)
00330 {
00331 return -1;
00332 }
00333
00334 INTERNAL_QUAL unsigned rtos_task_get_cpu_affinity(const RTOS_TASK *task)
00335 {
00336 return ~0;
00337 }
00338
00339 INTERNAL_QUAL const char * rtos_task_get_name(const RTOS_TASK* t)
00340 {
00341
00342
00343
00344
00345
00346
00347
00348
00349 return t->name;
00350 }
00351
00352 }
00353 }
00354 #undef INTERNAL_QUAL