view TaskManager/kernel/schedule/SchedTask.cc @ 180:e3b7776b1420 draft

いろいろ fix 。詳しくは TaskManager/Changelog、test_render/Changelog を
author gongo@localhost.localdomain
date Mon, 22 Dec 2008 16:09:57 +0900
parents 028ffc9c0375
children 8e9ada0c1ed0
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"

extern Scheduler::TaskObject task_list[MAX_TASK_OBJECT];

SchedTask*
CreateSchedTask(TaskListPtr taskList, Scheduler *sched)
{
    TaskPtr task = &taskList->tasks[sched->curIndex_taskList++];
    
    return task_list[task->command](taskList, task, sched->get_curReadBuf(),
				    sched->get_curWriteBuf(), sched);
}

SchedTask::SchedTask(TaskListPtr _list, TaskPtr _task, ListDataPtr rbuf,
		     ListDataPtr wbuf, Scheduler* sc)
{
    __list        = _list;
    __task        = _task;
    __inListData  = rbuf;
    __outListData = wbuf;
    __readbuf     = NULL;
    __writebuf    = NULL;
    __scheduler   = sc;
    __taskGroup   = NULL;
    __renew_flag  = 0;

    smanager = new STaskManager(this);
}

SchedTask::~SchedTask(void)
{
    if (__flag_renewTask) {
	/**
	 * __inListData  __outListData ϥȤΤΤʤΤ
	 * ä¨ free 롣
	 */
	free(__inListData);
        free(__outListData);
 
	/**
	 * __list != NULL ξ硢
	 *  Task  __list κǸ Task ˤʤΤ (SchedTask::next )
	 * Υߥ󥰤 __list 
	 *   (free Ϥ륢ɥ쥹ΤȤʤ)
	 * ʳ Task Ǥʤ
	 *  __list == NULL ʤΤǡfree ϤƤ̵
	 */
	free(__list);
    }

    delete smanager;
}

void
SchedTask::__init__(void)
{
    /**
     * task->inData  task->outData 
     * PPE ΤΤSPE ΤΤä
     * ɥ쥹ȽǤгڤˤʤȻפ
     */
    if (__flag_renewTask == 0) {
	__scheduler->dma_load(__inListData, (uint32)__task->inData,
			      sizeof(ListData), DMA_READ_IN_LIST);
	__scheduler->dma_load(__outListData, (uint32)__task->outData,
			      sizeof(ListData), DMA_READ_OUT_LIST);
	
	__taskGroup = new TaskGroup;
	__taskGroup->command = __task->self;

	ex_read  = &SchedTask::ex_read_normal;
	ex_exec  = &SchedTask::ex_exec_normal;
	ex_write = &SchedTask::ex_write_normal;
    } else {
	__inListData = __task->inData;
	__outListData = __task->outData;
	__taskGroup = (TaskGroupPtr)__task->self;

	ex_read  = &SchedTask::ex_read_renew;
	ex_exec  = &SchedTask::ex_exec_renew;
	ex_write = &SchedTask::ex_write_renew;
    }
}


/**
 * [Todo]
 *   ǡɤ߹߾ readbuf ǤϤʤ
 *   桼ȤǷ褦ˤʤȤ⤷ʤ
 *
 *   # TaskManager ˾äȤʤ
 *   # 桼 SPE ˻³뤳ȤǤ뤿ᡣ
 *   # ϥ桼Ǥ櫓
 */
void
SchedTask::read(void)
{    
    __debug("[SchedTask:%s]\n", __FUNCTION__);

    // wait for load inListData 
    __scheduler->dma_wait(DMA_READ_IN_LIST);

    // ɤǡĤʤ̵
    if (__inListData->length < 1 || __inListData->size == 0) return;

    // load Input Data
    __readbuf = __scheduler->allocate(__inListData->size);
    __scheduler->dma_loadList(__inListData, __readbuf, DMA_READ);

    (this->*ex_read)();
}

void
SchedTask::exec(void)
{
    __debug("[SchedTask:%s]\n", __FUNCTION__);

    // wait for load outListData 
    __scheduler->dma_wait(DMA_READ_OUT_LIST);
    __writebuf = __scheduler->allocate(__outListData->size);

    __debug("  task->command  = %d\n", __task->command);
    __debug("  task->in_size  = %d\n", __task->in_size);
    __debug("  task->in_addr  = 0x%x\n", __task->in_addr);
    __debug("  task->out_addr = 0x%x\n", __task->out_addr);
    __debug("  list->next     = 0x%x\n", (unsigned int)__list->next);
    __debug("  list->length   = 0x%x\n", (unsigned int)__list->length);

    __scheduler->dma_wait(DMA_READ);

    run(__readbuf, __writebuf);

    free(__readbuf);

    if (__taskGroup->status() != 0) {
	__task->self = __taskGroup->command;
	delete __taskGroup;
	__taskGroup = NULL;
    }

    // 񤭹ΰ褬פʤ̵
    if (__outListData->size > 0 || __outListData->length > 0) {
	__scheduler->dma_storeList(__outListData, __writebuf, DMA_WRITE);
	// SchedTask::write(void) Ǥ wait ݤƤɡ
        // ºݤˤϤ wait ʤȤȽ񤭹ޤƤʤ
	// wait ϤƤϤʤʡ
	__scheduler->dma_wait(DMA_WRITE);
    }

    (this->*ex_exec)();
}

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

    //__scheduler->dma_wait(DMA_WRITE);
    free(__writebuf);

    /**
     * ΥSPE줿
     * ΥνλԤɬפϤʤȤ꤬Ƥ뤿ᡢ
     *   (wait_task() ƤФƤʤ)
     * ǽλ롣ex_write ϼ¹Ԥʤ
     */
    if (__task->self == MY_SPE_NOP) return;

    (this->*ex_write)();
}

