view src/parallel_execution/examples/boundedBuffer/SemaphoreImpl.cbc @ 524:3bb5da57ddb5

Fix
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Sun, 21 Jan 2018 23:27:19 +0900
parents a7127917c736
children
line wrap: on
line source

#include "../../../context.h"
#interface "Semaphore.h"
#interface "Queue.h"
#interface "TaskManager.h"
#interface "Lock.h"

Semaphore* createSemaphoreImpl(struct Context* context, int n) {
    struct Semaphore* semaphore = new Semaphore();
    struct SemaphoreImpl* semaphoreImpl = new SemaphoreImpl();
    semaphore->semaphore = (union Data*)semaphoreImpl;
    semaphoreImpl->value =  n;
    semaphoreImpl->waitThreadQueue = createSingleLinkedQueue(context);
    semaphoreImpl->lock = createSpinLock(context);
    semaphore->p = C_pOperationSemaphoreImpl;
    semaphore->v = C_vOperationSemaphoreImpl;
    return semaphore;
}

__code pOperationSemaphoreImpl(struct SemaphoreImpl* semaphore, __code next(...)) {
    struct Lock* lock = semaphore->lock;
    goto lock->doLock(pOperationSemaphoreImpl1);
}

__code pOperationSemaphoreImpl1(struct SemaphoreImpl* semaphore, __code next(...)) {
    if (semaphore->value == 0) {
        context->next= C_pOperationSemaphoreImpl;
        struct Queue* queue = semaphore->waitThreadQueue;
        goto queue->put(context, pOperationSemaphoreImpl2); // put this context(thread, process)
    }
    semaphore->value--;
    struct Lock* lock = semaphore->lock;
    goto lock->doUnlock(next(...));
}

__code pOperationSemaphoreImpl2(struct SemaphoreImpl* semaphore, __code next(...)) {
    struct Lock* lock = semaphore->lock;
    goto lock->doUnlock(pOperationSemaphoreImpl3);
}

__code pOperationSemaphoreImpl3(struct SemaphoreImpl* semaphore, struct Worker* worker, __code next(...)) {
    goto worker->taskReceive(); // goto shceduler
}

__code pOperationSemaphoreImpl3_stub(struct Context* context) {
    // switch worker context
    struct Context* workerContext = context->worker->worker->CPUWorker.context;
    SemaphoreImpl* semaphoreImpl = (SemaphoreImpl*)GearImpl(context, Semaphore, semaphore);
    goto pOperationSemaphoreImpl3(workerContext,
                                  semaphoreImpl,
                                  context->worker,
                                  Gearef(context, Semaphore)->next);
}

__code vOperationSemaphoreImpl(struct SemaphoreImpl* semaphore, __code next(...)) {
    struct Lock* lock = semaphore->lock;
    goto lock->doLock(vOperationSemaphoreImpl1);
}

__code vOperationSemaphoreImpl1(struct SemaphoreImpl* semaphore, __code next(...)) {
    semaphore->value++;
    struct Queue* queue = semaphore->waitThreadQueue;
    goto queue->isEmpty(vOperationSemaphoreImpl2, vOperationSemaphoreImpl4);
}

__code vOperationSemaphoreImpl2(struct SemaphoreImpl* semaphore, __code next(...)) {
    struct Queue* queue = semaphore->waitThreadQueue;
    goto queue->take(vOperationSemaphoreImpl3);
}

__code vOperationSemaphoreImpl3(struct SemaphoreImpl* semaphore, struct Context* waitTask, __code next(...)) {
    struct TaskManager* taskManager = waitTask->taskManager;
    goto taskManager->spawn(waitTask, vOperationSemaphoreImpl4); //notify
}

__code vOperationSemaphoreImpl3_stub(struct Context* context) {
    SemaphoreImpl* semaphoreImpl = (SemaphoreImpl*)GearImpl(context, Semaphore, semaphore);
    struct Context* waitTask = &Gearef(context, Queue)->data->Context;
    goto vOperationSemaphoreImpl3(context,
                                  semaphoreImpl,
                                  waitTask,
                                  Gearef(context, Semaphore)->next);
}

__code vOperationSemaphoreImpl4(struct SemaphoreImpl* semaphore, __code next(...)) {
    struct Lock* lock = semaphore->lock;
    goto lock->doUnlock(next(...));
}