view include/TaskManager/SchedTaskImpl.h @ 305:dc9d06c60899

private
author kono@localhost.localdomain
date Mon, 08 Jun 2009 18:36:06 +0900
parents a02e863dc69f
children
line wrap: on
line source

#ifndef INCLUDED_SCHED_TASK_IMPL
#define INCLUDED_SCHED_TASK_IMPL

#include "base.h"
#include "Scheduler.h"
#include "SchedTaskBase.h"
#include "ListData.h"
#include "TaskGroup.h"

class SchedTaskImpl : public SchedTaskBase {
public:
    /* constructor */
    SchedTaskImpl();
    virtual ~SchedTaskImpl();

    BASE_NEW_DELETE(SchedTask);

private:
    /* variables */

    // Task を実行するスケジューラ自身
    Scheduler *__scheduler;

    // 現在スケジューラが実行している TaskList と、このタスクに対応する Task
    TaskListPtr __list;
    TaskPtr __task;

    // read/write 用の ListData
    ListDataPtr __inListData;
    ListDataPtr __outListData;

    /**
     * read データ、write 用のバッファ
     * readbuf には タスク登録時に設定した入力データが入っている。
     * writebuf にデータを描き込んでおくと、
     * タスク登録時に設定した出力先に書き込む
     */
    void *__readbuf;
    void *__writebuf;

    // Task の、Tasklist での位置。(task = &list[cur_index-1])
    int __cur_index;

    // タスク内で生成されたタスクのグループ
    TaskGroup *__taskGroup;

    // このタスク内で生成されたタスクの数
    int __renew_flag;

    // このタスクが SPE 内で生成されたタスクか否か 1: Yes, 0: No
    int __flag_renewTask;

    // タスクがメインメモリ側で生成されたものか、
    // SPE で生成されたものかによって、データの扱いが変わってくる。
    // そのために if (__flag_renewTask) を連発するのはよくないので
    // 関数ポインタで持っておく
    void (SchedTaskImpl::*ex_init)();
    void (SchedTaskImpl::*ex_read)();
    void (SchedTaskImpl::*ex_exec)();
    void (SchedTaskImpl::*ex_write)();
    SchedTaskBase* (SchedTaskImpl::*ex_next)();
   
    /* functions */

    // override
    void read();
    void exec();
    void write();
    SchedTaskBase* next(Scheduler *, SchedTaskBase *);

    // ここをユーザが継承して
    // それぞれのタスクに対応した処理を記述する
    virtual int run(void* r, void *w) { return 0; }

    int (SchedTaskImpl::*run_func)(void* r, void *w);

    //---  System API ---
    SchedTaskImpl* get_nextTask(TaskListPtr list);
    
    /**
     * PPE で生成されたタスクに対する
     * __init__, read,exec,write,next の付属(?)処理
     */
    void ex_init_normal();
    void ex_read_normal();
    void ex_exec_normal();
    void ex_write_normal();
    SchedTaskBase* ex_next_normal();

    /**
     * SPE で生成されたタスクに対する
     * __inti__, ead,exec,write,next の付属(?)処理
     */
    void ex_init_renew();
    void ex_read_renew();
    void ex_exec_renew();
    void ex_write_renew();
    SchedTaskBase* ex_next_renew();

public:
    /* functions */

    void __setRenew();
    void __init__(TaskListPtr _list, TaskPtr _task, int index,
		  ListDataPtr rbuf, ListDataPtr wbuf, Scheduler* sc);

    //---  User API ---
    int get_cpuid();

    void* get_input(void *buff, int index);
    void* get_output(void *buff, int index);
    uint32 get_inputAddr(int index);
    uint32 get_outputAddr(int index);
    int get_inputSize(int index);
    int get_outputSize(int index);
    int get_param(int index);

    TaskPtr create_task(int cmd);
    void wait_task(TaskPtr waitTask);

    void* global_alloc(int id, int size);
    void* global_get(int id);
    void global_free(int id);

    void mainMem_alloc(int id, int size);
    void mainMem_wait();
    void* mainMem_get(int id);

    void *allocate(int size);

    void dma_load(void *buf, uint32 addr, uint32 size, uint32 mask);
    void dma_store(void *buf,uint32 addr, uint32 size, uint32 mask);
    void dma_wait(uint32 mask);

private:
    class STaskManager {
    public:
	STaskManager(SchedTaskImpl *_t) {
	    outer = _t;
	}

	BASE_NEW_DELETE(STaskManager);

	SchedTaskImpl *outer;

	int get_cpuid() {
	    return outer->get_cpuid();
	}
	
	void* get_input(int index) {
	    return outer->get_input(outer->__readbuf, index);
	}

	void* get_output(int index) {
	    return outer->get_output(outer->__writebuf, index);
	}

	uint32 get_inputAddr(int index) {
	    return outer->get_inputAddr(index);
	}

	uint32 get_outputAddr(int index) {
	    return outer->get_outputAddr(index);
	}

	uint32 get_inputSize(int index) {
	    return outer->get_inputSize(index);
	}

	uint32 get_outputSize(int index) {
	    return outer->get_outputSize(index);
	}

	int get_param(int index) {
	    return outer->get_param(index);
	}

	TaskPtr create_task(int cmd) {
	    return outer->create_task(cmd);
	}

	void wait_task(TaskPtr waitTask) {
	    outer->wait_task(waitTask);
	}
	
	void* global_alloc(int id, int size) {
	    return outer->global_alloc(id, size);
	}

	void* global_get(int id) {
	    return outer->global_get(id);
	}

	void global_free(int id) {
	    outer->global_free(id);
	}

	void mainMem_alloc(int id, int size) {
	    outer->mainMem_alloc(id, size);
	}

	void mainMem_wait() {
	    outer->mainMem_wait();
	}

	void* mainMem_get(int id) {
	    return outer->mainMem_get(id);
	}

	void *allocate(int size) {
	    return outer->allocate(size);
	}

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

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

	void dma_wait(uint32 mask) {
	    outer->dma_wait(mask);
	}
    };

    STaskManager *smanager;
};

const int SCHED_TASK_NORMAL = 0;
const int SCHED_TASK_RENEW  = 1;

extern SchedTask* createSchedTaskImpl(TaskPtr);

#endif