view src/parallel_execution/worker.c @ 125:77e60b6cdace

Work dependency example
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Tue, 27 Sep 2016 17:22:00 +0900
parents 4ff6f093b695
children
line wrap: on
line source

#include <libkern/OSAtomic.h>

#include "context.h"
#include "origin_cs.h"

__code meta_getTask(struct Context* context, struct Queue* queue, enum Code next) {
    context->data[Queue] = (union Data *)queue;
    goto (context->code[next])(context);
}

__code getTask(struct Context* context, struct Queue* activeQueue) {
    context->next = GetInputData1;
    activeQueue->emptyNext = GetTask;
    goto meta_getTask(context, activeQueue, GetQueue1);
}

__code getTask_stub(struct Context* context) {
    goto getTask(context, &context->data[ActiveQueue]->queue);
}

__code getQueue1(struct Context* context, struct Queue* queue, struct Element* element) {
    if (queue->first == 0)
        goto meta(context, queue->emptyNext);

    element->data = queue->first->data;
    if (__sync_bool_compare_and_swap(&queue->first, queue->first, queue->next)) {
        queue->count--;
        goto meta(context, context->next);
    } else {
        goto meta(context, GetQueue1);
    }
}

__code getQueue1_stub(struct Context* context) {
    goto getQueue1(context, &context->data[Queue]->queue, &context->data[Element]->element);
}

__code getInputData1(struct Context* context, struct Task* task, struct Node* node, struct LoopCounter* loopCounter) {
    int i = loopCounter->i;
    if(i < sizeof(task->iKeys) / sizeof(int)) {
        context->next = GetInputData2;
        node->key = task->iKeys[i];
        struct Traverse *t = &context->data[Traverse]->traverse;
        t->next = GetQueue1;
        goto meta(context, Get);
    }
    loopCounter->i = 0;
    goto meta(context, GetOutputData1);
}

__code getInputData1_stub(struct Context* context) {
    goto getInputData1(context,
            (struct Task*)(context->data[Element]->element.data),
            &context->data[Node]->node,
            &context->data[LoopCounter]->loopCounter);
}

__code getInputData2(struct Context* context, struct Task* task, union Data* data, struct LoopCounter* loopCounter) {
    int i = loopCounter->i;
    task->iargs[i] = data;
    loopCounter->i++;
    goto meta(context, GetInputData1);
}

__code getInputData2_stub(struct Context* context) {
    goto getInputData2(context,
            (struct Task*)(context->data[Element]->element.data),
            context->data[Node]->node.value,
            &context->data[LoopCounter]->loopCounter);
}

__code getOutputData1(struct Context* context, struct Task* task, struct Node* node, struct LoopCounter* loopCounter) {
    int i = loopCounter->i;
    if(i < sizeof(task->oKeys)/ sizeof(int)) {
        context->next = GetOutputData2;
        node->key = task->oKeys[i];
        struct Traverse *t = &context->data[Traverse]->traverse;
        t->next = GetQueue1;
        goto meta(context, Get);
    }
    context->next = CheckTaskFinish1;
    loopCounter->i = 0;
    goto meta(context, task->code);
}

__code getOutputData1_stub(struct Context* context) {
    goto getOutputData1(context,
            (struct Task*)(context->data[Element]->element.data),
            &context->data[Node]->node,
            &context->data[LoopCounter]->loopCounter);
}

__code getOutputData2(struct Context* context, struct Task* task, union Data* data, struct LoopCounter* loopCounter) {
    int i = loopCounter->i;
    task->oargs[i] = data;
    loopCounter->i++;
    goto meta(context, GetOutputData1);
}

__code getOutputData2_stub(struct Context* context) {
    goto getOutputData2(context,
            (struct Task*)(context->data[Element]->element.data),
            context->data[Node]->node.value,
            &context->data[LoopCounter]->loopCounter);
}

#ifdef USE_CUDA
__code twiceGpu(struct Context* context) {
    cuMemcpyHtoDAsync(context,context,context,context->stream);
    cuLaunchkanel();
    cuMemcpyDtoHAsync();
}
#endif