view TaskManager/kernel/schedule/SchedTaskArray.cc @ 697:257ad1a518e3

TaskArray on going...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 13 Dec 2009 18:45:09 +0900
parents b5c3ef336878
children dcaa40ec963d
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;

    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);

    // 読むデータが一つもなければ無視
    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);
    scheduler->dma_loadList(&inListData, readbuf, DMA_READ);
    bound(&inListData);

}


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);
    // 書き込む領域がなければ無視

    // User 側で作る方法が必要...

    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));

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

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

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

    // この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(savedTask, next, array);
    } else {
	// このTaskArrayは終り。save していた Task の次を返す。
	// savedTask の read/exec は実行されない (command = TaskArray)
	return savedTask->next(scheduler, savedTask);
    }
}



/* end */