view src/parallel_execution/SynchronizedQueue.cbc @ 276:27bc962020de

add SynchronizedQueue.cbc
author mir3636
date Wed, 01 Feb 2017 21:29:21 +0900
parents
children 2c2e4e597eb0
line wrap: on
line source

#include "../queue.h"
#include "../origin_cs.h"
#include <stdio.h>

Queue* createSynchronizedQueue(struct Context* context) {
    struct Queue* queue = new Queue();
    struct SingleLinkedQueue* singleLinkedQueue = new SingleLinkedQueue();
    queue->queue = (union Data*)singleLinkedQueue;
    singleLinkedQueue->top  = NULL;
    singleLinkedQueue->last = NULL;
    queue->take  = C_takeSynchronizedQueue;
    queue->put  = C_putSynchronizedQueue;
    queue->isEmpty = C_isEmptySynchronizedQueue;
    queue->clear = C_clearSynchronizedQueue;
    return queue;
}

__code clearSynchronizedQueue(struct SingleLinkedQueue* queue, __code next(...)) {
    struct Element* top = queue->top;
    if (__sync_bool_compare_and_swap(&queue->top, top, NULL)) {
        goto next(...);
    } else {
        goto meta(context, C_clearSynchronizedQueue);
    }
}

__code putSynchronizedQueue(struct SingleLinkedQueue* queue, struct Element* element, union Data* data, __code next(...)) {
    element->next = NULL;
    element->data = data;
    if (queue->last) {
        Element* last = queue->last;
        if (__sync_bool_compare_and_swap(&queue->last, last, element)) {
            last->next = element;
        } else {
            goto meta(context, C_putSynchronizedQueue);
        }
    } else {
        if (__sync_bool_compare_and_swap(&queue->top, NULL, element)) {
            queue->last = element;
        } else {
            goto meta(context, C_putSynchronizedQueue);
        }
    }
    goto next(...);
}

__code takeSynchronizedQueue(struct SingleLinkedQueue* queue, __code next(union Data* data, ...)) {
    if (queue->top) {
        struct Element* top = queue->top;
        if (__sync_bool_compare_and_swap(&queue->top, top, top->next)) {
            *data = top->data;
        } else {
            goto meta(context, C_takeSynchronizedQueue);
        }
    } else {
        *data = NULL;
    }
    goto next(data, ...);
}

__code isEmptySynchronizedQueue(struct SingleLinkedQueue* queue, __code next(...), __code whenEmpty(...)) {
    if (queue->top)
        goto next(...);
    else
        goto whenEmpty(...);
}