view example/many_task/sort-compat.cc @ 945:a9c7784e5dae

sort example fix ( simple task accepts one param and more compatible with old task)
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Sun, 01 Aug 2010 19:29:27 +0900
parents
children
line wrap: on
line source

#include "TaskManager.h"
#include "SchedTask.h"
#include "sort.h"
#include "Func.h"
#include <string.h>

extern void check_data();
extern int all;  // allocate task at once

SchedDefineTask1(SortCompat, sort_start_compat );

static int sort_start_compat(SchedTask *manager, void *a, void *b)
{
    Sort *s = (Sort*)manager->get_param(0);
    int half_num = s->split_num-1;
    static int sort_count = s->split_num; // sort 完了に必要な回数

    // 一つのタスクで sort する data 数
    int block_num = (s->data_length + s->split_num -1)/s->split_num;
    int half_block_num = block_num/2;

    int last_block_num = s->data_length - (s->split_num-1)*block_num;
    int last_half_block_num = half_block_num+(last_block_num/2);


    if (--sort_count < 0) {
	return 0;
    }

    for (int i = 0; i < s->split_num-1; i++) {
	s->fsort[i] = manager->create_task(QUICK_SORT);
	s->fsort[i]->add_inData(&s->data[i*block_num], sizeof(Data)*block_num);
	s->fsort[i]->add_outData(&s->data[i*block_num], sizeof(Data)*block_num);
	if (i>0 && s->bsort[i-1]) {
	    s->fsort[i]->wait_for(s->bsort[i-1]);
	}
	if (i<s->split_num-2 && s->bsort[i]) {
	    s->fsort[i]->wait_for(s->bsort[i]);
	}
	s->fsort[i]->set_cpu(SPE_ANY);
    }

    // 最後の block は端数なので last_block_num を使う
    {
	int i = s->split_num-1;

	s->fsort[i] = manager->create_task(QUICK_SORT);
	s->fsort[i]->add_inData(&s->data[i*block_num], sizeof(Data)*last_block_num);
	s->fsort[i]->add_outData(&s->data[i*block_num], sizeof(Data)*last_block_num);
	if (i>0 && s->bsort[i-1]) {
	    s->fsort[i]->wait_for(s->bsort[i-1]);
	}
	s->fsort[i]->set_cpu(SPE_ANY);
   }

    if (s->split_num > 1) {

	for (int i = 0; i < half_num-1; i++) {
	    if (s->bsort[i]) manager->free_htask(s->bsort[i]);
	    s->bsort[i] = manager->create_task(QUICK_SORT);
	    s->bsort[i]->add_inData(&s->data[i*block_num+half_block_num],
				 sizeof(Data)*block_num);
	    s->bsort[i]->add_outData(&s->data[i*block_num+half_block_num],
				  sizeof(Data)*block_num);
	    s->bsort[i]->set_cpu(SPE_ANY);
	}

	{
	    int i = half_num-1;

	    if (s->bsort[i]) manager->free_htask(s->bsort[i]);
	    s->bsort[i] = manager->create_task(QUICK_SORT);
	    s->bsort[i]->add_inData(&s->data[i*block_num+half_block_num],
				 sizeof(Data)*last_half_block_num);
	    s->bsort[i]->add_outData(&s->data[i*block_num+half_block_num],
				  sizeof(Data)*last_half_block_num);
	    s->bsort[i]->set_cpu(SPE_ANY);	
	}
	
	for (int i = 0; i < half_num; i++) {
	    s->bsort[i]->wait_for(s->fsort[i]);
	    s->bsort[i]->wait_for(s->fsort[i+1]);
	    s->bsort[i]->no_auto_free();
	    s->bsort[i]->spawn();
	}
    }

    HTaskPtr restart = manager->create_task(SortCompat,0,0,0,0);
    restart->set_param(0,(memaddr)s);
    if (!all) restart->wait_for(s->fsort[0]);
    for (int i = 0; i < s->split_num; i++) {
	s->fsort[i]->spawn();
    }
    restart->spawn();

    return 0;
}