[09_queue] concurrency, lock_free_queue, done.
This commit is contained in:
parent
e3cfa2cad9
commit
ee3253afdd
74
c-cpp/09_queue/lock_free_queue.hpp
Normal file
74
c-cpp/09_queue/lock_free_queue.hpp
Normal file
@ -0,0 +1,74 @@
|
||||
/**
|
||||
* Created by Liam Huang (Liam0205) on 2018/10/11.
|
||||
*/
|
||||
|
||||
#ifndef QUEUE_LOCK_FREE_QUEUE_HPP_
|
||||
#define QUEUE_LOCK_FREE_QUEUE_HPP_
|
||||
|
||||
#include <memory>
|
||||
#include <atomic>
|
||||
|
||||
template <typename T>
|
||||
class LockFreeQueue {
|
||||
public:
|
||||
using value_type = T;
|
||||
|
||||
private:
|
||||
struct node {
|
||||
std::shared<value_type> data = nullptr;
|
||||
node* next = nullptr;
|
||||
};
|
||||
std::atomic<node*> head = nullptr;
|
||||
std::atomic<node*> tail = nullptr;
|
||||
|
||||
public:
|
||||
LockFreeQueue() head(new node), tail(head.load()) {}
|
||||
LockFreeQueue(const LockFreeQueue&) = delete;
|
||||
LockFreeQueue& operator=(const LockFreeQueue&) = delete;
|
||||
// TODO(Liam Huang): move constructor and move assignment should be well implemented later,
|
||||
// and hance marked "delete".
|
||||
LockFreeQueue(LockFreeQueue&&) = delete;
|
||||
LockFreeQueue& operator=(LockFreeQueue&&) = delete;
|
||||
~LockFreeQueue() {
|
||||
while (node* const old_head = head.load()) {
|
||||
head.store(old_head->next);
|
||||
delete old_head;
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
node* pop_head() {
|
||||
node* const res = head.load();
|
||||
if (res == tail.load()) {
|
||||
return nullptr;
|
||||
}
|
||||
head.store(res->next);
|
||||
return res;
|
||||
}
|
||||
|
||||
public:
|
||||
bool empty() const {
|
||||
return head.load() == tail.load();
|
||||
}
|
||||
std::shared_ptr<value_type> pop() {
|
||||
node* old_head = pop_head();
|
||||
if (nullptr == old_head) {
|
||||
return nullptr;
|
||||
} else {
|
||||
auto res = old_head->data;
|
||||
delete old_head;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
void push(value_type new_value) {
|
||||
auto new_data = std::make_shared<value_type>(new_value);
|
||||
node* p = new node;
|
||||
node* old_tail = tail.load();
|
||||
old_tail->data.swap(new_data);
|
||||
old_tail->next = p;
|
||||
tail_.store(p);
|
||||
}
|
||||
};
|
||||
|
||||
#endif // QUEUE_LOCK_FREE_QUEUE_HPP_
|
||||
|
Loading…
Reference in New Issue
Block a user