changeset 168:fa7419e2c67c

Add synchornizedQueue
author Tatsuki IHA <e125716@ie.u-ryukyu.ac.jp>
date Tue, 22 Nov 2016 04:21:11 +0900
parents 34562e63981f
children ea7b11f3e717
files src/parallel_execution/context.h src/parallel_execution/queue.c
diffstat 2 files changed, 96 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/src/parallel_execution/context.h	Mon Nov 21 18:03:43 2016 +0900
+++ b/src/parallel_execution/context.h	Tue Nov 22 04:21:11 2016 +0900
@@ -98,6 +98,14 @@
     C_getSingleLinkedStack,
     C_get2SingleLinkedStack,
     C_isEmptySingleLinkedStack,
+    C_takeSingleLinkedQueue,
+    C_putSingleLinkedQueue,
+    C_isEmptySingleLinkedQueue,
+    C_clearSingleLinkedQueue,
+    C_takeSynchronizedQueue,
+    C_putSynchronizedQueue,
+    C_isEmptySynchronizedQueue,
+    C_clearSynchronizedQueue,
     SpawnTask,
     Twice,
     StartTime,
--- a/src/parallel_execution/queue.c	Mon Nov 21 18:03:43 2016 +0900
+++ b/src/parallel_execution/queue.c	Tue Nov 22 04:21:11 2016 +0900
@@ -8,7 +8,6 @@
     struct SingleLinkedQueue* singleLinkedQueue = &ALLOCATE(context, SingleLinkedQueue)->singleLinkedQueue;
     queue->queue = (union Data*)singleLinkedQueue;
     singleLinkedQueue->top = NULL;
-    queue->get  = C_getSingleLinkedQueue;
     queue->take  = C_takeSingleLinkedQueue;
     queue->put  = C_putSingleLinkedQueue;
     queue->isEmpty = C_isEmptySingleLinkedQueue;
@@ -94,3 +93,91 @@
                                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;
+    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);
+}