Mercurial > hg > Members > kono > Cerium
view TaskManager/kernel/schedule/Scheduler.cc @ 187:ac52c139ad45
fix
author | gongo@localhost.localdomain |
---|---|
date | Thu, 08 Jan 2009 13:46:57 +0900 |
parents | 907bda4a1a14 |
children | d734af296d38 |
line wrap: on
line source
#include <stdio.h> #include <stdlib.h> #include "Scheduler.h" #include "SchedNop.h" #include "error.h" Scheduler::TaskObject task_list[MAX_TASK_OBJECT]; Scheduler::~Scheduler(void) { delete connector; } void Scheduler::init(void) { init_impl(); for (int i = 0; i < 2; i++) { buff_taskList[i] = (TaskListPtr)allocate(sizeof(TaskList)); buff_inListData[i] = (ListDataPtr)allocate(sizeof(ListData)); buff_outListData[i] = (ListDataPtr)allocate(sizeof(ListData)); } buffFlag_taskList = 0; buffFlag_inListData = 0; buffFlag_outListData = 0; flag_renewTaskList = 0; // bzero でもいいけど for (int i = 0; i < MAX_GLOBAL_AREA; i++) { globalList[i] = NULL; } for (int i = 0; i < MAX_MAINMEM_AREA; i++) { mainMemList[i] = NULL; } taskGroup = new TaskGroup; renewTop_taskList = NULL; renewCur_taskList = NULL; } void Scheduler::run(void) { SchedTaskBase* taskTmp; task1 = new SchedNop(); task2 = new SchedNop(); task3 = new SchedNop(); // main loop do { __debug("----------\n"); task3->write(); task2->exec(); task1->read(); taskTmp = task3; task3 = task2; task2 = task1; task1 = task1->next(this, taskTmp); } while (task1); delete task3; delete task2; } void Scheduler::finish(void) { free(buff_taskList[0]); free(buff_taskList[1]); free(buff_inListData[0]); free(buff_inListData[1]); free(buff_outListData[0]); free(buff_outListData[1]); } /** * あらかじめ memory allocte してある TaskList の領域を * パイプラインの各処理が交代して使う。 */ TaskListPtr Scheduler::get_curListBuf(void) { buffFlag_taskList ^= 1; return buff_taskList[buffFlag_taskList]; } /** * あらかじめ memory allocte してある ListData の領域を * パイプラインの各処理が交代して使う。 */ ListDataPtr Scheduler::get_curWriteBuf(void) { buffFlag_outListData ^= 1; return buff_outListData[buffFlag_outListData]; } ListDataPtr Scheduler::get_curReadBuf(void) { buffFlag_inListData ^= 1; return buff_inListData[buffFlag_inListData]; } /** * タスク内で生成されたタスクを格納する TaskList を取得する * 現在格納に使っている TaskList (renewCur_taskList) が使えるならそれを返す * もしそうでないなら、新しく TaskList を allocate してそれを返す * コード中で renewCur_taskList が NULL になるのは * - プログラム開始時 * - タスク内生成タスクがある TaskList の実行を新しく始める (Nop2Ready 参照) * 以上の場合です */ TaskListPtr Scheduler::get_renewListBuf(void) { if (renewCur_taskList && renewCur_taskList->length < TASK_MAX_SIZE) { return renewCur_taskList; } else { TaskListPtr newList = (TaskListPtr)allocate(sizeof(TaskList)); newList->length = 0; newList->next = NULL; renewTop_taskList = TaskList::append(renewTop_taskList, newList); renewCur_taskList = newList; return newList; } } /** * 次に実行する Renew Task List を返す * * @param[in] curList 現在実行中の TaskList * 中断して RenewTaskList を行うため * バックアップを取っておく * @return next RenewTaskList */ SchedTaskList* Scheduler::get_nextRenewTaskList(void) { if (renewTop_taskList) { TaskListPtr list = renewTop_taskList; renewTop_taskList = renewTop_taskList->next; renewCur_taskList = NULL; list->next = NULL; SchedTaskList *sched = createSchedTaskList((uint32)list, this, SCHED_TASKLIST_RENEW); return sched; } else { return NULL; } } void Scheduler::set_backupTaskList(TaskListPtr cur_taskList) { bak_curTaskList = cur_taskList; } void Scheduler::set_backupTaskListIndex(int cur_index) { bakIndex_taskList = cur_index; } /** * RenewTaskList 実行前に中断した TaskList を返す * NULL の場合、中断した TaskList は無い。 * * @return TaskList */ TaskListPtr Scheduler::get_backupTaskList(void) { TaskListPtr ret = bak_curTaskList; bak_curTaskList = NULL; return ret; } int Scheduler::get_backupTaskListIndex(void) { int ret = bakIndex_taskList; bakIndex_taskList = 0; return ret; } void Scheduler::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) { connector->dma_load(buf, addr, size, mask); } void Scheduler::dma_store(void *buf, uint32 addr, uint32 size, uint32 mask) { connector->dma_store(buf, addr, size, mask); } void Scheduler::dma_wait(uint32 mask) { connector->dma_wait(mask); } void Scheduler::dma_loadList(ListDataPtr list, void *buff, uint32 mask) { connector->dma_loadList(list, buff, mask); } void Scheduler::dma_storeList(ListDataPtr list, void *buff, uint32 mask) { return connector->dma_storeList(list, buff, mask); } void Scheduler::mail_write(uint32 data) { connector->mail_write(data); } uint32 Scheduler::mail_read(void) { return connector->mail_read(); } TaskGroupPtr Scheduler::set_groupTask(uint32 command) { TaskGroupPtr ret = taskGroup; reload_groupTask(); ret->command = command; return ret; } void Scheduler::add_groupTask(TaskGroupPtr group, TaskPtr task) { group->add(task); } void Scheduler::remove_groupTask(TaskGroupPtr group, TaskPtr task) { group->remove(task); } void Scheduler::reload_groupTask(void) { taskGroup = new TaskGroup; } uint32 Scheduler::status_groupTask(TaskGroupPtr group) { return group->status(); } void* Scheduler::global_alloc(int id, int size) { globalList[id] = allocate(size); return globalList[id]; } void* Scheduler::global_get(int id) { return globalList[id]; } void Scheduler::global_free(int id) { free(globalList[id]); globalList[id] = NULL; } /** * mainMem_alloc で確保したメインメモリの領域アドレスを返す。 * これは Fifo, Cell で共通 */ void* Scheduler::mainMem_get(int id) { return mainMemList[id]; } /** * 本当は Scheduler クラスに入れるべきなんだろうか。。。 * なんか手抜きの感がある */ void register_task(int cmd, Scheduler::TaskObject task) { task_list[cmd] = task; }