view src/parallel_execution/examples/boundedBuffer/BoundedBuffer.cbc @ 507:a7127917c736

SemaphoreImpl use spinlock
author Tatsuki IHA <innparusu@cr.ie.u-ryukyu.ac.jp>
date Wed, 03 Jan 2018 17:34:14 +0900
parents 2e7ea81e5943
children bc1616e1e172
line wrap: on
line source

#include "../../../context.h"
#interface "Buffer.h"
#interface "Semaphore.h"

Buffer* createBoundedBuffer(struct Context* context, int size) {
    struct Buffer* buffer = new Buffer();
    struct BoundedBuffer* boundedBuffer = new BoundedBuffer();
    boundedBuffer->top = new Element();
    boundedBuffer->top->next = NULL;
    boundedBuffer->last = boundedBuffer->top;
    boundedBuffer->fullCount = createSemaphoreImpl(context, 0);
    boundedBuffer->emptyCount = createSemaphoreImpl(context, size);
    boundedBuffer->lock = createSemaphoreImpl(context, 1); // binary semaphore
    buffer->buffer = (union Data*)boundedBuffer;
    buffer->take = C_takeBoundedBuffer;
    buffer->put = C_putBoundedBuffer;
    return buffer;
}

__code putBoundedBuffer(struct BoundedBuffer* buffer, union Data* data, __code next(...)) {
    struct Semaphore* semaphore = buffer->emptyCount;
    goto semaphore->p(putBoundedBuffer1);
}

__code putBoundedBuffer1(struct BoundedBuffer* buffer, union Data* data, __code next(...)) {
    struct Semaphore* semaphore = buffer->lock;
    goto semaphore->p(putBoundedBuffer2);
}

__code putBoundedBuffer2(struct BoundedBuffer* buffer, union Data* data, __code next(...)) {
    struct Element* element = new Element();
    element->data = data;
    element->next = NULL;
    struct Element* last = buffer->last;
    last->next = element;
    buffer->last = element;
    struct Semaphore* semaphore = buffer->lock;
    goto semaphore->v(putBoundedBuffer3);
}

__code putBoundedBuffer3(struct BoundedBuffer* buffer, union Data* data, __code next(...)) {
    struct Semaphore* semaphore = buffer->fullCount;
    goto semaphore->v(putBoundedBuffer4);
}

__code putBoundedBuffer4(struct BoundedBuffer* buffer, union Data* data, __code next(...)) {
    goto next(...);
}
__code takeBoundedBuffer(struct BoundedBuffer* buffer, __code next(union Data* data, ...)) {
    struct Semaphore* semaphore = buffer->fullCount;
    goto semaphore->p(takeBoundedBuffer1);
}

__code takeBoundedBuffer1(struct BoundedBuffer* buffer, __code next(union Data* data, ...)) {
    struct Semaphore* semaphore = buffer->lock;
    goto semaphore->p(takeBoundedBuffer2);
}

__code takeBoundedBuffer2(struct BoundedBuffer* buffer, __code next(union Data* data, ...)) {
    struct Element* top = buffer->top;
    struct Element* nextElement = top->next;
    data = nextElement->data;
    *O_data =data;
    buffer->top = nextElement;
    struct Semaphore* semaphore = buffer->lock;
    goto semaphore->v(takeBoundedBuffer3);
}

__code takeBoundedBuffer3(struct BoundedBuffer* buffer, __code next(union Data* data, ...)) {
    struct Semaphore* semaphore = buffer->emptyCount;
    goto semaphore->v(takeBoundedBuffer4);
}

__code takeBoundedBuffer4(struct BoundedBuffer* buffer, __code next(union Data* data, ...)) {
    goto next(data, ...);
}