source: nrEngine/src/Kernel.cpp @ 12

Revision 12, 21.3 KB checked in by art, 13 years ago (diff)
  • Friendly thread execution added (yielding of threads and main thread)
  • Test directory added, where simple test programms will be build
  • Each Makefile now contains the TOPDIR variable
Line 
1/***************************************************************************
2 *                                                                         *
3 *   (c) Art Tevs, MPI Informatik Saarbruecken                             *
4 *       mailto: <tevs@mpi-sb.mpg.de>                                      *
5 *                                                                         *
6 *   This program is free software; you can redistribute it and/or modify  *
7 *   it under the terms of the GNU General Public License as published by  *
8 *   the Free Software Foundation; either version 2 of the License, or     *
9 *   (at your option) any later version.                                   *
10 *                                                                         *
11 ***************************************************************************/
12
13
14#include "Kernel.h"
15#include "Profiler.h"
16#include "events/KernelTaskEvent.h"
17#include "EventManager.h"
18#include "StdHelpers.h"
19#include "Log.h"
20
21namespace nrEngine {
22
23        std::list< SharedPtr<ITask> >::iterator Kernel::_loopIterator;
24
25        //-------------------------------------------------------------------------
26        Kernel::Kernel(){
27                taskList.clear();
28                pausedTaskList.clear();
29                lastTaskID = 0;
30                bTaskStarted = false;
31                bInitializedRoot = false;
32                _bSystemTasksAccessable = false;
33                sendEvents(true);
34        }
35
36        //-------------------------------------------------------------------------
37        Kernel::~Kernel(){
38                StopExecution();
39
40                taskList.clear();
41                pausedTaskList.clear();
42
43                // Log that kernel is down
44                NR_Log(Log::LOG_KERNEL, "Kernel subsystem is down");
45        }
46
47        //-------------------------------------------------------------------------
48        void Kernel::lockSystemTasks()
49        {
50                _bSystemTasksAccessable = true;
51        }
52
53        //-------------------------------------------------------------------------
54        void Kernel::unlockSystemTasks()
55        {
56                _bSystemTasksAccessable = false;
57        }
58
59        //-------------------------------------------------------------------------
60        Result Kernel::OneTick()
61        {
62
63                // Profiling of the engine
64                _nrEngineProfile("Kernel::OneTick");
65
66                // start tasks if their are not started before
67                prepareRootTask();
68
69                // get iterator through our std::list
70                PipelineIterator it;
71
72                // iterate through all tasks and start them
73                for (it = taskList.begin(); it != taskList.end(); it++){
74                        if ((*it)->getTaskState() == TASK_STOPPED)
75                                _taskStart(*it);
76                }
77               
78                // we go always from teh first element in the list, because it is
79                // the system root task
80                _loopStartCycle();
81                while (_loopGetNextTask(taskList.begin(), it, 0) == OK){
82                        SharedPtr<ITask>& t=(*it);
83                       
84                        if (t && !t->_taskCanKill){
85                               
86                                // if the task is running
87                                if (t->getTaskState() == TASK_RUNNING){
88
89                                        // do some profiling
90                                        char name[256];
91                                        sprintf(name, "%s::update", t->getTaskName());
92                                        _nrEngineProfile(name);
93                                        t->updateTask();
94
95                                        // check if the task should run only once
96                                        if (t->getTaskProperty() & TASK_RUN_ONCE)
97                                                RemoveTask(t->getTaskID());
98
99                                }
100                        }
101                }
102                _loopEndCycle();
103
104                PipelineIterator thisIt;
105                TaskId tempID;
106
107                //loop again to remove dead tasks
108                for( it = taskList.begin(); it != taskList.end();){
109
110                        SharedPtr<ITask> &t=(*it);
111                        bool killed = false;
112                       
113                        // kill task if we need this
114                        if(t && t->_taskCanKill){
115
116                                _taskStop(t);
117
118                                // remove the task
119                                tempID = t->getTaskID();
120                                NR_Log(Log::LOG_KERNEL, "Task (id=%d) removed", tempID);
121                                it = taskList.erase(it);
122                                killed = true;
123
124                        // check whenver order of the task was changed by outside
125                        }else if (t->_orderChanged){
126                                ChangeTaskOrder(t->getTaskID(), t->getTaskOrder());
127                        }
128
129                        if (!killed) it++;
130                }
131
132                // Now we yield the running thread, so that we get user friendly
133                // thread behaviour.
134                IThread::yield();
135               
136                // return good result
137                return OK;
138        }
139
140
141        //-------------------------------------------------------------------------
142        void Kernel::prepareRootTask()
143        {
144                if (bInitializedRoot) return;
145                bInitializedRoot = true;
146               
147                // get iterator through our std::list
148                PipelineIterator it;
149
150                NR_Log(Log::LOG_KERNEL, "Create a system root task in the kernel");
151
152                // firstly we add a dummy system task, which depends on all others.
153                // This task do nothing, but depends on the rest.
154                // This is needed to get all thing worked
155                mRootTask.reset(new EmptyTask());
156                mRootTask->setTaskName("KernelRoot");
157                mRootTask->setTaskType(TASK_SYSTEM);
158
159                // Add the task as system task to the kernel
160                lockSystemTasks();
161                        AddTask(mRootTask, ORDER_SYS_ROOT);
162                unlockSystemTasks();
163
164        }
165
166        //-------------------------------------------------------------------------
167        /*void Kernel::startTasks(){
168
169                NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Start all kernel tasks");
170
171                // start all tasks, which are not running at now
172                for(it = taskList.begin(); it != taskList.end(); it++){
173                        _taskStart(*it);
174                }
175
176                bTaskStarted = true;
177        }
178        */
179       
180        //-------------------------------------------------------------------------
181        Result Kernel::_taskStart(SharedPtr<ITask>& task)
182        {
183               
184                // no task given, so return error
185                if (!task)
186                        return KERNEL_NO_TASK_FOUND;
187
188                // check if the task is not a thread
189                if (task->getTaskProperty() & TASK_IS_THREAD){
190
191                        SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
192                        thread->threadStart();
193                        task->setTaskState(TASK_RUNNING);
194                        task->onStartTask();
195                       
196                }else{
197
198                        // check for the task states
199                        if (task->getTaskState() == TASK_STOPPED){
200                                task->setTaskState(TASK_RUNNING);
201                                task->onStartTask();
202
203                        }else if (task->getTaskState() == TASK_PAUSED){
204                                return ResumeTask(task->getTaskID());
205                        }
206
207                }
208                               
209                // send a message about current task state
210                if (bSendEvents){
211                        SharedPtr<Event> msg(new KernelStartTaskEvent(task->getTaskName(), task->getTaskID()));
212                        Engine::sEventManager()->emitSystem(msg);
213                }
214               
215                // OK
216                return OK;
217        }
218
219        //-------------------------------------------------------------------------
220        Result Kernel::_taskStop(SharedPtr<ITask>& task)
221        {
222                try{
223                        // no task given, so return error
224                        if (!task)
225                                return KERNEL_NO_TASK_FOUND;
226
227                        // check if the task is not a thread
228                        if (task->getTaskProperty() & TASK_IS_THREAD){
229                               
230                                SharedPtr<IThread> thread = boost::dynamic_pointer_cast<IThread, ITask>(task);
231                                NR_Log(Log::LOG_KERNEL, "Stop thread/task \"%s\" (id=%d)", task->getTaskName(), task->getTaskID());
232                                thread->threadStop();
233
234                        }else{
235                                // stop the task
236                                NR_Log(Log::LOG_KERNEL, "Stop task \"%s\" (id=%d)",task->getTaskName(), task->getTaskID());
237                                task->stopTask();
238                        }
239
240                } catch (...){
241                        return UNKNOWN_ERROR;
242                }
243               
244                // send a message about current task state
245                if (bSendEvents){
246                        SharedPtr<Event> msg(new KernelStopTaskEvent(task->getTaskName(), task->getTaskID()));
247                        Engine::sEventManager()->emitSystem(msg);
248                }
249
250
251                // OK
252                return OK;
253
254        }
255
256        //-------------------------------------------------------------------------
257        /*Result Kernel::StartTask(taskID id){
258
259                SharedPtr<ITask> task = getTaskByID(id);
260
261                if (!task) {
262                        NR_Log(Log::LOG_KERNEL, Log::LL_DEBUG, "Can not start task with id=%d, because such task does not exists", id);
263                        return KERNEL_NO_TASK_FOUND;
264                }
265
266                // check if the task is not a thread
267                return _taskStart(task);
268        }*/
269
270
271        //-------------------------------------------------------------------------
272        Result Kernel::Execute(){
273                try{
274
275                        // Log that kernel is initialized
276                        NR_Log(Log::LOG_KERNEL, "Kernel subsystem is active, start main loop");
277
278                        // loop while we have tasks in our pipeline
279                        while (taskList.size()){
280                                OneTick();
281                        }
282
283                        NR_Log(Log::LOG_KERNEL, "Stop kernel main loop");
284
285                } catch(...){
286                        return UNKNOWN_ERROR;
287                }
288
289                // ok
290                return OK;
291
292        }
293
294
295        //-------------------------------------------------------------------------
296        TaskId Kernel::AddTask (SharedPtr<ITask> t, TaskOrder order, TaskProperty proper){
297
298                prepareRootTask();
299
300                _nrEngineProfile("Kernel::AddTask");
301
302                try {
303
304                        t->_taskOrder = order;
305                       
306                        if (proper & TASK_IS_THREAD)
307                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" as thread", t->getTaskName());
308                        else
309                                NR_Log(Log::LOG_KERNEL, "Add Task \"%s\" at order = %s", t->getTaskName(), orderToString(int32(t->getTaskOrder())).c_str());
310
311                        // check whenever such task already exists
312                        std::list< SharedPtr<ITask> >::iterator it;
313                        for (it = taskList.begin(); it != taskList.end(); it++){
314                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
315                                        NR_Log(Log::LOG_KERNEL, "Found same task in task std::list !");
316                                        return 0;
317                                }
318                        }
319
320                        for (it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
321                                if ((*it) == t || (*it)->getTaskID() == t->getTaskID() || strcmp((*it)->getTaskName(),t->getTaskName())==0){
322                                        NR_Log(Log::LOG_KERNEL, "Found same task in paused task std::list !");
323                                        return 0;
324                                }
325                        }
326
327                        // check if the given order number is valid
328                        if (t->getTaskOrder() <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
329                        {
330                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers");
331                                return 0;
332                        }
333
334                        // setup some data
335                        t->setTaskProperty(proper);
336                        t->setTaskState(TASK_STOPPED);
337                        t->setTaskID(++lastTaskID);
338
339                        // init task and check its return code
340                        if (t->onAddTask() != OK){
341                                NR_Log(Log::LOG_KERNEL, "Cannot initalize Task because of Task internal error");
342                                return 0;
343                        }
344
345                        // find the place for our task according to his order
346                        for( it=taskList.begin(); it != taskList.end(); it++){
347                                SharedPtr<ITask> &comp = (*it);
348                                if (comp->getTaskOrder() >= t->getTaskOrder()) break;
349                        }
350
351                        // add into the list
352                        taskList.insert (it,t);
353
354                } catch(...){
355                        return UNKNOWN_ERROR;
356                }
357
358                // if this is not a root task, then add dependency
359                // also there is no dependency if this is a thread
360                if (t->_taskOrder != ORDER_SYS_ROOT && !(t->getTaskProperty() & TASK_IS_THREAD))
361                        mRootTask->addTaskDependency(t->getTaskID());
362
363                // return the id
364                return t->getTaskID();
365        }
366
367
368        //-------------------------------------------------------------------------
369        Result Kernel::RemoveTask  (TaskId id){
370
371                if (id == 0) return OK;
372               
373                try{ 
374
375                        NR_Log(Log::LOG_KERNEL, "Remove task with id=%d", id);
376
377                        // find the task
378                        PipelineIterator it;
379
380                        // check whenever iterator is valid
381                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
382                                NR_Log(Log::LOG_KERNEL, "No such Task (id=%d) found !!!", id);
383                                return KERNEL_NO_TASK_FOUND;
384                        }
385
386                        // check whenever we are allowed to remove the task
387                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM)
388                        {
389                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to remove this task!");
390                                return KERNEL_NO_RIGHTS;
391
392                        }else{
393                                // say task want to remove his self
394                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
395                                (*it)->_taskCanKill = true;
396                        }
397
398                } catch(...){
399                        return UNKNOWN_ERROR;
400                }
401
402                // OK
403                return OK;
404        }
405
406
407        //-------------------------------------------------------------------------
408        Result Kernel::SuspendTask  (TaskId id){
409
410                try{
411
412                        NR_Log(Log::LOG_KERNEL, "Suspend task (id=%d)", id);
413
414                        // find the task
415                        PipelineIterator it;
416
417                        // check whenever iterator is valid
418                        if (!_getTaskByID(id, it)){
419                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
420                                return KERNEL_NO_TASK_FOUND;
421                        }else{
422                                SharedPtr<ITask> &t = (*it);
423
424                                if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
425                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to suspend this task!");
426                                        return KERNEL_NO_RIGHTS;
427                                }else{
428
429                                        // suspend task
430                                        Result res = t->onSuspendTask();
431                                        if (res == OK){
432                                                t->setTaskState(TASK_PAUSED);
433
434                                                // before removing the task from task std::list move it to paused std::list
435                                                // so we can guarantee that task object will be held in memory
436                                                pausedTaskList.push_back(t);
437                                                taskList.erase(it);
438                                                NR_Log(Log::LOG_KERNEL, "Task id=%d is sleeping now", id);
439
440                                                // send a message about current task state
441                                                if (bSendEvents){
442                                                        SharedPtr<Event> msg(new KernelSuspendTaskEvent(t->getTaskName(), t->getTaskID()));
443                                                        Engine::sEventManager()->emitSystem(msg);
444                                                }
445
446                                        }else{
447                                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not suspend! Check this!", id);
448                                                return res;
449                                        }
450                                }
451                        }
452
453                } catch(...){
454                        return UNKNOWN_ERROR;
455                }
456
457                // OK
458                return OK;
459        }
460
461        //-------------------------------------------------------------------------
462        Result Kernel::ResumeTask  (TaskId id){
463
464                try{
465
466                        NR_Log(Log::LOG_KERNEL, "Resume task (id=%d)", id);
467
468                        // find the task
469                        PipelineIterator it;
470
471                        // check whenever iterator is valid
472                        if (!_getTaskByID(id, it, TL_SLEEPING)){
473                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
474                                return KERNEL_NO_TASK_FOUND;
475                        }
476
477                        SharedPtr<ITask> &t = (*it);
478                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
479                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to resume this task!");
480                                return KERNEL_NO_RIGHTS;
481                        }else{
482
483                                // resume the task
484                                Result res = t->onResumeTask();
485                                if (res == OK){
486                                        t->setTaskState(TASK_RUNNING);
487
488                                        //keep the order of priorities straight
489                                        for( it = taskList.begin(); it != taskList.end(); it++){
490                                                SharedPtr<ITask> &comp=(*it);
491                                                if(comp->getTaskOrder() >= t->getTaskOrder()) break;
492                                        }
493                                        taskList.insert(it,t);
494
495                                        // erase task from paused std::list. Therefor we have to find it in the std::list
496                                        if (_getTaskByID(id, it, TL_SLEEPING)){
497                                                pausedTaskList.erase(it);
498                                        }
499
500                                        // send a message about current task state
501                                        if (bSendEvents){
502                                                SharedPtr<Event> msg(new KernelResumeTaskEvent(t->getTaskName(), t->getTaskID()));
503                                                Engine::sEventManager()->emitSystem(msg);
504                                        }
505
506                                }else{
507                                        NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "Task id=%d can not resume, so it stay in sleep mode", id);
508                                        return res;
509                                }
510                        }
511
512                } catch(...){
513                        return UNKNOWN_ERROR;
514                }
515
516                // OK
517                return OK;
518        }
519
520        //-------------------------------------------------------------------------
521        Result Kernel::StopExecution(){
522
523                try{
524
525                        NR_Log(Log::LOG_KERNEL, "Stop the kernel subsystem");
526
527                        // iterate through all tasks and kill them
528                        for(PipelineIterator it = taskList.begin(); it != taskList.end(); it++){
529                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
530                                (*it)->_taskCanKill=true;
531                        }
532
533                        // iterate also through all paused tasks and kill them also
534                        for(PipelineIterator it = pausedTaskList.begin(); it != pausedTaskList.end(); it++){
535                                NR_Log(Log::LOG_KERNEL, "Prepare to die: \"%s\" (id=%d)", (*it)->getTaskName(), (*it)->getTaskID());
536                                (*it)->_taskCanKill=true;
537                        }
538
539                        // Info if we do not have any tasks to kill
540                        if (!taskList.size() && !pausedTaskList.size())
541                                NR_Log(Log::LOG_KERNEL, "There is no more tasks to be killed !");
542
543                } catch(...){
544                        return UNKNOWN_ERROR;
545                }
546
547                // OK
548                return OK;
549
550        }
551
552
553        //-------------------------------------------------------------------------
554        Result Kernel::ChangeTaskOrder(TaskId id, TaskOrder order){
555
556                try{
557
558                        NR_Log(Log::LOG_KERNEL, "Change order of task (id=%d) to %d", id, int32(order));
559
560                        // find the task
561                        PipelineIterator it;
562
563                        // check whenever iterator is valid
564                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
565                                NR_Log(Log::LOG_KERNEL, "No task with id=%d found", id);
566                                return KERNEL_NO_TASK_FOUND;
567                        }
568
569                        SharedPtr<ITask> &t = (*it);
570
571                        // check if the given order number is valid
572                        if (order <= ORDER_SYS_LAST && t->getTaskType() == TASK_USER)
573                        {
574                                NR_Log(Log::LOG_KERNEL, "User task are not allowed to work on system order numbers!");
575                                return KERNEL_NO_RIGHTS;
576                        }
577
578                        // check for task access rights
579                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
580                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to change the order of system task!");
581                                return KERNEL_NO_RIGHTS;
582                        }else{
583
584                                // change order of the task
585                                t->setTaskOrder(order);
586                                t->_orderChanged = false;
587
588                                // sort lists
589                                pausedTaskList.sort();
590                                taskList.sort();
591                        }
592
593                } catch(...){
594                        return UNKNOWN_ERROR;
595                }
596
597                // OK
598                return OK;
599        }
600
601        //-------------------------------------------------------------------------
602        bool Kernel::_getTaskByID(TaskId id, PipelineIterator& jt, int32 useList){
603
604                // get std::list we want to search in
605                std::list< SharedPtr<ITask> > *li = NULL;
606
607                // search in normal list
608                if ((useList & TL_RUNNING) == TL_RUNNING){
609                        li = &taskList;
610
611                        // iterate through elements and search for task with same id
612                        PipelineIterator it;
613                        for ( it = li->begin(); it != li->end(); it++){
614                                if ((*it)->getTaskID() == id){
615                                        jt = it;
616                                        return true;
617                                }
618                        }
619                }
620
621                // search in paused list
622                if ((useList & TL_SLEEPING) == TL_SLEEPING){
623                        li = &pausedTaskList;
624
625                        // iterate through elements and search for task with same id
626                        PipelineIterator it;
627                        for ( it = li->begin(); it != li->end(); it++){
628                                if ((*it)->getTaskID() == id){
629                                        jt = it;
630                                        return true;
631                                }
632                        }
633
634                }
635
636                // not found so return an end iterator
637                return false;
638        }
639
640        //-------------------------------------------------------------------------
641        bool Kernel::_getTaskByName(const std::string& name, PipelineIterator& it, int32 useList){
642
643                // get std::list we want to search in
644                std::list< SharedPtr<ITask> > *li = NULL;
645
646                // search in normal list
647                if ((useList & TL_RUNNING) == TL_RUNNING){
648                        li = &taskList;
649
650                        // iterate through elements and search for task with same id
651                        PipelineIterator jt;
652                        for ( jt = li->begin(); jt != li->end(); jt++){
653                                if ((*jt)->getTaskName() == name){
654                                        it = jt;
655                                        return true;
656                                }
657                        }
658                }
659
660                // search in paused list
661                if ((useList & TL_SLEEPING) == TL_SLEEPING){
662                        li = &pausedTaskList;
663
664                        // iterate through elements and search for task with same id
665                        PipelineIterator jt;
666                        for ( jt = li->begin(); jt != li->end(); jt++){
667                                if ((*jt)->getTaskName() == name){
668                                        it = jt;
669                                        return true;
670                                }
671                        }
672                }
673
674                // not found so return end iterator
675                return false;
676        }
677
678        //-------------------------------------------------------------------------
679        SharedPtr<ITask> Kernel::getTaskByID(TaskId id){
680                try{
681
682                        // find the task
683                        PipelineIterator it;
684
685                        // check whenever iterator is valid
686                        if (!_getTaskByID(id, it, TL_RUNNING | TL_SLEEPING)){
687                                NR_Log(Log::LOG_KERNEL, "getTaskByID: No task with id=%d found", id);
688                                return SharedPtr<ITask>();
689                        }
690
691                        // check the rights
692                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
693                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
694                                return SharedPtr<ITask>();
695                        }
696
697                        return *it;
698
699                } catch(...){
700                        return SharedPtr<ITask>();
701                }
702
703        }
704
705
706        //-------------------------------------------------------------------------
707        SharedPtr<ITask> Kernel::getTaskByName(const std::string& name){
708                try{
709
710                        // find the task
711                        PipelineIterator it;
712
713                        // check whenever iterator is valid
714                        if (!_getTaskByName(name, it, TL_RUNNING | TL_SLEEPING)){
715                                NR_Log(Log::LOG_KERNEL, "getTaskByName: No task with name=%s found", name.c_str());
716                                return SharedPtr<ITask>();
717                        }
718
719                        // check the rights
720                        if (!areSystemTasksAccessable() && (*it)->getTaskType() == TASK_SYSTEM){
721                                NR_Log(Log::LOG_KERNEL, Log::LL_WARNING, "You do not have rights to access to this task!");
722                                return SharedPtr<ITask>();
723                        }
724
725                        return *it;
726
727                } catch(...){
728                        return SharedPtr<ITask>();
729                }
730        }
731
732        //-------------------------------------------------------------------------
733        Result Kernel::_loopStartCycle()
734        {
735
736                // Profiling of the engine
737                _nrEngineProfile("Kernel::_loopStartCycle");
738
739                // iterate through the tasks and mark them as non visited
740                _loopIterator = taskList.begin();
741                while (_loopIterator != taskList.end())
742                {
743                        (*_loopIterator)->_taskGraphColor = 0;
744                        _loopIterator ++;
745                }
746
747                _loopIterator = pausedTaskList.begin();
748                while (_loopIterator != pausedTaskList.end())
749                {
750                        (*_loopIterator)->_taskGraphColor = 0;
751                        _loopIterator ++;
752                }
753
754
755                _loopIterator = taskList.begin();
756
757                return OK;
758        }
759
760        //-------------------------------------------------------------------------
761        Result Kernel::_loopGetNextTask(PipelineIterator it, PipelineIterator& result, int depth)
762        {
763                // Profiling of the engine
764                _nrEngineProfile("Kernel::_loopGetNextTask");
765
766                // check whenever this is the end
767                if (it == taskList.end()) return KERNEL_END_REACHED;
768
769                // get the task in this iterator
770                const SharedPtr<ITask>& t = *it;
771
772                if (t->_taskGraphColor == 1) return KERNEL_CIRCULAR_DEPENDENCY;
773                if (t->_taskGraphColor == 2) return KERNEL_END_REACHED;
774
775                t->_taskGraphColor = 1;
776               
777                // now check if the task has got childrens
778                if (t->_taskDependencies.size() > 0){
779
780                        // do for each child call this function recursively
781                        for (uint32 i = 0; i < t->_taskDependencies.size(); i++){
782
783                                PipelineIterator jt;
784                                if (!_getTaskByID(t->_taskDependencies[i], jt, TL_RUNNING | TL_SLEEPING)) return KERNEL_TASK_MISSING;
785
786                                // check whenever the child was already visited
787                                if ((*jt)->_taskGraphColor != 2){
788                                        Result ret = _loopGetNextTask(jt, result, depth+1);
789
790                                        // we return OK only if we have not found any circularity
791                                        // and we are on the top (root-node)
792                                        if (ret != OK){
793                                                t->_taskGraphColor = 0;
794                                                if (depth == 0 && ret != KERNEL_CIRCULAR_DEPENDENCY) return OK;
795                                                return ret;
796                                        }
797                                }
798                        }
799
800                // we do not have childs, so this is a leaf node
801                }
802
803                // all our chlds are visited, so return the node itself
804                t->_taskGraphColor = 2;
805                result = it;
806                return KERNEL_LEAF_TASK;
807
808        }
809
810        //-------------------------------------------------------------------------
811        Result Kernel::_loopEndCycle()
812        {
813                return OK;
814        }
815
816}; //namespace nrEngine
817
Note: See TracBrowser for help on using the repository browser.