view TaskManager/kernel/schedule/SchedTaskArray.cc @ 699:7e937a1cd121

....
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 13 Dec 2009 22:46:15 +0900
parents dcaa40ec963d
children d3afc8777daa
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;
}

/**
 */
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->inListData();
    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->outListData();
	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->get_param(index);
}


/* end */