Initial commit of snmalloc

History squashed from internal development.

Internal history has commit hash:
  e27a0e485c44a5003a802de2661ce3b21e120316
This commit is contained in:
Matthew Parkinson
2019-01-15 14:17:55 +00:00
parent e488c24784
commit 4f9d991449
53 changed files with 6940 additions and 329 deletions

75
src/ds/mpmcstack.h Normal file
View File

@@ -0,0 +1,75 @@
#pragma once
#include "aba.h"
namespace snmalloc
{
template<class T, Construction c = RequiresInit>
class MPMCStack
{
using ABA = ABA<T, c>;
private:
static_assert(
std::is_same<decltype(((T*)0)->next), std::atomic<T*>>::value,
"T->next must be a std::atomic<T*>");
ABA stack;
public:
void push(T* item)
{
return push(item, item);
}
void push(T* first, T* last)
{
// Pushes an item on the stack.
auto cmp = stack.read();
do
{
T* top = ABA::load(cmp);
last->next.store(top, std::memory_order_release);
} while (!stack.compare_exchange(cmp, first));
}
T* pop()
{
// Returns the next item. If the returned value is decommitted, it is
// possible for the read of top->next to segfault.
auto cmp = stack.read();
T* top;
T* next;
do
{
top = ABA::load(cmp);
if (top == nullptr)
break;
next = top->next.load(std::memory_order_acquire);
} while (!stack.compare_exchange(cmp, next));
return top;
}
T* pop_all()
{
// Returns all items as a linked list, leaving an empty stack.
auto cmp = stack.read();
T* top;
do
{
top = ABA::load(cmp);
if (top == nullptr)
break;
} while (!stack.compare_exchange(cmp, nullptr));
return top;
}
};
}