Mercurial > hg > Members > kono > Cerium
view TaskManager/kernel/schedule/SchedTaskArray.cc @ 703:61b59376aec5
compatibility
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 14 Dec 2009 18:34:46 +0900 |
parents | 226d95fa2691 |
children | 6d497c098455 |
line wrap: on
line source
#include "SchedTaskArray.h" #include "Scheduler.h" SchedTaskArray::SchedTaskArray(Scheduler *s, SchedTaskBase *savedTask_, Task *curTask_, Task *_array) { savedTask = savedTask_; task = 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_; SchedTask *sv = (SchedTask*)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; array = task = (TaskPtr)&sv->list->tasks[sv->cur_index]; sv->cur_index += (task->size())/sizeof(SimpleTask); } /** */ SchedTaskArray::~SchedTaskArray() { } 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; } } void SchedTaskArray::read() { __debug("[SchedTaskArrayArray:%s]\n", __FUNCTION__); // object creation をSchedTaskArray生成時にやらないので、 // exec の直前のread で十分に間に合う loadSchedTask(scheduler, task->command); // 読むデータが一つもなければ無視 if (task->inData_count == 0) return; inListData.length = task->inData_count; inListData.size = task->inData_total_size(); inListData.element = task->inData(0); inListData.bound = (int*)scheduler->allocate(inListData.length*sizeof(int)); // load Input Data readbuf = scheduler->allocate(inListData.size); // inListData.print(); scheduler->dma_loadList(&inListData, readbuf, DMA_READ); bound(&inListData); } void SchedTaskArray::exec() { __debug("[SchedTaskArrayArray:%s]\n", __FUNCTION__); if (task->outData_count > 0) { outListData.length = task->outData_count; outListData.size = task->outData_total_size(); outListData.element = task->outData(0); outListData.bound = (int*)scheduler->allocate(outListData.length*sizeof(int)); bound(&outListData); writebuf = scheduler->allocate(outListData.size); } scheduler->dma_wait(DMA_READ); task_list[task->command].wait(scheduler,task->command); task_list[task->command].run(this, readbuf, writebuf); free(readbuf); // 書き込む領域がなければ無視 // User 側で作る方法が必要... if (task->outData_count > 0) { // outListData.print(); scheduler->dma_storeList(&outListData, writebuf, DMA_WRITE); } } void SchedTaskArray::write() { __debug("[SchedTaskArrayArray:%s]\n", __FUNCTION__); scheduler->dma_wait(DMA_WRITE); free(writebuf); free(inListData.bound); free(outListData.bound); // このTaskArrayは終り。終了を知らせる。 if (task->next() >= last()) { SchedTask *s = (SchedTask *)savedTask; scheduler->mail_write((memaddr)s->task->self); free(array); } } Task *SchedTaskArray::last() { SchedTask *s = (SchedTask *)savedTask; return (Task*)(((char*)array)+ s->read_size()); } SchedTaskBase* SchedTaskArray::next(Scheduler *scheduler, SchedTaskBase *p) { __debug("[SchedTaskArray:%s]\n", __FUNCTION__); Task *next = task->next(); if (next < last()) { // Task List が残っているので、次を準備 return (SchedTaskBase*)new SchedTaskArray(scheduler, savedTask, next, array); } else { // このTaskArrayは終り。save していた Task の次を返す。 // savedTask の read/exec は実行されない (command = TaskArray) return savedTask->next(scheduler, savedTask); } } /** * 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 *task->param(index); } /* end */