00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef __SIMPLE_STACK_HH
00019 # define __SIMPLE_STACK_HH
00020
00021 # include <memory>
00022
00023 namespace lockfree {
00024
00025 template <typename Elt,
00026 typename Alloc = std::allocator<Elt>
00027 >
00028 class simple_stack {
00029 private:
00030 struct node {
00031 Elt e;
00032 node* next;
00033 node(Elt&& e, node* next): e(std::move(e)), next(next) {}
00034 };
00035 typedef typename Alloc::template rebind<node>::other node_allocator_t;
00036
00037 node_allocator_t alloc;
00038 std::atomic<node*> head;
00039 public:
00040 simple_stack(Alloc alloc = Alloc()): alloc(alloc), head(NULL) {}
00041
00042 struct wrapped {
00043 private:
00044 node_allocator_t& alloc;
00045 node* n;
00046 public:
00047 wrapped(node_allocator_t& alloc, node *n): alloc(alloc), n(n) {}
00048 bool end() const {
00049 return (n == NULL);
00050 }
00051 Elt operator*() const {
00052 return n->e;
00053 }
00054 ~wrapped() {
00055 if (n != NULL) {
00056 alloc.destroy(n);
00057 alloc.deallocate(n, 1);
00058 }
00059 }
00060 };
00061
00062 void push(const Elt& e) {
00063 push(Elt(e));
00064 }
00065
00066 void push(Elt&& e) {
00067 node* n = alloc.allocate(1);
00068 alloc.construct(n, std::move(e), (node*)NULL);
00069 node *h;
00070 do {
00071 h = head.load();
00072 n->next = h;
00073 } while (!head.compare_exchange_strong(h, n));
00074 }
00075
00076 wrapped pop() {
00077 node* n;
00078 do {
00079 n = head.load();
00080 if (n == NULL)
00081 return wrapped(alloc, NULL);
00082 } while (!head.compare_exchange_strong(n, n->next));
00083 return wrapped(alloc, n);
00084 }
00085 };
00086
00087 }
00088
00089 #endif