X-Git-Url: http://plrg.eecs.uci.edu/git/?p=model-checker-benchmarks.git;a=blobdiff_plain;f=chase-lev-deque%2Fdeque.c;h=34f645be799ba82e4b369ffa08046de30cc831ec;hp=956e8e0177f165ec26a440070a45546f9a315e65;hb=1af8c0a4514c147221b92a1056afc58dc305f53c;hpb=e7fb1d3fca70b9f871b961f2f3c3443d4955a3b4 diff --git a/chase-lev-deque/deque.c b/chase-lev-deque/deque.c index 956e8e0..34f645b 100644 --- a/chase-lev-deque/deque.c +++ b/chase-lev-deque/deque.c @@ -1,58 +1,81 @@ -typedef struct { - atomic_size_t size; - atomic_int buffer[]; -} Array; +#include +#include +#include "deque.h" +#include -typedef struct { - atomic_size_t top, bottom; - Atomic(Array *) array; -} Deque; +Deque * create() { + Deque * q = (Deque *) calloc(1, sizeof(Deque)); + Array * a = (Array *) calloc(1, sizeof(Array)+2*sizeof(atomic_int)); + atomic_store_explicit(&q->array, a, memory_order_relaxed); + atomic_store_explicit(&q->top, 0, memory_order_relaxed); + atomic_store_explicit(&q->bottom, 0, memory_order_relaxed); + atomic_store_explicit(&a->size, 2, memory_order_relaxed); + return q; +} int take(Deque *q) { - size_t b = load_explicit(&q->bottom, relaxed) - 1; - Array *a = load_explicit(&q->array, relaxed); - store_explicit(&q->bottom, b, relaxed); - thread_fence(seq_cst); - size_t t = load_explicit(&q->top, relaxed); + size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed) - 1; + Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed); + atomic_store_explicit(&q->bottom, b, memory_order_relaxed); + atomic_thread_fence(memory_order_seq_cst); + size_t t = atomic_load_explicit(&q->top, memory_order_relaxed); int x; if (t <= b) { /* Non-empty queue. */ - x = load_explicit(&a->buffer[b % a->size], relaxed); + x = atomic_load_explicit(&a->buffer[b % atomic_load_explicit(&a->size,memory_order_relaxed)], memory_order_relaxed); if (t == b) { /* Single last element in queue. */ - if (!compare_exchange_strong_explicit(&q->top, &t, t + 1, seq_cst, relaxed)) + if (!atomic_compare_exchange_strong_explicit(&q->top, &t, t + 1, memory_order_seq_cst, memory_order_relaxed)) /* Failed race. */ x = EMPTY; - store_explicit(&q->bottom, b + 1, relaxed); + atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed); } } else { /* Empty queue. */ x = EMPTY; - store_explicit(&q->bottom, b + 1, relaxed); + atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed); } return x; } +void resize(Deque *q) { + Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed); + size_t size=atomic_load_explicit(&a->size, memory_order_relaxed); + size_t new_size=size << 1; + Array *new_a = (Array *) calloc(1, new_size * sizeof(atomic_int) + sizeof(Array)); + size_t top=atomic_load_explicit(&q->top, memory_order_relaxed); + size_t bottom=atomic_load_explicit(&q->bottom, memory_order_relaxed); + atomic_store_explicit(&new_a->size, new_size, memory_order_relaxed); + size_t i; + for(i=top; i < bottom; i++) { + atomic_store_explicit(&new_a->buffer[i], atomic_load_explicit(&a->buffer[i], memory_order_relaxed), memory_order_relaxed); + } + atomic_store_explicit(&q->array, new_a, memory_order_relaxed); +} + void push(Deque *q, int x) { - size_t b = load_explicit(&q->bottom, relaxed); - size_t t = load_explicit(&q->top, acquire); - Array *a = load_explicit(&q->array, relaxed); - if (b - t > a->size - 1) /* Full queue. */ + size_t b = atomic_load_explicit(&q->bottom, memory_order_relaxed); + size_t t = atomic_load_explicit(&q->top, memory_order_acquire); + Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed); + if (b - t > atomic_load_explicit(&a->size, memory_order_relaxed) - 1) /* Full queue. */ { resize(q); - store_explicit(&a->buffer[b % a->size], x, relaxed); - thread_fence(release); - store_explicit(&q->bottom, b + 1, relaxed); + //Bug in paper...should have next line... + a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed); + } + atomic_store_explicit(&a->buffer[b % atomic_load_explicit(&a->size, memory_order_relaxed)], x, memory_order_relaxed); + atomic_thread_fence(memory_order_release); + atomic_store_explicit(&q->bottom, b + 1, memory_order_relaxed); } int steal(Deque *q) { - size_t t = load_explicit(&q->top, acquire); - thread_fence(seq_cst); - size_t b = load_explicit(&q->bottom, acquire); + size_t t = atomic_load_explicit(&q->top, memory_order_acquire); + atomic_thread_fence(memory_order_seq_cst); + size_t b = atomic_load_explicit(&q->bottom, memory_order_acquire); int x = EMPTY; if (t < b) { /* Non-empty queue. */ - Array *a = load_explicit(&q->array, relaxed); - x = load_explicit(&a->buffer[t % a->size], relaxed); - if (!compare_exchange_strong_explicit(&q->top, &t, t + 1, seq_cst, relaxed)) + Array *a = (Array *) atomic_load_explicit(&q->array, memory_order_relaxed); + x = atomic_load_explicit(&a->buffer[t % atomic_load_explicit(&a->size, memory_order_relaxed)], memory_order_relaxed); + if (!atomic_compare_exchange_strong_explicit(&q->top, &t, t + 1, memory_order_seq_cst, memory_order_relaxed)) /* Failed race. */ return ABORT; }