From: Arnaud Giersch Date: Mon, 23 May 2011 12:49:11 +0000 (+0200) Subject: Add a lock-free synchronized queue. X-Git-Tag: v0.1~62^2~11 X-Git-Url: https://bilbo.iut-bm.univ-fcomte.fr/and/gitweb/loba.git/commitdiff_plain/db665945760baeb8f0d50f663db8caeede59697c?ds=inline;hp=10e5dbdfc7cf72a000a90a2f1a27c7dc30364761 Add a lock-free synchronized queue. --- diff --git a/README b/README index d92ee39..8fcbc7c 100644 --- a/README +++ b/README @@ -226,6 +226,8 @@ Liste de fichiers synchro.h mutex, condition, etc. + sync_queue.h lock-free synchronized queue + timer.h gestion de timer tracing.h définitions liées au traçage diff --git a/sync_queue.h b/sync_queue.h new file mode 100644 index 0000000..8888548 --- /dev/null +++ b/sync_queue.h @@ -0,0 +1,82 @@ +#ifndef SYNC_QUEUE_H +#define SYNC_QUEUE_H + +#if __GNUC__ == 4 && __GNUC_MINOR__ == 4 +# include // is named in gcc 4.4 +#else +# include +#endif + +template +class sync_queue { +public: + sync_queue() + { + node* n = new node(NULL, NULL); + std::atomic_store(&head, n); // head.store(n); + std::atomic_store(&tail, n); // tail.store(n); + } + + ~sync_queue() + { + node* n = head.load(); + while (n != NULL) { + node* prev = n; + n = n->next; + delete prev; + } + } + + bool empty() const + { + return head.load() == tail.load(); + } + + // size() is not not thread-safe + size_t size() const + { + size_t count = 0; + for (node* n = head.load()->next; n != NULL; n = n->next) + ++count; + return count; + } + + bool push(const T& val) + { + node* old_tail = tail.load(); + node* n = new node(val, NULL); + old_tail->next = n; + std::atomic_store(&tail, n); // tail.store(n); + return (old_tail == head.load()); + } + + bool try_pop(T& res) + { + node* old_head = head.load(); + if (old_head == tail.load()) { // empty? + return false; + } else { + node* new_head = old_head->next; + std::atomic_store(&head, new_head); // head.store(new_head); + delete old_head; + res = new_head->value; + return true; + } + } + +private: + struct node { + node(const T& v, node* n): value(v), next(n) { } + T value; + node* next; + }; + + std::atomic head; + std::atomic tail; +}; + +#endif // !SYNC_QUEUE_H + +// Local variables: +// mode: c++ +// End: