Mercurial > hg > Members > e085722 > Cerium
diff TaskManager/kernel/schedule/SchedTaskArray.cc @ 0:04e28d8d3c6f
first commit
author | Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 08 Nov 2010 01:23:25 +0900 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TaskManager/kernel/schedule/SchedTaskArray.cc Mon Nov 08 01:23:25 2010 +0900 @@ -0,0 +1,263 @@ +#include "SchedTaskArray.h" +#include "SchedTaskArrayNop.h" +#include "Scheduler.h" +#include "TaskManagerImpl.h" + + +SchedTaskArray::SchedTaskArray(Scheduler *s, SchedTaskBase *savedTask_, Task *curTask_, Task *_array, int tag) +{ + savedTask = savedTask_; + atask = curTask_; + array = _array; + scheduler = s; + + inListData.bound = 0; + inListData.size = 0; + inListData.length = 0; + inListData.element = 0; + outListData.bound = 0; + outListData.size = 0; + outListData.length = 0; + outListData.element = 0; + + cur_index = -1; + task = 0; + + this->tag = tag; + +} + +/** + Constructor for old Task with ListData + next TaskList entry contains Task object. + savedTask->rbuf is 0, it has only one Task. + */ + +SchedTaskArray::SchedTaskArray(Scheduler *s, SchedTaskBase *savedTask_) +{ + savedTask = savedTask_; + scheduler = s; + + inListData.bound = 0; + inListData.size = 0; + inListData.length = 0; + inListData.element = 0; + outListData.bound = 0; + outListData.size = 0; + outListData.length = 0; + outListData.element = 0; + + SimpleTaskPtr st = &savedTask->list->tasks[savedTask->cur_index]; + atask = (TaskPtr)st; + array = 0; + savedTask->cur_index += (atask->size()+sizeof(SimpleTask))/sizeof(SimpleTask); + cur_index = -1; + task = 0; + + this->tag = 0; + +} + +/** + */ +SchedTaskArray::~SchedTaskArray() +{ +} + +/** + * DMA buffer offset in rbuf + */ +static void +bound(ListData *list) +{ + ListElement *elm = list->element; + int *bound = list->bound; + int offset=0; + for(int i=0;i<list->length;i++) { + bound[i] = offset; + offset += elm[i].size; + } +} + + +/** + * Task data / code read + */ +void +SchedTaskArray::read() +{ + + // object creation をSchedTaskArray生成時にやらないので、 + // exec の直前のread で十分に間に合う + loadSchedTask(scheduler, atask->command); + + // 読むデータが一つもなければ無視 + if (atask->inData_count == 0) return; + + inListData.length = atask->inData_count; + inListData.size = atask->inData_total_size(); + inListData.element = atask->inData(0); + inListData.bound = (int*)manager->allocate(inListData.length*sizeof(int)); + + // load Input Data + readbuf = manager->allocate(inListData.size); + // inListData.print(); + scheduler->dma_loadList(&inListData, readbuf, (DMA_READ + this->tag)); + bound(&inListData); + +} + +/** + * Wait read data and execute task + * Start write DMA + */ +void +SchedTaskArray::exec() +{ + task_list[atask->command].wait(scheduler,atask->command); + TaskObjectRun run = task_list[atask->command].run; + if (atask->outData_count > 0) { + // allocate write buffer + outListData.length = atask->outData_count; + outListData.size = atask->outData_total_size(); + // atask->outData_offset += cur_index + 1 ; // to avoid compiler bug + outListData.element = atask->outData(0); + outListData.bound = (int*)manager->allocate(outListData.length*sizeof(int)); + bound(&outListData); + + writebuf = manager->allocate(outListData.size); + //if (outListData.element == inListData.element ) { + // printf("bad %x\n",outListData.element); + //} + } + scheduler->dma_wait((DMA_READ + this->tag)); + run(this, get_input(readbuf, 0), get_output(writebuf, 0)); + free(readbuf); + // 書き込む領域がなければ無視 + + // User 側で作る方法が必要... + + if (atask->outData_count > 0) { + // outListData.print(); + scheduler->dma_storeList(&outListData, writebuf, DMA_WRITE); + } +} + +/** + * Wait write DMA + * send finish mail + */ +void +SchedTaskArray::write() +{ + + scheduler->dma_wait(DMA_WRITE); + free(writebuf); + free(inListData.bound); + free(outListData.bound); +} + +Task *SchedTaskArray::last() +{ + SchedTask *s = (SchedTask *)savedTask; + return (Task*)(((char*)array)+ s->read_size()); +} + +SchedTaskBase* +SchedTaskArray::next(Scheduler *scheduler, SchedTaskBase *p) +{ + + Task *next = atask->next(); + if (next < last()) { + // Task List が残っているので、次を準備 + //scheduler->printf("hog\n"); + return new SchedTaskArray(scheduler, savedTask, next, array, this->tag^1); + } else { + + //このTaskArrayは終わったが、Pipeline 上にread の TaskArray が残っているので + //1ステージを稼ぐ必要がある + //scheduler->printf("auau\n"); + return new SchedTaskArrayNop(scheduler, savedTask, next, array); + + } +} + + + +/** + * task->add_inData で与えられた順番に対応する index (0〜n-1) で、 + * buffer から対応するデータを返す。 + */ +void* +SchedTaskArray::get_input(void *buff, int index) +{ + return (void*)((char*)readbuf + inListData.bound[index]); +} + +/** + * get_input(index) のアドレスを返す + */ +memaddr +SchedTaskArray::get_inputAddr(int index) +{ +#ifdef __CERIUM_CELL__ + return (memaddr)inListData.element[index].addr; +#else + return inListData.element[index].addr; +#endif +} + +/** + * get_input(index) のサイズを返す + */ +int +SchedTaskArray::get_inputSize(int index) +{ + return inListData.element[index].size; +} + +/** + * write buffer の領域を返す。 + */ +void* +SchedTaskArray::get_output(void *buff, int index) +{ + return (void*)((char *)writebuf + outListData.bound[index]); +} + +/** + * get_output(index) のアドレスを返す + */ +memaddr +SchedTaskArray::get_outputAddr(int index) +{ +#ifdef __CERIUM_CELL__ + return (memaddr)outListData.element[index].addr; +#else + return outListData.element[index].addr; +#endif +} + +/** + * get_output(index) のサイズを返す + */ +int +SchedTaskArray::get_outputSize(int index) +{ + return outListData.element[index].size; +} + +memaddr +SchedTaskArray::get_param(int index) +{ + return *atask->param(index); +} + +int +SchedTaskArray::read_size() +{ + return get_inputSize(0); +} + + +/* end */