HelenOS sources
This source file includes following definitions.
- join
- finished
- detach
- detached
- thread_main
- sleep_until
- sleep_for
#ifndef LIBCPP_BITS_THREAD
#define LIBCPP_BITS_THREAD
#include <__bits/thread/threading.hpp>
#include <chrono>
#include <ostream>
namespace std
{
namespace aux
{
template<class Callable>
int thread_main(void*);
class joinable_wrapper
{
public:
joinable_wrapper()
: join_mtx_{}, join_cv_{},
finished_{false}, detached_{false}
{
aux::threading::mutex::init(join_mtx_);
aux::threading::condvar::init(join_cv_);
}
void join()
{
aux::threading::mutex::lock(join_mtx_);
while (!finished_)
aux::threading::condvar::wait(join_cv_, join_mtx_);
aux::threading::mutex::unlock(join_mtx_);
}
bool finished() const
{
return finished_;
}
void detach()
{
detached_ = true;
}
bool detached() const
{
return detached_;
}
protected:
aux::mutex_t join_mtx_;
aux::condvar_t join_cv_;
bool finished_;
bool detached_;
};
template<class Callable>
class callable_wrapper: public joinable_wrapper
{
public:
callable_wrapper(Callable&& clbl)
: joinable_wrapper{}, callable_{forward<Callable>(clbl)}
{ }
void operator()()
{
callable_();
aux::threading::mutex::lock(join_mtx_);
finished_ = true;
aux::threading::mutex::unlock(join_mtx_);
aux::threading::condvar::broadcast(join_cv_);
}
private:
Callable callable_;
};
}
class thread
{
public:
class id;
using native_handle_type = aux::thread_t*;
thread() noexcept;
~thread();
template<class F, class... Args>
explicit thread(F&& f, Args&&... args)
: id_{}
{
auto callable = [=](){
return f(forward<Args>(args)...);
};
auto callable_wrapper = new aux::callable_wrapper<decltype(callable)>{move(callable)};
joinable_wrapper_ = static_cast<aux::joinable_wrapper*>(callable_wrapper);
id_ = aux::threading::thread::create(
aux::thread_main<decltype(callable_wrapper)>,
*callable_wrapper
);
aux::threading::thread::start(id_);
}
thread(const thread&) = delete;
thread& operator=(const thread&) = delete;
thread(thread&& other) noexcept;
thread& operator=(thread&& other) noexcept;
void swap(thread& other) noexcept;
bool joinable() const noexcept;
void join();
void detach();
id get_id() const noexcept;
native_handle_type native_handle();
static unsigned hardware_concurrency() noexcept;
private:
aux::thread_t id_;
aux::joinable_wrapper* joinable_wrapper_{nullptr};
template<class Callable>
friend int aux::thread_main(void*);
};
namespace aux
{
template<class CallablePtr>
int thread_main(void* clbl)
{
if (!clbl)
return 1;
auto callable = static_cast<CallablePtr>(clbl);
(*callable)();
if (callable->detached())
delete callable;
return 0;
}
}
void swap(thread& x, thread& y) noexcept;
namespace this_thread
{
thread::id get_id() noexcept;
void yield() noexcept;
template<class Clock, class Duration>
void sleep_until(const chrono::time_point<Clock, Duration>& abs_time)
{
auto now = Clock::now();
auto time = aux::threading::time::convert(abs_time - now);
aux::threading::time::sleep(time);
}
template<class Rep, class Period>
void sleep_for(const chrono::duration<Rep, Period>& rel_time)
{
if (rel_time <= chrono::duration<Rep, Period>::zero())
return;
auto time = aux::threading::time::convert(rel_time);
aux::threading::time::sleep(time);
}
}
template<class T>
struct hash;
class thread::id
{
public:
constexpr id() noexcept
: id_{}
{ }
private:
aux::thread_t id_;
id(aux::thread_t id)
: id_{id}
{ }
friend class thread;
friend bool operator==(thread::id, thread::id) noexcept;
friend bool operator!=(thread::id, thread::id) noexcept;
friend bool operator<(thread::id, thread::id) noexcept;
friend bool operator<=(thread::id, thread::id) noexcept;
friend bool operator>(thread::id, thread::id) noexcept;
friend bool operator>=(thread::id, thread::id) noexcept;
template<class Char, class Traits>
friend basic_ostream<Char, Traits>& operator<<(
basic_ostream<Char, Traits>&, thread::id);
friend struct hash<id>;
friend id this_thread::get_id() noexcept;
};
bool operator==(thread::id lhs, thread::id rhs) noexcept;
bool operator!=(thread::id lhs, thread::id rhs) noexcept;
bool operator<(thread::id lhs, thread::id rhs) noexcept;
bool operator<=(thread::id lhs, thread::id rhs) noexcept;
bool operator>(thread::id lhs, thread::id rhs) noexcept;
bool operator>=(thread::id lhs, thread::id rhs) noexcept;
template<class Char, class Traits>
basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& out, thread::id id)
{
out << id.id_;
return out;
}
template<>
struct hash<thread::id>;
}
#endif
HelenOS homepage, sources at GitHub