Mercurial > hg > Members > kono > Cerium
view TaskManager/kernel/schedule/SchedTask.cc @ 639:70c5c2d2eb24
fix
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Thu, 19 Nov 2009 18:45:24 +0900 |
parents | 5530fa36d42e |
children | bffdede05f1e |
line wrap: on
line source
#include <stdlib.h> #include <string.h> #include "SchedTask.h" #include "SchedTaskList.h" #include "SchedNop2Ready.h" #include "DmaManager.h" #include "error.h" #include "TaskManager.h" #include <stdarg.h> extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT]; /** Task Object を作る */ SchedTask * createSchedTask(Scheduler *scheduler, TaskPtr task) { return new SchedTask(); } /** code load を始める。既に get_segment hash に入っていれば何もしない。 最初の一回は SchedTaskList:: next から呼ばれる。 この段階では、SchedTask object は、まだ作られてない。 */ static void loadSchedTask(Scheduler *scheduler,TaskPtr task) { // fprintf(stderr,"loadSchedTask %d\n",task->command); task_list[task->command].load(scheduler,task->command); } SchedTask::SchedTask() { list = NULL; task = NULL; #ifndef SIMPLE_TASK inListData = NULL; outListData = NULL; #endif readbuf = NULL; writebuf = NULL; scheduler = NULL; cur_index = 0; this->stdout_ = stdout; this->stderr_ = stderr; this->stdin_ = stdin; } /** * dma_store の wait を行う */ SchedTask::~SchedTask() { } void SchedTask::init(TaskListPtr _list, TaskPtr _task, int index, // ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc) { list = _list; task = _task; #ifndef SIMPLE_TASK inListData = &_task->inData; outListData = &_task->outData; #endif scheduler = sc; cur_index = index; scheduler->mainMem_wait(); } void SchedTask::read() { __debug("[SchedTask:%s]\n", __FUNCTION__); // object creation をSchedTask生成時にやらないので、 // exec の直前のread で十分に間に合う if (cur_index < list->length) { // load next task loadSchedTask(scheduler, &list->tasks[cur_index]); } #ifdef SIMPLE_TASK writebuf = scheduler->allocate(task->w_size); // 読むデータが一つもなければ無視 if (task->r_size == 0) return; // load Input Data readbuf = scheduler->allocate(task->r_size); scheduler->dma_load(readbuf, task->rbuf,task->r_size, DMA_READ); #else writebuf = scheduler->allocate(outListData->size); // 読むデータが一つもなければ無視 if (inListData->length == 0) return; // load Input Data readbuf = scheduler->allocate(inListData->size); scheduler->dma_loadList(inListData, readbuf, DMA_READ); #endif } void SchedTask::exec() { __debug("[SchedTask:%s]\n", __FUNCTION__); scheduler->dma_wait(DMA_READ); task_list[task->command].wait(scheduler,task->command); task_list[task->command].run(this, readbuf, writebuf); free(readbuf); // 書き込む領域がなければ無視 #ifdef SIMPLE_TASK if (task->w_size > 0) { scheduler->dma_store(writebuf, task->wbuf,task->w_size, DMA_WRITE); } #else if (outListData->length > 0) { scheduler->dma_storeList(outListData, writebuf, DMA_WRITE); } #endif } void SchedTask::write() { __debug("[SchedTask:%s]\n", __FUNCTION__); scheduler->dma_wait(DMA_WRITE); free(writebuf); scheduler->mail_write((memaddr)task->self); } SchedTaskBase* SchedTask::next(Scheduler *scheduler, SchedTaskBase *p) { __debug("[SchedTask:%s]\n", __FUNCTION__); if (cur_index < list->length) { // Task List が残っているので、次を準備 TaskPtr nextTask = &list->tasks[cur_index++]; SchedTaskBase *nextSched = createSchedTask(scheduler, nextTask); // この up cast は汚い... ((SchedTask*)nextSched)->init(list, nextTask, cur_index, scheduler); return nextSched; } else { memaddr nextList = (memaddr)list->next; if (nextList == 0) { // もう何もする必要がない return new SchedNop2Ready(scheduler); } else { // 新しいリストに取り掛かる return createSchedTaskList(nextList, scheduler, 0); } } } int SchedTask::get_cpuid() { return scheduler->id; } /** * task->add_inData で与えられた順番に対応する index (0〜n-1) で、 * buffer から対応するデータを返す。 */ void* SchedTask::get_input(void *buff, int index) { if (buff != NULL) { return (void*)((char*)buff + inListData->bound[index]); } else { return NULL; } } /** * 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; } /** * write buffer の領域を返す。 */ void* SchedTask::get_output(void *buff, int index) { if (buff != NULL) { return (void*)((char *)buff + outListData->bound[index]); } else { return NULL; } } /** * 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; } memaddr SchedTask::get_param(int index) { #ifdef SIMPLE_TASK return param[index]; #else return task->param[index]; #endif } 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) { scheduler->dma_load(buf, addr, size, mask); } void SchedTask::dma_store(void *buf,memaddr addr, uint32 size, uint32 mask) { scheduler->dma_store(buf, addr, size, mask); } void SchedTask::dma_wait(uint32 mask) { scheduler->dma_wait(mask); } void SchedTask::show_dma_wait() { scheduler->show_dma_wait(); } MemorySegment * SchedTask::get_segment(memaddr addr, MemList *m) { return scheduler->get_segment(addr,m); } 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 scheduler->create_task(cmd); } HTaskPtr SchedTask::create_task(int cmd, memaddr r, long rs, memaddr w, long ws) { return scheduler->create_task(cmd,r,rs,w,ws); } void SchedTask::set_task_depend(HTaskPtr master, HTaskPtr slave) { scheduler->set_task_depend(master, slave); } void SchedTask::spawn_task(HTaskPtr t) { scheduler->spawn_task(t); } void SchedTask::set_task_cpu(HTaskPtr t, CPU_TYPE cpu) { scheduler->set_task_cpu(t, cpu); } void* SchedTask::allocate(int size) { return scheduler->allocate(size) ; } void* SchedTask::allocate(int size,int align) { return scheduler->allocate(size,align) ; } Scheduler* SchedTask::get_scheduler() { return scheduler; } /* system call */ int SchedTask::fprintf(FILE * stream, const char * format, ...) { va_list ap; va_start(ap,format); int ret = vfprintf(stream,format, ap); va_end(ap); return ret; } int SchedTask::printf(const char * format, ...) { va_list ap; va_start(ap,format); int ret= vfprintf(stdout,format, ap); va_end(ap); return ret; } /* end */