Mercurial > hg > Members > kono > Cerium
view TaskManager/kernel/schedule/SchedTaskArray.cc @ 871:ab3cd3aeacff
fix get segment dma tag zero problem
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Sun, 04 Jul 2010 16:56:04 +0900 |
parents | c7905ead974f |
children | 1c12673c11be |
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) { 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; } /** 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); } /** */ 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); 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(); outListData.element = atask->outData(0); outListData.bound = (int*)manager->allocate(outListData.length*sizeof(int)); bound(&outListData); writebuf = manager->allocate(outListData.size); } scheduler->dma_wait(DMA_READ); (*run)(this, readbuf, writebuf); 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 が残っているので、次を準備 return new SchedTaskArray(scheduler, savedTask, next, array); } else { //このTaskArrayは終わったが、Pipeline 上にread の TaskArray が残っているので //1ステージを稼ぐ必要がある 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() { printf("Don't use read_size() in TaskArray, use get_inputSize(index)\n"); return 0; } /* end */