Mercurial > hg > Members > Moririn
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); +}