/**
 * PPE 줿 ex_read()
 */
void
SchedTask::ex_read_normal(void)
{
}

/**
 * SPE 줿 ex_read()
 */
void
SchedTask::ex_read_renew(void)
{
}

/**
 * PPE 줿 ex_exec()
 */
void
SchedTask::ex_exec_normal(void)
{
}

/**
 * SPE 줿 ex_exec()
 */
void
SchedTask::ex_exec_renew(void)
{
}



/**
 * PPE 줿 ex_write()
 * 
 * Υǿ˥졢
 * ĤΥνλԤɬפ硢
 * PPE ˽λȤΤ餻ʤ(command ʤ)
 */
void
SchedTask::ex_write_normal(void)
{
    /**
     * Υǿ˥ʤä
     * or 줿ΥνλԤɬפ̵
     */
    if (__renew_flag == 0) {
	__scheduler->mail_write(__task->self);
    }
}

/**
 * SPE 줿 ex_write()
 *
 *  A <- ƥ
 *  | \
 *  B   C <- SPE 줿
 *
 * A  SPE  B, C Ȥ롣
 * B  C λ顢A  PPE Ϥäޥɤ
 * ҥ˰ѤƤΤǡǸ˼¹Ԥ줿ҥ
 * PPE  mail 롣
 */
void
SchedTask::ex_write_renew(void)
{
    uint32 cmd;
	
    __taskGroup->remove(__task);
    cmd = __taskGroup->status();
    

    // Ǻ줿ƤΥλ
    if (cmd != 0) {
	delete __taskGroup;
	__scheduler->mail_write(cmd);
    }
}
    
SchedTaskBase*
SchedTask::next(Scheduler *m, SchedTaskBase *p)
{
    __debug("[SchedTask:%s]\n", __FUNCTION__);

    delete p;

    if (__scheduler->curIndex_taskList < __list->length) {
	SchedTask* schedTask = CreateSchedTask(__list, __scheduler);
	schedTask->__flag_renewTask = this->__flag_renewTask;
	schedTask->__init__();

	/**
	 * ͳ SchedTask:~SchedTask() 
	 */
	__list = NULL;

	return schedTask;
    } else {
	uint32 nextList = (uint32)__list->next;

	if (nextList == 0) {
	    return new SchedNop2Ready(__scheduler);
	} else {
	    return new SchedTaskList(nextList, __scheduler);
	}
    }
}

/**
 * task->add_input Ϳ줿֤б index (0n-1) ǡ
 * buffer бǡ֤
 */
void*
SchedTask::get_input(void *buff, int index)
{
    if (buff != NULL) {
	return (void*)((int)buff + __inListData->bound[index]);
    } else {
	return NULL;
    }
}

/**
 * write buffer ΰ֤
 */
void*
SchedTask::get_output(void *buff, int index)
{
    if (buff != NULL) {
	return (void*)((int)buff + __outListData->bound[index]);
    } else {
	return NULL;
    }
}

int
SchedTask::get_param(int index)
{
    return __task->param[index];
}

TaskPtr
SchedTask::create_task(int cmd)
{
    TaskListPtr taskList = __scheduler->get_renewListBuf();
    TaskPtr p = &taskList->tasks[taskList->length++];
    p->command = cmd;

    p->inData = (ListData*)__scheduler->allocate(sizeof(ListData));
    p->outData = (ListData*)__scheduler->allocate(sizeof(ListData));

    p->inData->clear();
    p->outData->clear();

    p->self = MY_SPE_NOP;
    p->param_size = 0;

    return p;
}

/**
 * λƤ顢ᥤ󥹥塼(PPE) 
 * λݤΤ餻롣
 *
 * @param[in] waitTask 
 */
void
SchedTask::wait_task(TaskPtr waitTask)
{
    waitTask->self = (uint32)__taskGroup;

    __scheduler->add_groupTask(__taskGroup, waitTask);

    __renew_flag++;
}

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_free(int id) {
    __scheduler->global_free(id);
}

void
SchedTask::mainMem_alloc(int id, int size) {
    __scheduler->mainMem_alloc(id, size);
}

void
SchedTask::mainMem_wait(void) {
    __scheduler->mainMem_wait();
}

void*
SchedTask::mainMem_get(int id) {
    return __scheduler->mainMem_get(id);
}

void*
SchedTask::allocate(int size) {
    return __scheduler->allocate(size);
}

void
SchedTask::dma_load(void *buf, uint32 addr, uint32 size, uint32 mask) {
    __scheduler->dma_load(buf, addr, size, mask);
}

void
SchedTask::dma_store(void *buf,uint32 addr, uint32 size, uint32 mask) {
    __scheduler->dma_store(buf, addr, size, mask);
}

void
SchedTask::dma_wait(uint32 mask) {
    __scheduler->dma_wait(mask);
}