Mercurial > hg > Game > Cerium
view TaskManager/kernel/schedule/SchedTaskArray.cc @ 1413:5b024efa2429 draft
fix free on non copy DMA
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 19 Feb 2012 10:07:27 +0900 |
parents | 44d9b08519e0 |
children | 94ac6d8e73aa |
line wrap: on
line source
#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; connector = s->connector; 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; connector = s->connector; 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() { } /** * 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 // inListData.print(); readbuf = connector->dma_loadList(scheduler, &inListData, readbuf, (DMA_READ + this->tag)); connector->bound(&inListData); } void SchedTaskArray::setup_outputData() { // 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); free(outListData.bound); outListData.bound = (int*)manager->allocate(outListData.length*sizeof(int)); connector->bound(&outListData); // connector->free(writebuf); what?! writebuf = connector->get_writebuf(scheduler, &outListData, outListData.size); //if (outListData.element == inListData.element ) { // printf("bad %x\n",outListData.element); //} } /** * 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) { setup_outputData(); } connector->dma_wait((DMA_READ + this->tag)); run(this, get_input(readbuf, 0), get_output(writebuf, 0)); connector->free(readbuf); // 書き込む領域がなければ無視 // User 側で作る方法が必要... if (atask->outData_count > 0) { // outListData.print(); connector->dma_storeList(&outListData, writebuf, DMA_WRITE); } } /** * Wait write DMA * send finish mail */ void SchedTaskArray::write() { connector->dma_wait(DMA_WRITE); connector->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; } void SchedTaskArray::set_outputSize(int index, int size) { outListData.element[index].size = size; } memaddr SchedTaskArray::get_param(int index) { return *atask->param(index); } int SchedTaskArray::read_size() { return get_inputSize(0); } /* end */