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