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