view TaskManager/kernel/schedule/SchedTaskArray.cc @ 696:b5c3ef336878

on going...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 13 Dec 2009 10:49:07 +0900
parents cbcf0182635e
children 257ad1a518e3
line wrap: on
line source

#include "SchedTaskArray.h"
#include "SchedTask.h"

extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT];

SchedTaskArray::SchedTaskArray(SchedTaskBase *savedTask_, Task *curTask_, Task *_array)
{
    savedTask = savedTask_;
    task = curTask_;
    array = _array;
}

/**
 * dma_store の wait を行う
 */
SchedTaskArray::~SchedTaskArray()
{
    inListData.bound = 0;
    inListData.size = 0;
    inListData.length = 0;
    inListData.element = 0;
    outListData.bound = 0;
    outListData.size = 0;
    outListData.length = 0;
    outListData.element = 0;
}

static void
bound(ListData *list, void *data)
{
    ListEelement elm = list->element;
    void *bound = list->bound;
    for(int i=0;i<list->length;i++) {
	// we assume all data is properly aligned
	bound[i] = data;
	data = (void*)(((char*)data)+elm[i].size);
    }
}

void
SchedTaskArray::read()
{
    __debug("[SchedTaskArrayArray:%s]\n", __FUNCTION__);

    // object creation をSchedTaskArray生成時にやらないので、
    // exec の直前のread で十分に間に合う
    loadSchedTask(scheduler, task);

    // 読むデータが一つもなければ無視
    if (task->inData_count == 0) return;

    inListData.length = task->inData_count;
    inListData.size = task->inData_total_size();
    inListData.element = task->inData();
    inListData.bound = scheduler->allocate(inListData.count*sizeof(void*));

    // load Input Data
    readbuf = scheduler->allocate(inListData.size);
    scheduler->dma_loadList(&inListData, readbuf, DMA_READ);
    bound(&inListData, readbuf);

}


void
SchedTaskArray::exec()
{
    __debug("[SchedTaskArrayArray:%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);
    // 書き込む領域がなければ無視
    if (task->outData_count > 0) {
	outListData.length = task->outData_count;
	outListData.size = task->outData_total_size();
	outListData.element = task->outData();

	writebuf = scheduler->allocate(outListData.size);
        scheduler->dma_storeList(&outListData, writebuf, DMA_WRITE);
	bound(&outListData, writebuf);
    }
}

void
SchedTaskArray::write()
{
    __debug("[SchedTaskArrayArray:%s]\n", __FUNCTION__);

    scheduler->dma_wait(DMA_WRITE);
    free(writebuf);

    // このTaskArrayは終り。終了を知らせる。
    if (task->next() >= last()) {
	scheduler->mail_write((memaddr)savedTask->task->self);
	free(array);
    }

}

Task *SchedTaskArray::last()
{
   return  (Task*)(((char*)array)+ savedTask->read_size());
}

SchedTaskBase*
SchedTaskArray::next(Scheduler *scheduler, SchedTaskArrayBase *p)
{
    __debug("[SchedTaskArray:%s]\n", __FUNCTION__);


    if (task->next() < last()) {
	// Task List が残っているので、次を準備
	return (SchedTaskBase*)new SchedTaskArray(savedTask, next, array);
    } else {
	// このTaskArrayは終り。save していた Task の次を返す。
	// savedTask の read/exec は実行されない (command = TaskArray)
	return savedTask->next();
    }
}



/* end */