Kernel.cpp

00001 /***************************************************************************
00002  *                                                                         *
00003  *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
00004  *       mailto: <tevs@mpi-sb.mpg.de>                                      *
00005  *                                                                         *
00006  *   This program is free software; you can redistribute it and/or modify  *
00007  *   it under the terms of the GNU General Public License as published by  *
00008  *   the Free Software Foundation; either version 2 of the License, or     *
00009  *   (at your option) any later version.                                   *
00010  *                                                                         *
00011  ***************************************************************************/
00012 
00013 
00014 #include "Kernel.h"
00015 #include "Profiler.h"
00016 #include "events/KernelTaskEvent.h"
00017 #include "EventManager.h"
00018 #include "StdHelpers.h"
00019 #include "Log.h"
00020 
00021 namespace nrEngine {
00022 
00023         std::list< SharedPtr<ITask> >::iterator Kernel::_loopIterator;
00024 
00025         //-------------------------------------------------------------------------
00026         Kernel::Kernel(){
00027                 taskList.clear();
00028                 pausedTaskList.clear();
00029                 lastTaskID = 0;
00030                 bTaskStarted = false;
00031                 bInitializedRoot = false;
00032                 _bSystemTasksAccessable = false;
00033                 sendEvents(true);
00034         }
00035 
00036         //-------------------------------------------------------------------------
00037         Kernel::~Kernel(){
00038                 StopExecution();
00039 
00040                 taskList.clear();
00041                 pausedTaskList.clear();
00042 
00043                 // Log that kernel is down
00044                 NR_Log(Log::LOG_KERNEL, "Kernel subsystem is down");
00045         }
00046 
00047         //-------------------------------------------------------------------------
00048         void Kernel::lockSystemTasks()
00049         {
00050                 _bSystemTasksAccessable = true;
00051         }
00052 
00053         //-------------------------------------------------------------------------
00054         void Kernel::unlockSystemTasks()
00055         {
00056                 _bSystemTasksAccessable = false;
00057         }
00058 
00059         //-------------------------------------------------------------------------
00060         Result Kernel::OneTick()
00061         {
00062 
00063                 // Profiling of the engine
00064                 _nrEngineProfile("Kernel::OneTick");
00065 
00066                 // start tasks if their are not started before
00067                 prepareRootTask();
00068 
00069                 // get iterator through our std::list
00070                 PipelineIterator it;
00071 
00072                 // iterate through all tasks and start them
00073                 for (it = taskList.begin(); it != taskList.end(); it++){
00074                         if ((*it)->getTaskState() == TASK_STOPPED)
00075                                 _taskStart(*it);
00076                 }
00077 
00078                 // resetup to the beginning
00079                 it = taskList.begin();
00080 
00081                 // we go always from teh first element in the list, because it is
00082                 // the system root task
00083                 _loopStartCycle();
00084                 while (_loopGetNextTask(taskList.begin(), it, 0) == OK){
00085                         SharedPtr<ITask>& t=(*it);
00086 
00087                         if (t && !t->_taskCanKill){
00088 
00089                                 // if the task is running
00090                                 if (t->getTaskState() == TASK_RUNNING){
00091 
00092                                         // do some profiling
00093                                         char name[256];
00094                                         sprintf(name, "%s::update", t->getTaskName());
00095                                         _nrEngineProfile(name);
00096 
00097                                         t->updateTask();
00098 
00099                                         // check if the task should run only once
00100                                         if (t->getTaskProperty() & TASK_RUN_ONCE)
00101                                                 RemoveTask(t->getTaskID());
00102 
00103                                 }
00104                         }
00105                 }
00106                 _loopEndCycle();
00107 
00108                 PipelineIterator thisIt;
00109                 TaskId tempID;
00110 
00111                 //loop again to remove dead tasks
00112                 for( it = taskList.begin(); it != taskList.end();){
00113 
00114                         SharedPtr<ITask> &t=(*it);
00115                         bool killed = false;
00116 
00117                         // kill task if we need this
00118                         if(t && t->_taskCanKill){
00119 
00120                                 _taskStop(t);
00121 
00122                                 // remove the task
00123                                 tempID = t->getTaskID();
00124                                 NR_Log(Log::LOG_KERNEL, "Task (id=%d) removed", tempID);
00125                                 it = taskList.erase(it);
00126                                 killed = true;
00127 
00128                         // check whenver order of the task was changed by outside
00129                         }else if (t->_orderChanged){
00130                                 ChangeTaskOrder(t->getTaskID(), t->getTaskOrder());
00131                         }
00132 
00133                         if (!killed) it++;
00134                 }
00135 
00136                 // Now we yield the running thread, so that our system could still 
00137                 // response
00138                 IThread::yield();
00139 
00140                 // return good result
00141                 return OK;
00142         }
00143 
00144 
00145         //-------------------------------------------------------------------------
00146         void Kernel::prepareRootTask()
00147         {
00148                 if (bInitializedRoot) return;
00149                 bInitializedRoot = true;
00150 
00151                 // get iterator through our std::list
00152                 PipelineIterator it;
00153 
00154                 NR_Log(Log::LOG_KERNEL, "Create a system root task in the kernel");
00155 
00156                 // firstly we add a dummy system task, which depends on all others.
00157                 // This task do nothing, but depends on the rest.
00158                 // This is needed to get all thing worked
00159                 mRootTask.reset(new EmptyTask());
00160                 mRootTask->setTaskName("KernelRoot");
00161                 mRootTask->setTaskType(TASK_SYSTEM);
00162 
00163                 // Add the task as system task to the kernel
00164                 lockSystemTasks();
00165                         AddTask(mRootTask, ORDER_SYS_ROOT);
00166                 unlockSystemTasks();
00167 
00168         }
00169 
00170         //-------------------------------------------------------------------------
00171         /*void Kernel::startTasks(){
00172 
00173                 NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Start all kernel tasks");
00174 
00175                 // start all tasks, which are not running at now
00176                 for(it = taskList.begin(); it != taskList.end(); it++){
00177                         _taskStart(*it);
00178                 }
00179 
00180                 bTaskStarted = true;
00181         }
00182         */
00183 
00184         //-------------------------------------------------------------------------
00185         Result Kernel::_taskStart(SharedPtr<ITask>& task)
00186         {
00187 
00188                 // no task given, so return error
00189                 if (!task)
00190                         return KERNEL_NO_TASK_FOUND;
00191 
00192                 // check if the task is not a thread
00193                 if (task->getTaskProperty() & TASK_IS_THREAD){
00194 
00195                         SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
00196                         thread->threadStart();
00197                         task->setTaskState(TASK_RUNNING);
00198                         task->onStartTask();
00199 
00200                 }else{
00201 
00202                         // check for the task states
00203                         if (task->getTaskState() == TASK_STOPPED)
00204                         {
00205                                 task->setTaskState(TASK_RUNNING);
00206                                 task->onStartTask();
00207                         }else if (task->getTaskState() == TASK_PAUSED){
00208                                 return ResumeTask(task->getTaskID());
00209                         }
00210 
00211                 }
00212 
00213                 // send a message about current task state
00214                 if (bSendEvents){
00215                         SharedPtr<Event> msg(new KernelStartTaskEvent(task->getTaskName(), task->getTaskID()));
00216                         Engine::sEventManager()->emitSystem(msg);
00217                 }
00218 
00219                 // OK
00220                 return OK;
00221         }
00222 
00223         //-------------------------------------------------------------------------
00224         Result Kernel::_taskStop(SharedPtr<ITask>& task)
00225         {
00226                 try{
00227                         // no task given, so return error
00228                         if (!task)
00229                                 return KERNEL_NO_TASK_FOUND;
00230 
00231                         // check if the task is not a thread
00232                         if (task->getTaskProperty() & TASK_IS_THREAD){
00233 
00234                                 SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
00235                                 NR_Log(Log::LOG_KERNEL, "Stop thread/task \"%s\" (id=%d)", task->getTaskName(), task->getTaskID());
00236                                 thread->threadStop();
00237 
00238                         }else{
00239                                 // stop the task
00240                                 NR_Log(Log::LOG_KERNEL, "Stop task \"%s\" (id=%d)",task->getTaskName(), task->getTaskID());
00241                                 task->stopTask();
00242                         }
00243 
00244                 } catch (...){
00245                         return UNKNOWN_ERROR;
00246                 }
00247 
00248                 // send a message about current task state
00249                 if (bSendEvents){
00250                         SharedPtr<Event> msg(new KernelStopTaskEvent(task->getTaskName(), task->getTaskID()));
00251                         Engine::sEventManager()->emitSystem(msg);
00252                 }
00253 
00254 
00255                 // OK
00256                 return OK;
00257 
00258         }
00259 
00260         //-------------------------------------------------------------------------
00261         /*Result Kernel::StartTask(taskID id){
00262 
00263                 SharedPtr<ITask> task = getTaskByID(id);
00264 
00265                 if (!task) {
00266                         NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Can not start task with id=%d, because such task does not exists", id);
00267                         return KERNEL_NO_TASK_FOUND;
00268                 }
00269 
00270                 // check if the task is not a thread
00271                 return _taskStart(task);
00272         }*/
00273 
00274 
00275         //-------------------------------------------------------------------------
00276         Result Kernel::Execute(){
00277                 try{
00278 
00279                         // Log that kernel is initialized
00280                         NR_Log(Log::LOG_KERNEL, "Kernel subsystem is active, start main loop");
00281 
00282                         // loop while we have tasks in our pipeline
00283                         while (taskList.size()){
00284                                 OneTick();
00285                         }
00286 
00287                         NR_Log(Log::LOG_KERNEL, "Stop kernel main loop");
00288 
00289                 } catch(...){
00290                         return UNKNOWN_ERROR;
00291                 }
00292 
00293                 // ok
00294                 return OK;
00295 
00296         }
00297 
00298 
00299         //-------------------------------------------------------------------------
00300         TaskId Kernel::AddTask (SharedPtr<ITask> t, TaskOrder order, TaskProperty proper){
00301 
00302                 prepareRootTask();
00303 
00304                 _nrEngineProfile("Kernel::AddTask");
00305 
00306                 try {
00307 
00308                         t->_taskOrder = order;
00309 
00310                         // check whenever such task already exists
00311                         std::list< SharedPtr<ITask> >::iterator it;
00312                         for (it = taskList.begin(); it != taskList.end(); it++){
00313                                 if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
00314                                         NR_Log(Log::LOG_KERNEL, "Cannot add task \"%s\" because same task was already added!", t->getTaskName());
00315                                         return 0;
00316                                 }
00317                         }
00318 
00319                         for (it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
00320                                 if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
00321                                         NR_Log(Log::LOG_KERNEL, "Found same task in paused task std::list !");
00322                                         return 0;
00323                                 }
00324                         }
00325 
00326                         // check if the given order number is valid
00327                         if (t->getTaskOrder() <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
00328                         {
00329                                 NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers");
00330                                 return 0;
00331                         }
00332 
00333                         // setup some data
00334                         t->setTaskProperty(proper);
00335                         t->setTaskState(TASK_STOPPED);
00336                         t->setTaskID(++lastTaskID);
00337 
00338                         // some debug info
00339                         if (proper & TASK_IS_THREAD)
00340                                 NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" as thread (id = %d)", t->getTaskName(), t->getTaskID());
00341                         else
00342                                 NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" at order = %s (id = %d)", t->getTaskName(), orderToString(int32(t->getTaskOrder())).c_str(), t->getTaskID());
00343 
00344                         // init task and check its return code
00345                         if (t->onAddTask() != OK){
00346                                 NR_Log(Log::LOG_KERNEL, "Cannot initalize Task because of Task internal error");
00347                                 return 0;
00348                         }
00349 
00350                         // find the place for our task according to its order
00351                         for( it=taskList.begin(); it != taskList.end(); it++){
00352                                 SharedPtr<ITask> &comp = (*it);
00353                                 if (comp->getTaskOrder() >= t->getTaskOrder()) break;
00354                         }
00355 
00356                         // add into the list
00357                         taskList.insert (it,t);
00358 
00359                 } catch(...){
00360                         return UNKNOWN_ERROR;
00361                 }
00362 
00363                 // if this is not a root task, then add dependency
00364                 // also there is no dependency if this is a thread
00365                 if (t->_taskOrder != ORDER_SYS_ROOT && !(t->getTaskProperty() & TASK_IS_THREAD))
00366                         mRootTask->addTaskDependency(t);
00367 
00368                 // return the id
00369                 return t->getTaskID();
00370         }
00371 
00372 
00373         //-------------------------------------------------------------------------
00374         Result Kernel::RemoveTask  (TaskId id){
00375 
00376                 if (id == 0) return OK;
00377 
00378                 try{
00379 
00380                         NR_Log(Log::LOG_KERNEL, "Remove task with id=%d", id);
00381 
00382                         // find the task
00383                         PipelineIterator it;
00384 
00385                         // check whenever iterator is valid
00386                         if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
00387                                 NR_Log(Log::LOG_KERNEL, "No such Task (id=%d) found !!!", id);
00388                                 return KERNEL_NO_TASK_FOUND;
00389                         }
00390 
00391                         // check whenever we are allowed to remove the task
00392                         if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM)
00393                         {
00394                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to remove this task!");
00395                                 return KERNEL_NO_RIGHTS;
00396 
00397                         }else{
00398                                 // say task want to remove his self
00399                                 NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
00400                                 (*it)->_taskCanKill = true;
00401                         }
00402 
00403                 } catch(...){
00404                         return UNKNOWN_ERROR;
00405                 }
00406 
00407                 // OK
00408                 return OK;
00409         }
00410 
00411 
00412         //-------------------------------------------------------------------------
00413         Result Kernel::SuspendTask  (TaskId id){
00414 
00415                 try{
00416 
00417                         NR_Log(Log::LOG_KERNEL, "Suspend task (id=%d)", id);
00418 
00419                         // find the task
00420                         PipelineIterator it;
00421 
00422                         // check whenever iterator is valid
00423                         if (!_getTaskByID(id, it)){
00424                                 NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
00425                                 return KERNEL_NO_TASK_FOUND;
00426                         }else{
00427                                 SharedPtr<ITask> &t = (*it);
00428 
00429                                 if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
00430                                         NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to suspend this task!");
00431                                         return KERNEL_NO_RIGHTS;
00432                                 }else{
00433 
00434                                         // suspend task
00435                                         Result res = t->onSuspendTask();
00436                                         if (res == OK){
00437                                                 t->setTaskState(TASK_PAUSED);
00438 
00439                                                 // before removing the task from task std::list move it to paused std::list
00440                                                 // so we can guarantee that task object will be held in memory
00441                                                 pausedTaskList.push_back(t);
00442                                                 taskList.erase(it);
00443                                                 NR_Log(Log::LOG_KERNEL, "Task id=%d is sleeping now", id);
00444 
00445                                                 // send a message about current task state
00446                                                 if (bSendEvents){
00447                                                         SharedPtr<Event> msg(new KernelSuspendTaskEvent(t->getTaskName(), t->getTaskID()));
00448                                                         Engine::sEventManager()->emitSystem(msg);
00449                                                 }
00450 
00451                                         }else{
00452                                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not suspend! Check this!", id);
00453                                                 return res;
00454                                         }
00455                                 }
00456                         }
00457 
00458                 } catch(...){
00459                         return UNKNOWN_ERROR;
00460                 }
00461 
00462                 // OK
00463                 return OK;
00464         }
00465 
00466         //-------------------------------------------------------------------------
00467         Result Kernel::ResumeTask  (TaskId id){
00468 
00469                 try{
00470 
00471                         NR_Log(Log::LOG_KERNEL, "Resume task (id=%d)", id);
00472 
00473                         // find the task
00474                         PipelineIterator it;
00475 
00476                         // check whenever iterator is valid
00477                         if (!_getTaskByID(id, it, TL_SLEEPING)){
00478                                 NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
00479                                 return KERNEL_NO_TASK_FOUND;
00480                         }
00481 
00482                         SharedPtr<ITask> &t = (*it);
00483                         if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
00484                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to resume this task!");
00485                                 return KERNEL_NO_RIGHTS;
00486                         }else{
00487 
00488                                 // resume the task
00489                                 Result res = t->onResumeTask();
00490                                 if (res == OK){
00491                                         t->setTaskState(TASK_RUNNING);
00492 
00493                                         //keep the order of priorities straight
00494                                         for( it = taskList.begin(); it != taskList.end(); it++){
00495                                                 SharedPtr<ITask> &comp=(*it);
00496                                                 if(comp->getTaskOrder() >= t->getTaskOrder()) break;
00497                                         }
00498                                         taskList.insert(it,t);
00499 
00500                                         // erase task from paused std::list. Therefor we have to find it in the std::list
00501                                         if (_getTaskByID(id, it, TL_SLEEPING)){
00502                                                 pausedTaskList.erase(it);
00503                                         }
00504 
00505                                         // send a message about current task state
00506                                         if (bSendEvents){
00507                                                 SharedPtr<Event> msg(new KernelResumeTaskEvent(t->getTaskName(), t->getTaskID()));
00508                                                 Engine::sEventManager()->emitSystem(msg);
00509                                         }
00510 
00511                                 }else{
00512                                         NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not resume, so it stay in sleep mode", id);
00513                                         return res;
00514                                 }
00515                         }
00516 
00517                 } catch(...){
00518                         return UNKNOWN_ERROR;
00519                 }
00520 
00521                 // OK
00522                 return OK;
00523         }
00524 
00525         //-------------------------------------------------------------------------
00526         Result Kernel::StopExecution(){
00527 
00528                 try{
00529 
00530                         NR_Log(Log::LOG_KERNEL, "Stop the kernel subsystem");
00531 
00532                         // iterate through all tasks and kill them
00533                         for(PipelineIterator it = taskList.begin(); it != taskList.end(); it++){
00534                                 NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
00535                                 (*it)->_taskCanKill=true;
00536                         }
00537 
00538                         // iterate also through all paused tasks and kill them also
00539                         for(PipelineIterator it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
00540                                 NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
00541                                 (*it)->_taskCanKill=true;
00542                         }
00543 
00544                         // Info if we do not have any tasks to kill
00545                         if (!taskList.size() && !pausedTaskList.size())
00546                                 NR_Log(Log::LOG_KERNEL, "There is no more tasks to be killed !");
00547 
00548                 } catch(...){
00549                         return UNKNOWN_ERROR;
00550                 }
00551 
00552                 // OK
00553                 return OK;
00554 
00555         }
00556 
00557 
00558         //-------------------------------------------------------------------------
00559         Result Kernel::ChangeTaskOrder(TaskId id, TaskOrder order){
00560 
00561                 try{
00562 
00563                         NR_Log(Log::LOG_KERNEL, "Change order of task (id=%d) to %d", id, int32(order));
00564 
00565                         // find the task
00566                         PipelineIterator it;
00567 
00568                         // check whenever iterator is valid
00569                         if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
00570                                 NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
00571                                 return KERNEL_NO_TASK_FOUND;
00572                         }
00573 
00574                         SharedPtr<ITask> &t = (*it);
00575 
00576                         // check if the given order number is valid
00577                         if (order <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
00578                         {
00579                                 NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers!");
00580                                 return KERNEL_NO_RIGHTS;
00581                         }
00582 
00583                         // check for task access rights
00584                         if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
00585                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to change the order of system task!");
00586                                 return KERNEL_NO_RIGHTS;
00587                         }else{
00588 
00589                                 // change order of the task
00590                                 t->setTaskOrder(order);
00591                                 t->_orderChanged = false;
00592 
00593                                 // sort lists
00594                                 pausedTaskList.sort();
00595                                 taskList.sort();
00596                         }
00597 
00598                 } catch(...){
00599                         return UNKNOWN_ERROR;
00600                 }
00601 
00602                 // OK
00603                 return OK;
00604         }
00605 
00606         //-------------------------------------------------------------------------
00607         bool Kernel::_getTaskByID(TaskId id, PipelineIterator& jt, int32 useList){
00608 
00609                 // get std::list we want to search in
00610                 std::list< SharedPtr<ITask> > *li = NULL;
00611 
00612                 // search in normal list
00613                 if ((useList & TL_RUNNING) == TL_RUNNING){
00614                         li = &taskList;
00615 
00616                         // iterate through elements and search for task with same id
00617                         PipelineIterator it;
00618                         for ( it = li->begin(); it != li->end(); it++){
00619                                 if ((*it)->getTaskID() == id){
00620                                         jt = it;
00621                                         return true;
00622                                 }
00623                         }
00624                 }
00625 
00626                 // search in paused list
00627                 if ((useList & TL_SLEEPING) == TL_SLEEPING){
00628                         li = &pausedTaskList;
00629 
00630                         // iterate through elements and search for task with same id
00631                         PipelineIterator it;
00632                         for ( it = li->begin(); it != li->end(); it++){
00633                                 if ((*it)->getTaskID() == id){
00634                                         jt = it;
00635                                         return true;
00636                                 }
00637                         }
00638 
00639                 }
00640 
00641                 // not found so return an end iterator
00642                 return false;
00643         }
00644 
00645         //-------------------------------------------------------------------------
00646         bool Kernel::_getTaskByName(const std::string& name, PipelineIterator& it, int32 useList)
00647         {
00648 
00649                 // get std::list we want to search in
00650                 std::list< SharedPtr<ITask> > *li = NULL;
00651 
00652                 // search in normal list
00653                 if ((useList & TL_RUNNING) == TL_RUNNING){
00654                         li = &taskList;
00655 
00656                         // iterate through elements and search for task with same id
00657                         PipelineIterator jt;
00658                         for ( jt = li->begin(); jt != li->end(); jt++){
00659                                 if ((*jt)->getTaskName() == name){
00660                                         it = jt;
00661                                         return true;
00662                                 }
00663                         }
00664                 }
00665 
00666                 // search in paused list
00667                 if ((useList & TL_SLEEPING) == TL_SLEEPING){
00668                         li = &pausedTaskList;
00669 
00670                         // iterate through elements and search for task with same id
00671                         PipelineIterator jt;
00672                         for ( jt = li->begin(); jt != li->end(); jt++){
00673                                 if ((*jt)->getTaskName() == name){
00674                                         it = jt;
00675                                         return true;
00676                                 }
00677                         }
00678                 }
00679 
00680                 // not found so return end iterator
00681                 return false;
00682         }
00683 
00684         //-------------------------------------------------------------------------
00685         SharedPtr<ITask> Kernel::getTaskByID(TaskId id){
00686                 try{
00687 
00688                         // find the task
00689                         PipelineIterator it;
00690 
00691                         // check whenever iterator is valid
00692                         if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
00693                                 NR_Log(Log::LOG_KERNEL, "getTaskByID: No task with id=%d found", id);
00694                                 return SharedPtr<ITask>();
00695                         }
00696 
00697                         // check the rights
00698                         if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
00699                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
00700                                 return SharedPtr<ITask>();
00701                         }
00702 
00703                         return *it;
00704 
00705                 } catch(...){
00706                         return SharedPtr<ITask>();
00707                 }
00708 
00709         }
00710 
00711 
00712         //-------------------------------------------------------------------------
00713         SharedPtr<ITask> Kernel::getTaskByName(const std::string& name){
00714                 try{
00715 
00716                         // find the task
00717                         PipelineIterator it;
00718 
00719                         // check whenever iterator is valid
00720                         if (!_getTaskByName(name, it, TL_RUNNING | TL_SLEEPING)){
00721                                 NR_Log(Log::LOG_KERNEL, "getTaskByName: No task with name=%s found", name.c_str());
00722                                 return SharedPtr<ITask>();
00723                         }
00724 
00725                         // check the rights
00726                         if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
00727                                 NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
00728                                 return SharedPtr<ITask>();
00729                         }
00730 
00731                         return *it;
00732 
00733                 } catch(...){
00734                         return SharedPtr<ITask>();
00735                 }
00736         }
00737 
00738         //-------------------------------------------------------------------------
00739         Result Kernel::_loopStartCycle()
00740         {
00741 
00742                 // Profiling of the engine
00743                 _nrEngineProfile("Kernel::_loopStartCycle");
00744 
00745                 // iterate through the tasks and mark them as non visited
00746                 _loopIterator = taskList.begin();
00747                 while (_loopIterator != taskList.end())
00748                 {
00749                         (*_loopIterator)->_taskGraphColor = 0;
00750                         _loopIterator ++;
00751                 }
00752 
00753                 _loopIterator = pausedTaskList.begin();
00754                 while (_loopIterator != pausedTaskList.end())
00755                 {
00756                         (*_loopIterator)->_taskGraphColor = 0;
00757                         _loopIterator ++;
00758                 }
00759 
00760 
00761                 _loopIterator = taskList.begin();
00762 
00763                 return OK;
00764         }
00765 
00766         //-------------------------------------------------------------------------
00767         Result Kernel::_loopGetNextTask(PipelineIterator it, PipelineIterator& result, int depth)
00768         {
00769                 // Profiling of the engine
00770                 _nrEngineProfile("Kernel::_loopGetNextTask");
00771 
00772                 // check whenever this is the end
00773                 if (it == taskList.end()) return KERNEL_END_REACHED;
00774 
00775                 // get the task in this iterator
00776                 const SharedPtr<ITask>& t = *it;
00777 
00778                 if (t->_taskGraphColor == 1) return KERNEL_CIRCULAR_DEPENDENCY;
00779                 if (t->_taskGraphColor == 2) return KERNEL_END_REACHED;
00780 
00781                 t->_taskGraphColor = 1;
00782 
00783                 // now check if the task has got childrens
00784                 if (t->_taskDependencies.size() > 0)
00785                 {
00786 
00787                         // do for each child call this function recursively
00788                         /*for (uint32 i = 0; i < t->_taskDependencies.size(); i++)
00789                         {
00790                                 PipelineIterator jt;
00791                                 if (!_getTaskByID(t->_taskDependencies[i], jt, TL_RUNNING | TL_SLEEPING)) return KERNEL_TASK_MISSING;
00792 
00793                                 // check whenever the child was already visited
00794                                 if ((*jt)->_taskGraphColor != 2){
00795                                         Result ret = _loopGetNextTask(jt, result, depth+1);
00796 
00797                                         // we return OK only if we have not found any circularity
00798                                         // and we are on the top (root-node)
00799                                         if (ret != OK){
00800                                                 t->_taskGraphColor = 0;
00801                                                 if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
00802                                                 return ret;
00803                                         }
00804                                 }
00805                         }*/
00806 
00807                         // iterate through all dependencies and check them
00808                         std::list<SharedPtr<ITask> >::iterator jt = t->_taskDependencies.begin();
00809                         for (; jt != t->_taskDependencies.end(); jt ++)
00810                         {
00811                                 // check whenever the child was already visited
00812                                 if ((*jt)->_taskGraphColor != 2){
00813                                         Result ret = _loopGetNextTask(jt, result, depth+1);
00814 
00815                                         // we return OK only if we have not found any circularity
00816                                         // and we are on the top (root-node)
00817                                         if (ret != OK){
00818                                                 t->_taskGraphColor = 0;
00819                                                 if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
00820                                                 return ret;
00821                                         }
00822                                 }
00823 
00824                         }
00825 
00826                 // we do not have childs, so this is a leaf node
00827                 }
00828 
00829                 // all our chlds are visited, so return the node itself
00830                 t->_taskGraphColor = 2;
00831                 result = it;
00832                 return KERNEL_LEAF_TASK;
00833 
00834         }
00835 
00836         //-------------------------------------------------------------------------
00837         Result Kernel::_loopEndCycle()
00838         {
00839                 return OK;
00840         }
00841 
00842 }; //namespace nrEngine
00843 

Generated on Wed Sep 12 23:19:42 2007 for nrEngine by  doxygen 1.5.1