view src/parallel_execution/OneDimIterator.cbc @ 386:89a9e9c14498

Add comment to createOneDimiterateTask
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Wed, 26 Jul 2017 18:57:19 +0900
parents f1d111e293c4
children
line wrap: on
line source

#include "../context.h"
#include <stdio.h>

Iterator* createOneDimIterator(struct Context* context, int x) {
    struct Iterator* iterator = new Iterator();
    struct OneDimIterator* oneDimIterator = new OneDimIterator();
    iterator->iterator = (union Data*)oneDimIterator;
    iterator->exec = C_execOneDimIterator;
    iterator->barrier = C_barrierOneDimIterator;
    oneDimIterator->x = x;
    oneDimIterator->count = x;
    oneDimIterator->loopCounter = new LoopCounter();
    oneDimIterator->loopCounter->i = 0;
    return iterator;
}

/**
 * create iterateTask with index, that copy from task argument
 * @return created iterateTask
 * @param task      task of the copy source
 * @x     index
 */
struct Context* createOneDimIterateTask(struct Context* task, int x) {
    struct Context* task1 = NEW(struct Context);
    initContext(task1);
    task1->taskManager = task->taskManager;
    task1->next     = task->next;
    task1->iterate  = 1;
    task1->iterator = task->iterator;
    task1->idgCount = task->idgCount;
    task1->idg      = task->idg;
    task1->maxIdg   = task->maxIdg;
    for(int i = task1->idg; i < task1->maxIdg; i++) {
        task1->data[i] = task->data[i];
    }

    // create index data gear and register input data to iterate task
    struct Integer* dataX = &ALLOCATE_DATA_GEAR(task1, Integer)->Integer;
    dataX->value = x;
    task1->data[task1->maxIdg++] = (union Data*)dataX;

    task1->odg      = task->odg + 1;
    task1->maxOdg   = task->maxOdg + 1;
    for (int i = task1->odg; i < task1->maxOdg; i++) {
        task1->data[i] = task->data[i-1];
    }

    return task1;
}

__code execOneDimIterator(struct OneDimIterator* iterator, struct TaskManager* taskManager, struct Context* task, __code next(...)) {
    int i = iterator->loopCounter->i;
    if (i == iterator->x) {
        iterator->loopCounter->i = 0;
        goto next(...);
    }
    struct Context* iterateTask = createOneDimIterateTask(task, i);
    iterator->loopCounter->i++;
    taskManager->taskManager = (union Data*)task->taskManager;
    taskManager->context = iterateTask;
    taskManager->next = C_execOneDimIterator;
    goto meta(context, task->taskManager->spawn);
}

__code execOneDimIterator_stub(struct Context* context) {
    OneDimIterator* iterator = (OneDimIterator*)GearImpl(context, Iterator, iterator);
    TaskManager* taskManager = Gearef(context, TaskManager);
    Context* task = Gearef(context, Iterator)->task;
    enum Code next = Gearef(context, Iterator)->next;
    goto execOneDimIterator(context, iterator, taskManager, task, next);
} 

__code barrierOneDimIterator(struct OneDimIterator* iterator, struct Context* task, __code next(...), __code whenWait(...)) {
    if (__sync_fetch_and_sub(&iterator->count, 1) == 1) {
        goto next(...);
    }
    goto whenWait(...);
}

__code barrierOneDimIterator_stub(struct Context* context) {
    OneDimIterator* iterator = (OneDimIterator*)GearImpl(context, Iterator, iterator);
    Context* task = Gearef(context, Iterator)->task;
    enum Code next = Gearef(context, Iterator)->next;
    enum Code whenWait = Gearef(context, Iterator)->whenWait;
    goto barrierOneDimIterator(context, iterator, task, next, whenWait);
}