view TaskManager/Cell/SpeThreads.cc @ 161:1f4c3f3238e6 fullHD_omedetou

texture の座標がマイナスになったあと、それを 0 にし忘れてた
author gongo@localhost.localdomain
date Mon, 08 Dec 2008 16:37:02 +0900
parents 5c194c71eca8
children 72dcf908ec52
line wrap: on
line source

#include <stdlib.h>
#include "types.h"
#include "SpeThreads.h"

SpeThreads::SpeThreads(int num) : spe_num(num) {}

SpeThreads::~SpeThreads(void)
{
    unsigned int mail = MY_SPE_COMMAND_EXIT;
    int ret;

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

    for (int i = 0; i < spe_num; i++) {
	pthread_join(threads[i], NULL);
	ret = spe_context_destroy(spe_ctx[i]);
	if (ret) {
	    perror("[~SpeThreads] spe_context_destroy");
	}
    }

    spe_image_close(spe_handle);

    delete [] spe_ctx;
    delete [] threads;
    delete [] args;
}

void*
SpeThreads::spe_thread_run(void *arg)
{
    unsigned int entry = SPE_DEFAULT_ENTRY;
    //spe_context_ptr_t ctx = (spe_context_ptr_t)arg;
    thread_arg_t *arg_t = (thread_arg_t *)arg;

    spe_stop_info_t stop_info;
    unsigned long long status;
    
    spe_context_run(arg_t->ctx, &entry, 0, (void*)arg_t->speid, NULL, &stop_info);
    
    status = ((stop_info.result.spe_exit_code & 0xff) << 8)
	| (stop_info.result.spe_signal_code & 0xff);

    printf("[SPE %d] ", arg_t->speid);
    switch(stop_info.stop_reason) {
    case SPE_EXIT:
	printf("SPE_EXIT stop_info.result.stop_exit_code=0x%x\n", stop_info.result.spe_exit_code);
	break;
    case SPE_STOP_AND_SIGNAL:
	printf("SPE_STOP_AND_SIGNAL stop_info.result.stop_signal_code=%d\n", stop_info.result.spe_signal_code);
	break;
    case SPE_RUNTIME_ERROR:
	printf("SPE_RUNTIME_ERROR stop_info.result.spe_runtime_error=%d\n", stop_info.result.spe_runtime_error);
	break;
    case SPE_RUNTIME_EXCEPTION:
	printf("SPE_RUNTIME_EXCEPTION stop_info.result.spe_runtime_exception=%d\n", stop_info.result.spe_runtime_exception);
	break;
    }

    pthread_exit(NULL);
}

void*
SpeThreads::frontend_thread_run(void *arg)
{
    pthread_t thread;
    thread_arg_t *arg_t = (thread_arg_t *)arg;

    pthread_create(&thread, NULL, &spe_thread_run, (void*)arg_t->ctx);

    // mail read  blocking Ǥ
    // ǸƤᤤ

    pthread_exit(NULL);
}

void
SpeThreads::init(void)
{
    spe_handle = spe_image_open(SPE_ELF);

    if (spe_handle == NULL) {
	perror("spe_image_open");
	exit(EXIT_FAILURE);
    }

    spe_ctx = new spe_context_ptr_t[spe_num];
    threads = new pthread_t[spe_num];
    args    = new thread_arg_t[spe_num];

    for (int i = 0; i < spe_num; i++) {
	args[i].speid = i;
	spe_ctx[i] = spe_context_create(0, NULL);
	spe_program_load(spe_ctx[i], spe_handle);
	args[i].ctx = spe_ctx[i];
    }

    for (int i = 0; i < spe_num; i++) {
#if 0
	pthread_create(&threads[i], NULL,
		       &frontend_thread_run, (void*)&args[i]);
#else
	pthread_create(&threads[i], NULL,
		       //&spe_thread_run, (void*)spe_ctx[i]);
		       &spe_thread_run, (void*)&args[i]);
#endif
    }
}

/**
 * SPE Υ᡼롣
 *
 * @param [speid] SPE ID
 *
 * @return Received 32-bit mailbox messages
 *         if ([ret] < 0) no data read
 */
int
SpeThreads::get_mail(int speid)
{
    unsigned int ret = (unsigned int)(-1);

    spe_out_mbox_read(spe_ctx[speid], &ret, 1);
    return ret;
}

/**
 * Inbound Mailbox
 * ᡼ PPE -> SPE
 *
 * ʤ٤ NONBLOCKING ʤɡ
 * Inbound Mailbox 塼˶ʤǤʤΤ
 * Ƥ뤫ǧƤ롣̵Ԥġ
 *
 * ԤĤʡ ALL_BLOCKING äƼ¤ busy wait äꤹ뤷
 *
 * @param [speid] SPE ID
 * @param [data] Send 32-bit mailbox messages
 * @param [num] The number of messages
 */
void
SpeThreads::send_mail(int speid, unsigned int *data, int num)
{
    while (spe_in_mbox_status(spe_ctx[speid]) < num);
    spe_in_mbox_write(spe_ctx[speid], data, num, SPE_MBOX_ANY_NONBLOCKING);
}