view TaskManager/kernel/schedule/SchedTask.cc @ 1007:18a548c337cb

add mail_queue
author yutaka@localhost.localdomain
date Thu, 28 Oct 2010 08:39:19 +0900
parents d093d601fc14
children c67379f9d411
line wrap: on
line source


#include <stdlib.h>
#include <string.h>
#include "SchedTask.h"
#include "SysFunc.h"
#include "SchedTaskList.h"
#include "SchedTaskArrayLoad.h"
#include "SchedNop2Ready.h"
#include "DmaManager.h"
#include "error.h"
#include "TaskManager.h"
#include <stdarg.h>

#include "SchedTaskArray.h"
#define Task SimpleTask
#define TaskPtr SimpleTaskPtr

extern TaskObject task_list[MAX_TASK_OBJECT];



SchedTask::SchedTask()
{
    list        = NULL;
    task        = NULL;
    readbuf     = NULL;
    writebuf    = NULL;
    scheduler   = NULL;
    cur_index   = 0;
    this->stdout_ = stdout;
    this->stderr_ = stderr;
    this->stdin_ = stdin;


}

SchedTask::~SchedTask()
{
}

void
SchedTask::init(TaskListPtr _list, TaskPtr _task, int index, Scheduler* sc, int tag)
{
    list        = _list;
    task        = _task;
    scheduler   = sc;
    cur_index   = index;
    this->tag = tag;

    // scheduler->mainMem_wait();   // これはなんで?
    manager = sc->manager;

#ifdef TASK_LIST_MAIL
    if (list)
       waiter = (memaddr) list->waiter;
#else
    if (task)
       waiter = (memaddr) task->self;
#endif

}


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

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

    // 読むデータが一つもなければ無視
    if (task->r_size == 0) return;
    // load Input Data
    readbuf = manager->allocate(task->r_size);
    scheduler->dma_load(readbuf, task->rbuf,task->r_size, DMA_READ + this->tag);


}


void
SchedTask::exec()
{
    task_list[task->command].wait(scheduler,task->command);
    TaskObjectRun run = task_list[task->command].run;
    if (task->w_size > 0) {
	writebuf = manager->allocate(task->w_size);
    }
    scheduler->dma_wait(DMA_READ + this->tag);
    run(this, readbuf, writebuf);
    free(readbuf);

    // 書き込む領域がなければ無視

    if (task->w_size > 0) {
	scheduler->dma_store(writebuf, task->wbuf,task->w_size, DMA_WRITE);
    }
}

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

    scheduler->dma_wait(DMA_WRITE);
    free(writebuf);
#ifdef TASK_LIST_MAIL
    if (!(cur_index < list->length) )
	scheduler->mail_write(waiter);

#elseif MAIL_QUEUE

    scheduler->mail_write_queue(waiter);

#else
    scheduler->mail_write(waiter);
#endif
}

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];
        SchedTask *nextSched = new SchedTask();
	nextSched->init(list, nextTask, cur_index+1, scheduler, this->tag^1);
	// この時点で、TaskList は down load が済んでないことがある
        // 最初のTaskの種類に関しては、別な情報で渡す方が良い
	// あるいはTaskListの最初には、TaskArray1/TaskArray を置かない?

	if (nextTask->command==TaskArray1) {
	    // compatibility
	    return new SchedTaskArray(scheduler, nextSched);
	}
	if (nextTask->command==TaskArray) {
	    // Start Task Array
	    int dma_tag_switch = 0;
	    return new SchedTaskArrayLoad(scheduler, nextSched, dma_tag_switch);
	}
	return nextSched;
    } else {
        memaddr nextList = (memaddr)list->next;
        if (nextList == 0) {
	    // もう何もする必要がない
            return new SchedNop2Ready(scheduler);
        } else {
	    // 新しいリストに取り掛かる
  	    int dma_tag_switch = 0;
	    return new SchedTaskList(nextList, scheduler, dma_tag_switch);
        }
    }
}


int
SchedTask::get_cpuid()
{
    return scheduler->id;
}

void SchedTask::free_(void *p) {
    scheduler->free_(p);
}

/**
 *    SimpleTask has one parameter , one input, one output
 */

void* SchedTask::get_input(void *buff, int index) { return readbuf; }
memaddr SchedTask::get_inputAddr(int index) { return task->rbuf; }
int SchedTask::get_inputSize(int index) {return task->r_size; }
void* SchedTask::get_output(void *buff, int index) {return writebuf; }
memaddr SchedTask::get_outputAddr(int index) { return task->wbuf; }
int SchedTask::get_outputSize(int index) { return task->w_size; }
memaddr SchedTask::get_param(int index) { return task->param; }


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

long
SchedTask::get_random() {
    return scheduler->get_random();
}

void
SchedTask::start_profile() {
    scheduler->start_profile();
}

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

uint32 SchedTask::get_tag() {
    return scheduler->get_tag();
}


HTaskPtr
SchedTask::create_task(int cmd)
{
    return manager->create_task(cmd, __builtin_return_address(0));
}

HTaskPtr 
SchedTask::create_task(int cmd, memaddr r, long rs, memaddr w, long ws)
{
    return manager->create_task(cmd,r,rs,w,ws, __builtin_return_address(0));
}

HTaskPtr
SchedTask::create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData)
{
  return manager->create_task_array(id, num_task, num_param, num_inData, num_outData, __builtin_return_address(0));
}

void SchedTask::free_htask(HTask *p) {
#if  !defined(__SPU__)
    manager->free_htask(p);
#endif
}


void SchedTask::set_task_depend(HTaskPtr master, HTaskPtr slave)
{
    manager->set_task_depend(master, slave);
}

void SchedTask::spawn_task(HTaskPtr t)
{
    manager->spawn_task(t);
}

void SchedTask::set_task_cpu(HTaskPtr t, CPU_TYPE cpu)
{
    manager->set_task_cpu(t, cpu);
}

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

void* SchedTask::allocate(int size,int align) 
{
    return manager->allocate(size,align) ;
}

void SchedTask::polling()
{
    manager->polling();
}

Scheduler* SchedTask::get_scheduler() 
{
    return scheduler;
}

/* system call */

int 
SchedTask::printf(const char * format, ...)
{
    va_list ap;
    va_start(ap,format);
    int ret= scheduler->vprintf0(format, ap);
    va_end(ap);
    return ret;
}


/* end */