view src/parallel_execution/queue.c @ 169:ea7b11f3e717

Using Queue Interface
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Tue, 22 Nov 2016 09:48:37 +0900
parents fa7419e2c67c
children 57a11c15ff4c
line wrap: on
line source

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

union Data* createSingleLinkedQueue(struct Context* context) {
    struct Queue* queue = &ALLOCATE(context, Queue)->queue;
    struct SingleLinkedQueue* singleLinkedQueue = &ALLOCATE(context, SingleLinkedQueue)->singleLinkedQueue;
    queue->queue = (union Data*)singleLinkedQueue;
    singleLinkedQueue->top  = NULL;
    singleLinkedQueue->last = NULL;
    queue->take  = C_takeSingleLinkedQueue;
    queue->put  = C_putSingleLinkedQueue;
    queue->isEmpty = C_isEmptySingleLinkedQueue;
    queue->clear = C_clearSingleLinkedQueue;
    return (union Data*)(queue);
}

void printQueue1(union Data* data) {
    struct Node* node = &data->element.data->node;
    if (node == NULL) {
        printf("NULL");
    } else {
        printf("key = %d ,", node->key);
        printQueue1((union Data*)data->element.next);
    }
}

void printQueue(union Data* data) {
    printQueue1(data);
    printf("\n");
}

__code clearSingleLinkedQueue(struct Context* context, struct SingleLinkedQueue* queue,enum Code next) {
    queue->top = NULL;
    goto meta(context, next);
}

__code clearSingleLinkedQueue_stub(struct Context* context) {
    goto clearSingleLinkedQueue(context, (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue, context->data[D_Queue]->queue.next);
}

__code putSingleLinkedQueue(struct Context* context, struct SingleLinkedQueue* queue, struct Element* element, union Data* data, enum Code next) {
    element->next = NULL;
    element->data = data;
    if (queue->last) {
        Element* last = queue->last;
        last->next = element;
        queue->last = element;
    } else {
        queue->top = element;
        queue->last = element;
    } 
    goto meta(context, next);
}

__code putSingleLinkedQueue_stub(struct Context* context) {
    struct Element* element = &ALLOCATE(context, Element)->element;
    goto putSingleLinkedQueue(context,
                               (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
                               element,
                               context->data[D_Queue]->queue.data,
                               context->data[D_Queue]->queue.next);
}

__code takeSingleLinkedQueue(struct Context* context, struct SingleLinkedQueue* queue, union Data** data, enum Code next) {
    if (queue->top) {
        *data = queue->top->data;
        queue->top = queue->top->next;
    } else {
        *data = NULL;
    }
    goto meta(context, next);
}

__code takeSingleLinkedQueue_stub(struct Context* context) {
    goto takeSingleLinkedQueue(context,
                               (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
                               &context->data[D_Queue]->queue.data,
                               context->data[D_Queue]->queue.next);
}

__code isEmptySingleLinkedQueue(struct Context* context, struct SingleLinkedQueue* queue, enum Code next,enum Code whenEmpty) {
    if (queue->top)
        goto meta(context, next);
    else
        goto meta(context, whenEmpty);
}

__code isEmptySingleLinkedQueue_stub(struct Context* context) {
    goto isEmptySingleLinkedQueue(context,
                               (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
                               context->data[D_Queue]->queue.next,
                               context->data[D_Queue]->queue.whenEmpty);
}

union Data* createSynchronizedQueue(struct Context* context) {
    struct Queue* queue = &ALLOCATE(context, Queue)->queue;
    struct SingleLinkedQueue* singleLinkedQueue = &ALLOCATE(context, SingleLinkedQueue)->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 (union Data*)(queue);
}

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

__code clearSynchornizedQueue_stub(struct Context* context) {
    goto clearSingleLinkedQueue(context, (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue, context->data[D_Queue]->queue.next);
}

__code putSynchronizedQueue(struct Context* context, struct SingleLinkedQueue* queue, struct Element* element, union Data* data, enum 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 meta(context, next);
}

__code putSynchronizedQueue_stub(struct Context* context) {
    struct Element* element = &ALLOCATE(context, Element)->element;
    goto putSynchronizedQueue(context,
            (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
            element,
            context->data[D_Queue]->queue.data,
            context->data[D_Queue]->queue.next);
}

__code takeSynchronizedQueue(struct Context* context, struct SingleLinkedQueue* queue, union Data** data, enum Code next) {
    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 meta(context, next);
}

__code takeSynchronizedQueue_stub(struct Context* context) {
    goto takeSynchronizedQueue(context,
            (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
            &context->data[D_Queue]->queue.data,
            context->data[D_Queue]->queue.next);
}

__code isEmptySynchronizedQueue(struct Context* context, struct SingleLinkedQueue* queue, enum Code next,enum Code whenEmpty) {
    if (queue->top)
        goto meta(context, next);
    else
        goto meta(context, whenEmpty);
}

__code isEmptySynchronizedQueue_stub(struct Context* context) {
    goto isEmptySynchronizedQueue(context,
            (struct SingleLinkedQueue *)context->data[D_Queue]->queue.queue->queue.queue,
            context->data[D_Queue]->queue.next,
            context->data[D_Queue]->queue.whenEmpty);
}