view TaskManager/kernel/ppe/HTask.cc @ 2003:7dc90c83a787 draft

change set_last(t to next). run test at compilation time
author Shohei KOKUBO <e105744@ie.u-ryukyu.ac.jp>
date Mon, 05 May 2014 22:11:49 +0900
parents bbc8802bb0fd
children
line wrap: on
line source

#include "HTask.h"
#include "ListData.h"
#include "TaskManagerImpl.h"
#include "strings.h"
#include "rdtsc.h"
#include "SysFunc.h"

/*!
  manager->set_task_depend(task1, task2); // task2 は task1 の終了を待つ
 
  ってやるより
 
  task2->set_depend(task1);
 
  ってやったほうがわかりやすいよねー的な話し合いで
  下のようなAPIを作りました
*/

void
HTask::spawn(void)
{
    this->flag.dim_count = 1;    
    TaskList *tl = (TaskList*)rbuf;
    tl->set_last(last);
    mimpl->spawn_task(this);
}

void
HTask::iterate(long x) {
    this->flag.dim_count = 1;
    TaskList *tl = (TaskList*)rbuf;    
    for (;tl;tl=tl->next) {
        tl->set_last(last);
        tl->dim=1;
        tl->x=x;
        tl->y=1;
        tl->z=1;
    }
    mimpl->spawn_task(this);
}

void
HTask::iterate(long x, long y) {
    this->flag.dim_count = 1;
    TaskList *tl = (TaskList*)rbuf;
    for (;tl;tl=tl->next) {
        tl->set_last(last);
        tl->dim=1;
        tl->x=x;
        tl->y=y;
        tl->z=1;
    }
    mimpl->spawn_task(this);
}

void
HTask::iterate(long x, long y, long z) {
    this->flag.dim_count = 1;
    TaskList *tl = (TaskList*)rbuf;
    for (;tl;tl=tl->next) {
        tl->set_last(last);
        tl->dim=1;
        tl->x=x;
        tl->y=y;
        tl->z=z;
    }
    mimpl->spawn_task(this);
}

/*!
  @brief この Task が待ち合わせする Task を指定する
  @param[in] master この Task が終了待ち合わせをする相手の Task
  
  繰り返し使用する事で複数の Task を待ち合わせする事ができる。

  wait_for している Task の入力バッファにこの Task から書き込みできる機能があると良い
*/
void
HTask::wait_for(HTaskPtr master)
{
    mimpl->set_task_depend(master, this);
}

/**
 * タスクが実行する CPU を選択する
 *
 * 現在は CPU_PPE, CPU_SPE, SPE_ANY, SPE_0, SPE_1, ..., SPE_5
 * types.h に書いてます。
 * 
 * mimpl によって使えるCPUが異なるので、mimpl に任せる必要がある
 */
void
HTask::set_cpu(CPU_TYPE type)
{
    mimpl->set_task_cpu(this, type);
}

/*!
  @brief このTaskが終了した時に実行する関数
  @param arg1, arg2 の二つの引数を持つ (Task に合わせてある)
*/
void
HTask::set_post(PostFunction func,void *arg1, void *arg2)
{
    this->post_func = func;
    this->post_arg1 = arg1;
    this->post_arg2 = arg2;
}


/*!
  @brief まとまって実行されるTask である Task Array の作成
  @param id           Task ID
  @param num_task     実行する Task の数
  @param num_param    一つのTaskがset_paramする数
  @param num_inData   一つのTaskが読み込む Data の数、set_inData の数
  @param num_outData  一つのTaskが書き出す Data の数、set_outData の数
  @return  Task Array へのポインタ
*/ 

Task *
HTask::create_task_array(int id, int num_task, int num_param, int num_inData, int num_outData)
{
    r_size = 0;
    TaskListPtr tl =  mimpl->createTaskList();
    tl->self = this;
    this->flag.dim_count = 1;
    rbuf = (memaddr)tl;
    bzero(tl->tasks,sizeof(Task)*TASK_MAX_SIZE);
    Task *task = tl->tasks;
    task->init(id, num_param,num_inData,num_outData); // next_task_array が呼ばれれば、これは不要 
    last = task->next();                              //
    return task;  // first task
}


/*!
  @brief Task Array の次のTask
  @param t            今のTaskのポインタ
  0 の場合は最初のTask
  @return  次のTaskへのポインタ
*/
Task *
HTask::next_task_array(int id, Task *t)
{
    TaskPtr t1 = t;
    if (t==0) {
        TaskList *tl = (TaskList*)rbuf;
        t1 = tl->tasks;
    }
    return next_task_array(id,t,t1->param_count,t1->inData_count,t1->outData_count);
}

/*!
  @brief Task Array の次のTask
  @param t            今のTaskのポインタ
  0 の場合は最初のTask
  @return  次のTaskへのポインタ
*/
Task *
HTask::next_task_array(int id, Task *t, int param_count, int inData_count, int outData_count)
{
    TaskList *tl = (TaskList*)rbuf;
    if (t==0) {
        TaskPtr task = tl->tasks;
        task->init(id, param_count, inData_count, outData_count);
        last = task->next();
        return task;
    }
    // lastTask can't exceed TaskList
    int task_size = Task::calc_size(param_count, inData_count, outData_count);
    Task *next=get_nextTaskArea(t,tl,task_size);
    next->init(id, param_count, inData_count, outData_count);
    last = next->next();
    return next;
}

Task *
HTask::get_nextTaskArea(Task *t, TaskList *tl, int task_size) {
    Task *next = t->next();
    if (((char*)tl->last())-((char*)next) < task_size) {
        tl->set_last(next);
        TaskListPtr nextTaskList =  mimpl->createTaskList();
        nextTaskList->prev = tl;
        tl->next = nextTaskList;
        next = nextTaskList->tasks;
        nextTaskList->self = tl->self;
        tl->self = 0;
        rbuf = (memaddr)nextTaskList;
    } 

    return next;
}
/*!
  @brief Task Array の中のすべてのTaskが書き込まれたかどうかをチェックする
  TaskArray 自体の spawn() は別に必要
  @param last            今のTaskのポインタ (最後である必要がある)
*/
void
HTask::spawn_task_array(Task * last)
{
}

int
HTask::task_count()
{
    TaskList *tl = (TaskList*)rbuf;

    int count = 0;
    while(tl->prev) tl=tl->prev;
    while(tl) {
        Task *t = &tl->tasks[0];
        for( ; t < tl->last() ; t = t->next()) {
            count++;
        }

        TaskListPtr next = tl->next;
        tl = next;
    }
    return count;
}

void 
HTask::print() {
    ((TaskList *)rbuf)->print();
}


/* end */