lock free linked list implementation

This commit is contained in:
Dominik Tomičević 2015-09-24 01:14:00 +02:00
parent 38ec6a10b1
commit ec9af001d6
5 changed files with 162 additions and 84 deletions

View File

@ -1,71 +0,0 @@
#ifndef MEMGRAPH_DATA_STRUCTURES_LOCKFREE_LIST2_HPP
#define MEMGRAPH_DATA_STRUCTURES_LOCKFREE_LIST2_HPP
#include <atomic>
#include "threading/sync/spinlock.hpp"
#include "threading/sync/lockable.hpp"
namespace lockfree
{
template <class T>
class List2 : Lockable<SpinLock>
{
struct Node { T value; std::atomic<Node*> next; };
class iterator
{
iterator(Node* node) : node(node) {}
T& operator*() const { return *node; }
T* operator->() const { return node; }
bool end() const
{
return node == nullptr;
}
iterator& operator++()
{
node = node->next.load(std::memory_order_relaxed);
return *this;
}
iterator& operator++(int)
{
return operator++();
}
protected:
Node* node;
};
public:
~List2()
{
Node* next, node = head.load(std::memory_order_relaxed);
for(; node != nullptr; node = next)
{
next = node->next;
delete node;
}
}
void insert(T value)
{
auto guard = acquire();
head.store(new Node { value, head });
}
iterator begin() { return iterator(head.load()); }
private:
std::atomic<Node*> head;
};
}
#endif

115
promise.cpp Normal file
View File

@ -0,0 +1,115 @@
#include <iostream>
#include <atomic>
#include "server/uv/uv.hpp"
#include "server/http/http.hpp"
template <class T, class... Args>
class Promise
{
public:
Promise(std::function<T(Args...)> f, Args&&... args)
{
result = f(std::forward<Args>(args)...);
}
template <class R>
Promise<R, T> then(std::function<R(T)> f)
{
return Promise(f, std::forward<T>(result));
}
T get()
{
return result;
}
private:
T result;
std::atomic<bool> completed;
};
class TaskPool
{
template <class R, class... Args>
class Task
{
public:
using task_t = Task<R, Args...>;
using work_f = std::function<R(Args...)>;
using after_work_f = std::function<void(R)>;
Task(work_f work, after_work_f callback)
: work(work), callback(callback)
{
req.data = this;
}
void launch(uv::UvLoop& loop)
{
uv_queue_work(loop, &req, work_cb, after_work_cb);
}
private:
std::function<R(Args...)> work;
std::function<void(R&)> callback;
R result;
uv_work_t req;
static void work_cb(uv_work_t* req)
{
auto& task = *reinterpret_cast<task_t*>(req->data);
}
static void after_work_cb(uv_work_t* req, int)
{
auto task = reinterpret_cast<task_t>(req->data);
delete task;
}
};
public:
TaskPool(uv::UvLoop& loop) : loop(loop) {}
template <class R, class...Args>
void launch(std::function<R(Args...)> func,
std::function<void(R&)> callback)
{
auto task = new Task<R, Args...>(func, callback);
task->launch(loop);
}
private:
uv::UvLoop& loop;
};
int main(void)
{
uv::UvLoop loop;
TaskPool tp(loop);
tp.launch([](void) -> int { return 3 },
[](int x) -> void { std::cout << x << std::endl; });
// http::HttpServer server(loop);
//
// http::Ipv4 ip("0.0.0.0", 3400);
//
// server.listen(ip, [](http::Request& req, http::Response& res) {
//
//
//
// res.send(req.url);
// });
//
// loop.run(uv::UvLoop::Mode::Default);
return 0;
}

View File

@ -12,6 +12,7 @@ class LockExpiredError : public std::runtime_error
using runtime_error::runtime_error;
};
template <size_t microseconds = 250>
class TimedSpinLock
{
public:
@ -36,7 +37,7 @@ public:
if(clock::now() - start > expiration)
throw LockExpiredError("This lock has expired");
usleep(250);
usleep(microseconds);
}
}

View File

@ -1,12 +0,0 @@
#ifndef MEMGRAPH_THREADING_TASK_HPP
#define MEMGRAPH_THREADING_TASK_HPP
class Task
{
public:
private:
//std::function<
};
#endif

45
utils/mark_ref.hpp Normal file
View File

@ -0,0 +1,45 @@
#ifndef MEMGRAPH_UTILS_MARK_REF_HPP
#define MEMGRAPH_UTILS_MARK_REF_HPP
#include <stdint.h>
template <class T>
struct MarkRef
{
MarkRef() = default;
MarkRef(MarkRef&) = default;
MarkRef(MarkRef&&) = default;
bool is_marked() const
{
return ptr & 0x1L;
}
bool set_mark()
{
return ptr |= 0x1L;
}
bool clear_mark()
{
return ptr &= ~0x1L;
}
T* get() const
{
return reinterpret_cast<T*>(ptr & ~0x1L);
}
T& operator*() { return *get(); }
T* operator->() { return get(); }
uintptr_t ptr;
};
//template <class T, class... Args>
//MarkRef<T> make_markref(Args&&... args)
//{
//
//}
#endif