55 lines
1.1 KiB
C++
55 lines
1.1 KiB
C++
#pragma once
|
|
|
|
#include <atomic>
|
|
#include <thread>
|
|
#include <cassert>
|
|
|
|
#include "utils/underlying_cast.hpp"
|
|
#include "id.hpp"
|
|
|
|
class Thread
|
|
{
|
|
static std::atomic<unsigned> thread_counter;
|
|
|
|
public:
|
|
static size_t count(std::memory_order order = std::memory_order_seq_cst)
|
|
{
|
|
return thread_counter.load(order);
|
|
}
|
|
|
|
static constexpr unsigned UNINITIALIZED = -1;
|
|
static constexpr unsigned MAIN_THREAD = 0;
|
|
|
|
template <class F>
|
|
Thread(F f)
|
|
{
|
|
thread_id = thread_counter.fetch_add(1, std::memory_order_acq_rel);
|
|
thread = std::thread([this, f]() { start_thread(f); });
|
|
}
|
|
|
|
Thread() = default;
|
|
Thread(const Thread&) = delete;
|
|
|
|
Thread(Thread&& other)
|
|
{
|
|
assert(thread_id == UNINITIALIZED);
|
|
thread_id = other.thread_id;
|
|
thread = std::move(other.thread);
|
|
}
|
|
|
|
void join() { return thread.join(); }
|
|
|
|
private:
|
|
unsigned thread_id = UNINITIALIZED;
|
|
std::thread thread;
|
|
|
|
template <class F, class... Args>
|
|
void start_thread(F&& f)
|
|
{
|
|
this_thread::id = thread_id;
|
|
f();
|
|
}
|
|
};
|
|
|
|
std::atomic<unsigned> Thread::thread_counter {1};
|