view TaskManager/kernel/ppe/CpuThreads.cc @ 1179:5393bebe0956 draft

CpuThreads update
author Daichi TOMA
date Tue, 21 Jun 2011 19:50:53 +0900
parents 730f5e5c8351
children fa380908f801
line wrap: on
line source

#include <stdlib.h>
#include "types.h"
#include "CpuThreads.h"
#include "MainScheduler.h"
#include "SysFunc.h"
#include "SchedNop.h"
#include "SpeTaskManagerImpl.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);
		sem_destroy(&sem[i]);
	}

    for (int i = 0; i < cpu_num; i++) {
    	delete args[i].scheduler;
    }

    delete [] threads;
    delete [] args;
	delete [] sem;
}

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

    TaskManagerImpl *manager = new SpeTaskManagerImpl();
    c_scheduler->init(manager);
    c_scheduler->id = (int)argt->cpuid;

    manager->set_scheduler(c_scheduler);

    //SchedRegister(ShowTime);
    //SchedRegister(StartProfile);

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

    return NULL;
}

void
//CpuThreads::init()
CpuThreads::init()
{
    threads = new pthread_t[cpu_num];
    args    = new cpu_thread_arg_t[cpu_num];
	sem		= new sem_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]);
	sem_init(&sem[i], 0, 1);
    }
}

/**
 * この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
	sem_wait(&sem[cpuid]);
    *ret = args[cpuid-id_offset].scheduler->mail_read_from_host();
	sem_post(&sem[cpuid]);
    return 1;
}

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

/**
 * 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
	sem_wait(&sem[cpuid]);
    args[cpuid-id_offset].scheduler->mail_write_from_host(*data);
	sem_post(&sem[cpuid]);
}

void
CpuThreads::add_output_tasklist(int command, memaddr buff, int alloc_size)
{
    /*
     * output TaskList が無ければ新しく作る
     * あれば TaskList に allocate した Task を追加
     * command に対応した Task の初期化を実行する
     * SPE に data が書き出し終わった後に PPE 側で初期化
     */

}

/* end */