24 #ifndef LOCK_FREE_POOL_HPP
25 #define LOCK_FREE_POOL_HPP
28 #include <graphlab/logger/assertions.hpp>
29 #include <graphlab/parallel/atomic.hpp>
30 #include <graphlab/util/lock_free_internal.hpp>
31 #include <graphlab/util/branch_hints.hpp>
34 template <
typename T,
typename index_type = u
int32_t>
45 std::vector<index_type> freelist;
46 typedef lock_free_internal::reference_with_counter<index_type> queue_ref_type;
47 volatile queue_ref_type freelisthead;
50 lock_free_pool(
size_t poolsize = 0) { reset_pool(poolsize); }
53 void reset_pool(
size_t poolsize) {
57 lower_ptrlimit = NULL;
58 upper_ptrlimit = NULL;
60 data.resize(poolsize);
61 freelist.resize(poolsize);
62 for (index_type i = 0;i < freelist.size(); ++i) {
65 freelist[freelist.size() - 1] = index_type(-1);
66 lower_ptrlimit = &(data[0]);
67 upper_ptrlimit = &(data[data.size() - 1]);
69 freelisthead.q.val = 0;
70 freelisthead.q.counter = 0;
73 std::vector<T>& unsafe_get_pool_ref() {
return data; }
77 queue_ref_type oldhead;
78 queue_ref_type newhead;
80 oldhead.combined = freelisthead.combined;
81 if (oldhead.q.val == index_type(-1))
return new T;
82 newhead.q.val = freelist[oldhead.q.val];
83 newhead.q.counter = oldhead.q.counter + 1;
87 freelist[oldhead.q.val] = index_type(-1);
88 return &(data[oldhead.q.val]);
94 if (__unlikely__(p < lower_ptrlimit || p > upper_ptrlimit)) {
99 index_type cur = index_type(p - &(data[0]));
104 queue_ref_type oldhead;
105 queue_ref_type newhead;
107 oldhead.combined = freelisthead.combined;
108 freelist[cur] = oldhead.q.val;
110 newhead.q.counter = oldhead.q.counter + 1;