Mercurial > hg > Members > Moririn
comparison src/parallel_execution/SynchronizedQueue.cbc @ 276:27bc962020de
add SynchronizedQueue.cbc
author | mir3636 |
---|---|
date | Wed, 01 Feb 2017 21:29:21 +0900 (2017-02-01) |
parents | |
children | 2c2e4e597eb0 |
comparison
equal
deleted
inserted
replaced
275:06dab015a54d | 276:27bc962020de |
---|---|
1 #include "../queue.h" | |
2 #include "../origin_cs.h" | |
3 #include <stdio.h> | |
4 | |
5 Queue* createSynchronizedQueue(struct Context* context) { | |
6 struct Queue* queue = new Queue(); | |
7 struct SingleLinkedQueue* singleLinkedQueue = new SingleLinkedQueue(); | |
8 queue->queue = (union Data*)singleLinkedQueue; | |
9 singleLinkedQueue->top = NULL; | |
10 singleLinkedQueue->last = NULL; | |
11 queue->take = C_takeSynchronizedQueue; | |
12 queue->put = C_putSynchronizedQueue; | |
13 queue->isEmpty = C_isEmptySynchronizedQueue; | |
14 queue->clear = C_clearSynchronizedQueue; | |
15 return queue; | |
16 } | |
17 | |
18 __code clearSynchronizedQueue(struct SingleLinkedQueue* queue, __code next(...)) { | |
19 struct Element* top = queue->top; | |
20 if (__sync_bool_compare_and_swap(&queue->top, top, NULL)) { | |
21 goto next(...); | |
22 } else { | |
23 goto meta(context, C_clearSynchronizedQueue); | |
24 } | |
25 } | |
26 | |
27 __code putSynchronizedQueue(struct SingleLinkedQueue* queue, struct Element* element, union Data* data, __code next(...)) { | |
28 element->next = NULL; | |
29 element->data = data; | |
30 if (queue->last) { | |
31 Element* last = queue->last; | |
32 if (__sync_bool_compare_and_swap(&queue->last, last, element)) { | |
33 last->next = element; | |
34 } else { | |
35 goto meta(context, C_putSynchronizedQueue); | |
36 } | |
37 } else { | |
38 if (__sync_bool_compare_and_swap(&queue->top, NULL, element)) { | |
39 queue->last = element; | |
40 } else { | |
41 goto meta(context, C_putSynchronizedQueue); | |
42 } | |
43 } | |
44 goto next(...); | |
45 } | |
46 | |
47 __code takeSynchronizedQueue(struct SingleLinkedQueue* queue, __code next(union Data* data, ...)) { | |
48 if (queue->top) { | |
49 struct Element* top = queue->top; | |
50 if (__sync_bool_compare_and_swap(&queue->top, top, top->next)) { | |
51 *data = top->data; | |
52 } else { | |
53 goto meta(context, C_takeSynchronizedQueue); | |
54 } | |
55 } else { | |
56 *data = NULL; | |
57 } | |
58 goto next(data, ...); | |
59 } | |
60 | |
61 __code isEmptySynchronizedQueue(struct SingleLinkedQueue* queue, __code next(...), __code whenEmpty(...)) { | |
62 if (queue->top) | |
63 goto next(...); | |
64 else | |
65 goto whenEmpty(...); | |
66 } |