view TaskManager/kernel/ppe/TaskManagerImpl.cc @ 58:7492eb28b577

*** empty log message ***
author gongo
date Sat, 16 Feb 2008 19:40:20 +0900
parents 90523ccc4dff
children 54355e641172
line wrap: on
line source

#include <stdio.h>
#include "TaskManagerImpl.h"
#include "types.h"
#include "error.h"

void
noaction(void)
{
}

TaskManagerImpl::TaskManagerImpl(int num) : machineNum(num) {}

TaskManagerImpl::~TaskManagerImpl(void)
{
    delete mailManager;
    delete scheduler;
    delete bufferManager;
}

void
TaskManagerImpl::init(void)
{
    mailManager = new MailManager();
    mailManager->init(20);

    scheduler = new MainScheduler();
    scheduler->init();
    scheduler->set_mailManager(mailManager);
}

HTaskPtr
TaskManagerImpl::create_task(int cmd, int size, DmaBuffer *in_addr, 
			     DmaBuffer *out_addr, void (*func)(void))
{
    HTaskPtr new_task;

    new_task = bufferManager->create_task(cmd, size, in_addr, out_addr);

    if (func == NULL) {
	new_task->post_func = noaction;
    } else {
	new_task->post_func = func;
    }

    return new_task;
}

/**
 * task の依存関係を設定
 * master task が終わってから、slave task を実行するように
 */
void
TaskManagerImpl::set_task_depend(HTaskPtr master, HTaskPtr slave)
{
    TaskQueuePtr m, s;

    m = bufferManager->create_taskQueue(master);
    s = bufferManager->create_taskQueue(slave);

    master->wait_me = TaskQueueInfo::append(master->wait_me, s);
    slave->wait_i = TaskQueueInfo::append(slave->wait_i, m);
}

void
TaskManagerImpl::spawn_task(HTaskPtr task)
{
    if (task->wait_i == NULL) {
	bufferManager->append_activeTask(task);
    } else {
	bufferManager->append_waitTask(task);	
    }
}

TaskListPtr
TaskManagerImpl::set_task(void)
{
    // ここ...直すかな
    TaskListPtr list;
    TaskQueuePtr queue;
    TaskQueuePtr d;
    HTaskPtr htask;
    TaskPtr task;

    queue = bufferManager->activeTaskQueue;
    if (queue == NULL) {
	return NULL;
    }

    bufferManager->clear_taskList();
 
    while (queue) {
	list = bufferManager->get_available_taskList();
	htask = queue->task;
	d = queue;
	queue = queue->next;

	task = &list->tasks[list->length++];
	task->command  = htask->command;

	// Fix me !!!!!
	// ださい
	// かっこいい class 判定がないものか。typeinfoだっけ?
	// in,out にあるのが DmaBuffer 以外だったら通信させない決まりにしたい
	if (htask->in_addr != 0) {
	    //task->in_addr = (uint32)(htask->in_addr->get_buffer());
	    htask->in_addr->get_buffer(&task->in_addr);
	} else {
	    task->in_addr = 0;
	}
	if (htask->in_addr != 0) {
	    //task->out_addr = (uint32)(htask->out_addr->get_buffer());
	    htask->out_addr->get_buffer(&task->out_addr);
	} else {
	    task->out_addr = 0;
	}
	task->in_size  = htask->in_size;
	task->self = htask;

	bufferManager->free_taskQueue(d);
    }

    bufferManager->activeTaskQueue = NULL;

    return list;
}

void
TaskManagerImpl::run(void)
{
    TaskListPtr list;
    MailQueuePtr list_mail; // task list
    MailQueuePtr sentinel;  // 番兵
    MailQueuePtr in_mail_list = NULL;
    MailQueuePtr out_mail_list = NULL;

    // 暫定
    list = set_task();

    list_mail =	mailManager->create((unsigned int)list);
    in_mail_list = MailManager::append_mailQueue(in_mail_list, list_mail);

    do {
	sentinel  = mailManager->create(MY_SPE_COMMAND_EXIT);
	in_mail_list = MailManager::append_mailQueue(in_mail_list, sentinel);

	scheduler->send_mailList(in_mail_list);
	scheduler->run();
	out_mail_list = scheduler->recv_mailList();

	// out_mail_list には、ppe scheduler からの mail がある
	in_mail_list = mail_check(out_mail_list);
    } while (in_mail_list);
}

/**
 * PPE Scheduler からのメールをチェックする
 */
MailQueuePtr
TaskManagerImpl::mail_check(MailQueuePtr mail_list)
{
    MailQueuePtr q = mail_list;
    MailQueuePtr d;
    MailQueuePtr ret = NULL;
    unsigned int data;
    TaskListPtr next_list;

    while (q) {
	data = q->data;

	if (data == MY_SPE_STATUS_READY) {
	    __debug_ppe("[FIFO] finish\n");
	    next_list = set_task();
	    if (next_list != NULL) {
		d = mailManager->create((unsigned int)next_list);
		ret = MailManager::append_mailQueue(ret, d);
	    }
	} else {
	    __debug_ppe("[PPE] recv from : 0x%x\n", data);
	    bufferManager->check_task_finish((HTaskPtr)data);
	}

	d = q;
	q = q->next;

	mailManager->free(d);
    }

    return ret;
}

/**
 * 型名指定するには template だけど...
 */
DmaBuffer*
TaskManagerImpl::allocate(int size)
{
    return new DmaBuffer(size);
}