Mercurial > hg > Game > Cerium
view TaskManager/kernel/schedule/SchedTask.cc @ 1474:b158873485f6 draft
fix simple task
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 16 Jul 2012 11:01:40 +0900 |
parents | d585a7614cd5 |
children | eee4f68409dd |
line wrap: on
line source
#include <stdlib.h> #include <string.h> #include "SchedTask.h" #include "SysFunc.h" #include "SchedTaskList.h" #include "SchedNop2Ready.h" #include "DmaManager.h" #include "error.h" #include "TaskManager.h" #include <stdarg.h> extern TaskObject task_list[MAX_TASK_OBJECT]; SchedTask::SchedTask() { list = NULL; atask = NULL; readbuf = NULL; writebuf = NULL; scheduler = NULL; cur_index = 0; din[0] = dout[0] = 0; this->stdout_ = stdout; this->stderr_ = stderr; this->stdin_ = stdin; } SchedTask::~SchedTask() { } void SchedTask::init(TaskListPtr _list, TaskPtr _task, Scheduler* sc, int tag) { list = _list; atask = _task; scheduler = sc; this->tag = tag; // scheduler->mainMem_wait(); // これはなんで? manager = sc->manager; connector = sc->connector; inListData.bound = din; inListData.size = 0; inListData.length = 0; inListData.element = 0; outListData.bound = dout; outListData.size = 0; outListData.length = 0; outListData.element = 0; cur_index = _task; this->tag = tag; #ifdef TASK_LIST_MAIL if (list) waiter = (memaddr) list->waiter; #else if (task) waiter = (memaddr) task->self; #endif } void SchedTask::read() { __debug("[SchedTask:%s]\n", __FUNCTION__); // object creation をSchedTask生成時にやらないので、 // 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, (DMA_READ + this->tag)); connector->bound(&inListData); } void SchedTask::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); // if (outListData.bound!=dout) free(outListData.bound); outListData.bound = (int*)manager->allocate(outListData.length*sizeof(int)); connector->bound(&outListData); writebuf = connector->get_writebuf(scheduler, (memaddr)outListData.element[0].addr, outListData.size); } void SchedTask::exec() { task_list[atask->command].wait(scheduler,atask->command); TaskObjectRun run = task_list[atask->command].run; if (atask->outData_count > 0) { setup_outputData(); // we need write buffer before run() } connector->dma_wait((DMA_READ + this->tag)); void *read = get_input(readbuf, 0); void *write = get_output(writebuf, 0); run(this, read,write); connector->free_(readbuf); // User 側で作る方法が必要... // 書き込む領域がなければ無視 if (atask->outData_count > 0) { // outListData.print(); connector->dma_storeList(&outListData, writebuf, DMA_WRITE); } } void SchedTask::write() { __debug("[SchedTask:%s]\n", __FUNCTION__); connector->dma_wait(DMA_WRITE); connector->free_(writebuf); if (inListData.bound != din) free(inListData.bound); if (outListData.bound != dout) free(outListData.bound); #ifdef TASK_LIST_MAIL if ((cur_index->next() >= list->last()) ) connector->mail_write(waiter); #else connector->mail_write(waiter); #endif } SchedTaskBase* SchedTask::next(Scheduler *scheduler, SchedTaskBase *p) { __debug("[SchedTask:%s]\n", __FUNCTION__); if (cur_index == 0) { // 最初の一つ SchedTask *nextSched = new SchedTask(); nextSched->init(list, &list->tasks[0], scheduler, this->tag^1); return nextSched; } TaskPtr nextTask = cur_index->next(); if (nextTask < list->last()) { // Task List が残っているので、次を準備 TaskPtr nextTask = cur_index->next(); SchedTask *nextSched = new SchedTask(); nextSched->init(list, nextTask, scheduler, this->tag^1); return nextSched; } else { memaddr nextList = (memaddr)list->next; if (nextList == 0) { // もう何もする必要がない return new SchedNop2Ready(scheduler); } else { // 新しいリストに取り掛かる int dma_tag_switch = 0; return new SchedTaskList(nextList, scheduler, dma_tag_switch); } } } int SchedTask::get_cpuid() { return scheduler->id; } void SchedTask::free_(void *p) { scheduler->free_(p); } /** * SimpleTask has one parameter , one input, one output */ /** * task->add_inData で与えられた順番に対応する index (0〜n-1) で、 * buffer から対応するデータを返す。 */ void* SchedTask::get_input(void *buff, int index) { return (void*)((char*)readbuf + inListData.bound[index]); } /** * get_input(index) のアドレスを返す */ memaddr SchedTask::get_inputAddr(int index) { #ifdef __CERIUM_CELL__ return (memaddr)inListData.element[index].addr; #else return inListData.element[index].addr; #endif } /** * get_input(index) のサイズを返す */ int SchedTask::get_inputSize(int index) { return inListData.element[index].size; } int SchedTask::read_size() { return get_inputSize(0); } /** * write buffer の領域を返す。 */ void* SchedTask::get_output(void *buff, int index) { return (void*)((char *)writebuf + outListData.bound[index]); } /** * get_output(index) のアドレスを返す */ memaddr SchedTask::get_outputAddr(int index) { #ifdef __CERIUM_CELL__ return (memaddr)outListData.element[index].addr; #else return outListData.element[index].addr; #endif } /** * get_output(index) のサイズを返す */ int SchedTask::get_outputSize(int index) { return outListData.element[index].size; } int SchedTask::write_size() { return get_outputSize(0); } void SchedTask::set_outputSize(int index, int size) { outListData.element[index].size = size; } memaddr SchedTask::get_param(int index) { return *atask->param(index); } void* SchedTask::global_alloc(int id, int size) { return scheduler->global_alloc(id, size); } void* SchedTask::global_get(int id) { return scheduler->global_get(id); } void SchedTask::global_set(int id, void *addr) { scheduler->global_set(id, addr); } void SchedTask::global_free(int id) { scheduler->global_free(id); } MemList* SchedTask::createMemList(int size, int count) { return scheduler->createMemList(size, count); } void SchedTask::mainMem_alloc(int id, int size) { scheduler->mainMem_alloc(id, size); } void SchedTask::mainMem_wait() { scheduler->mainMem_wait(); } memaddr SchedTask::mainMem_get(int id) { return scheduler->mainMem_get(id); } void * SchedTask::dma_load(void *buf, memaddr addr, uint32 size, uint32 mask) { return connector->dma_load1(buf, addr, size, mask); // direct DMA API (should be purged ) } void * SchedTask::get_load_buf(uint32 size) { return connector->get_writebuf(scheduler, 0, size); // direct DMA API (should be purged ) } void SchedTask::free_load_buf(void *buf) { return connector->free_(buf); // direct DMA API (should be purged ) } void SchedTask::dma_store(void *buf,memaddr addr, uint32 size, uint32 mask) { connector->dma_store(buf, addr, size, mask); } void SchedTask::dma_wait(uint32 mask) { connector->dma_wait(mask); } void SchedTask::show_dma_wait() { connector->show_dma_wait(scheduler, scheduler->id); } long SchedTask::get_random() { return scheduler->get_random(); } void SchedTask::start_profile() { connector->start_profile(); } MemorySegment * SchedTask::get_segment(memaddr addr, MemList *m) { return scheduler->get_segment(addr,m); } MemorySegment * SchedTask::get_free_segment(memaddr addr, MemList *m) { return scheduler->get_free_segment(addr,m); } void SchedTask::overwrite_segment(MemorySegment *s, memaddr addr) { return scheduler->overwrite_segment(s,addr); } void SchedTask::put_segment(MemorySegment *s) { scheduler->put_segment(s); } void SchedTask::wait_segment(MemorySegment *s) { scheduler->wait_segment(s); } HTaskPtr SchedTask::create_task(int cmd) { return manager->create_task(cmd, __builtin_return_address(0)); } HTaskPtr SchedTask::create_task(int cmd, memaddr r, long rs, memaddr w, long ws) { return manager->create_task(cmd,r,rs,w,ws, __builtin_return_address(0)); } HTaskPtr SchedTask::create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData) { return manager->create_task_array(id, num_task, num_param, num_inData, num_outData, __builtin_return_address(0)); } void SchedTask::free_htask(HTask *p) { #if !defined(__SPU__) manager->free_htask(p); #endif } void SchedTask::set_task_depend(HTaskPtr master, HTaskPtr slave) { manager->set_task_depend(master, slave); } void SchedTask::spawn_task(HTaskPtr t) { manager->spawn_task(t); } void SchedTask::set_task_cpu(HTaskPtr t, CPU_TYPE cpu) { manager->set_task_cpu(t, cpu); } void* SchedTask::allocate(int size) { return manager->allocate(size) ; } void* SchedTask::allocate(int size,int align) { return manager->allocate(size,align) ; } void SchedTask::polling() { manager->polling(); } Scheduler* SchedTask::get_scheduler() { return scheduler; } /* system call */ int SchedTask::printf(const char * format, ...) { va_list ap; va_start(ap,format); int ret= scheduler->vprintf0(format, ap); va_end(ap); return ret; } /* end */