view TaskManager/kernel/ppe/TaskManagerImpl.cc @ 48:70a0ac46133e

*** empty log message ***
author gongo
date Fri, 15 Feb 2008 16:09:42 +0900
parents f154d9d07a42
children 7927e00fb8e2
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) {}

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

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

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

    new_task = taskInfo->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 = taskInfo->create_taskQueue(master);
    s = taskInfo->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) {
	taskInfo->append_activeTask(task);
    } else {
	taskInfo->append_waitTask(task);	
    }
}

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

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

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

	task = &list->tasks[list->length++];
	task->command  = htask->command;
	task->in_addr  = htask->in_addr;
	task->out_addr = htask->out_addr;
	task->in_size  = htask->in_size;
	task->self = htask;

	taskInfo->free_taskQueue(d);
    }

    taskInfo->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_mail((unsigned int)list);
    in_mail_list = append_mailQueue(in_mail_list, list_mail);

    do {
	sentinel  = mailManager->create_mail(MY_SPE_COMMAND_EXIT);
	in_mail_list = 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_mail((unsigned int)next_list);
		ret = append_mailQueue(ret, d);
	    }
	} else {
	    __debug_ppe("[PPE] recv from : 0x%x\n", data);
	    taskInfo->check_task_finish((HTaskPtr)data);
	}

	d = q;
	q = q->next;

	mailManager->free_mailQueue(d);
    }

    return ret;
}