view TaskManager/kernel/ppe/CpuThreads.cc @ 0:04e28d8d3c6f

first commit
author Daiki KINJYO <e085722@ie.u-ryukyu.ac.jp>
date Mon, 08 Nov 2010 01:23:25 +0900
parents
children
line wrap: on
line source

#include <stdlib.h>
#include "types.h"
#include "CpuThreads.h"
#include "MainScheduler.h"
#include "SysFunc.h"
#include "SchedNop.h"

SchedExternTask(ShowTime);
SchedExternTask(StartProfile);


CpuThreads::CpuThreads(int num, int start_id) : cpu_num(num), id_offset(start_id) {}

CpuThreads::~CpuThreads()
{
    memaddr mail = (memaddr)MY_SPE_COMMAND_EXIT;

    for (int i = 0; i < cpu_num; i++) {
        send_mail(i, 1, &mail);
    }

    for (int i = 0; i < cpu_num; i++) {
	pthread_join(threads[i], NULL);
    }

    delete [] threads;
    delete [] args;
}

void *
CpuThreads::cpu_thread_run(void *args)
{
    cpu_thread_arg_t *argt = (cpu_thread_arg_t *) args;
    Scheduler *c_scheduler = argt->scheduler;

    SchedRegister(ShowTime);
    SchedRegister(StartProfile);

    c_scheduler->init(argt->manager);
    c_scheduler->id = (int)argt->cpuid;

    c_scheduler->run(new SchedNop());
    c_scheduler->finish();

    return NULL;
}

void
CpuThreads::init()
{
    threads = new pthread_t[cpu_num];
    args    = new cpu_thread_arg_t[cpu_num];

    for (int i = 0; i < cpu_num; i++) {
	args[i].cpuid = i + id_offset;
	args[i].scheduler = new MainScheduler();
    }

    for (int i = 0; i < cpu_num; i++) {
	pthread_create(&threads[i], NULL,
		       &cpu_thread_run, (void*)&args[i]);
    }
}

/**
 * このCPU からのメールを受信する。
 *
 * @param [cpuid] SPE ID
 *
 * @return Received 32-bit mailbox messages
 *         if ([ret] < 0) no data read
 */
int
CpuThreads::get_mail(int cpuid, int count, memaddr *ret)
{   
    // need synchronization
    *ret = args[cpuid-id_offset].scheduler->mail_read_from_host();
    return 1;
}

int
CpuThreads::has_mail(int cpuid, int count, memaddr *ret)
{
    // need synchronization
    return  args[cpuid-id_offset].scheduler->has_mail_from_host();
}

/**
 * Inbound Mailbox
 * メール送信 Front End -> CPU
 *
 * なるべく NONBLOCKING なんだけど、
 * Inbound Mailbox キューに空きがないと送信できないので
 * 送信する数だけ空いているか確認してから送る。空いて無い場合は待つ。
 *
 * 結局待つんだよな。しかも ALL_BLOCKING って実は busy wait だったりするし
 *
 * @param [cpuid] SPE ID
 * @param [data] Send 32-bit mailbox messages
 * @param [num] The number of messages
 */
void
CpuThreads::send_mail(int cpuid, int num, memaddr *data)

{
    // need synchronization
    args[cpuid-id_offset].scheduler->mail_write_from_host(*data);
}


/* end */