From a3541b2a243bdf1cc49029b696b217ce752199c7 Mon Sep 17 00:00:00 2001 From: liukangcc Date: Fri, 3 Sep 2021 11:38:48 +0800 Subject: [update] support armclang and c++11. --- components/cplusplus/cpp11/gcc/thread | 239 ++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 components/cplusplus/cpp11/gcc/thread (limited to 'components/cplusplus/cpp11/gcc/thread') diff --git a/components/cplusplus/cpp11/gcc/thread b/components/cplusplus/cpp11/gcc/thread new file mode 100644 index 0000000000..5b64decd6a --- /dev/null +++ b/components/cplusplus/cpp11/gcc/thread @@ -0,0 +1,239 @@ +#pragma once + +#if __cplusplus < 201103L +#error "C++ version lower than C++11" +#endif + +//#if defined(RT_USING_LIBC) && defined(RT_USING_PTHREADS) + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define rt_cpp_thread_t pthread_t +#ifndef PTHREAD_NUM_MAX +#define PTHREAD_NUM_MAX 32 +#endif +#define CPP_UNJOINABLE_THREAD PTHREAD_NUM_MAX + +namespace std +{ + #define __STDCPP_THREADS__ __cplusplus + + + + class thread + { + public: + typedef rt_cpp_thread_t native_handle_type; + + struct invoker_base; + typedef shared_ptr invoker_base_ptr; + + class id + { + // basically a wrapper around native_handle_type + native_handle_type __cpp_thread_t; + + public: + id() noexcept : __cpp_thread_t(CPP_UNJOINABLE_THREAD) {} + + explicit id(native_handle_type hid) + : __cpp_thread_t(hid) {} + private: + friend class thread; + friend class hash; + + friend bool operator==(thread::id x, thread::id y) noexcept; + + friend bool operator<(thread::id x, thread::id y) noexcept; + + template + friend basic_ostream& + operator<<(basic_ostream& out, thread::id id); + }; + + thread() noexcept = default; + thread(const thread&) = delete; + thread& operator=(const thread&) = delete; + ~thread(); + + template + explicit thread(F&& f, Args&&... args) + { + start_thread(make_invoker_ptr(std::bind( + std::forward(f), + std::forward(args)... + ))); + } + + thread(thread&& t) noexcept + { + swap(t); + } + + thread& operator=(thread&& t) noexcept + { + if (joinable()) + terminate(); + swap(t); + return *this; + } + + // member functions + void swap(thread& t) noexcept + { + std::swap(_m_thr, t._m_thr); + } + + bool joinable() const noexcept + { + return (_m_thr.__cpp_thread_t < PTHREAD_NUM_MAX); + } + + void join(); + + void detach(); + + id get_id() const noexcept { return _m_thr; } + + native_handle_type native_handle() { return _m_thr.__cpp_thread_t; } + + // static members + static unsigned hardware_concurrency() noexcept; + + private: + id _m_thr; + + void start_thread(invoker_base_ptr b); + public: + struct invoker_base + { + invoker_base_ptr this_ptr; + + virtual ~invoker_base() = default; + + virtual void invoke() = 0; + }; + + + template + struct invoker : public invoker_base + { + Callable func; + + invoker(Callable&& F) : func(std::forward(F)) { } + + void invoke() { func(); } + }; + + template + shared_ptr> make_invoker_ptr(Callable&& F) + { + return std::make_shared>(std::forward(F)); + } + + + }; + + inline void swap(thread& x, thread& y) noexcept + { + x.swap(y); + } + + + inline bool operator==(thread::id x, thread::id y) noexcept + { + // From POSIX for pthread_equal: + //"If either t1 or t2 are not valid thread IDs, the behavior is undefined." + return x.__cpp_thread_t == y.__cpp_thread_t; + } + + inline bool operator!=(thread::id x, thread::id y) noexcept + { + return !(x == y); + } + + inline bool operator<(thread::id x, thread::id y) noexcept + { + return x.__cpp_thread_t < y.__cpp_thread_t; + } + + inline bool operator<=(thread::id x, thread::id y) noexcept + { + return !(y < x); + } + + inline bool operator>(thread::id x, thread::id y) noexcept + { + return !(x <= y); + } + + inline bool operator>=(thread::id x, thread::id y) noexcept + { + return !(x < y); + } + + template + inline basic_ostream& + operator<<(basic_ostream& out, thread::id id) + { + if (id == thread::id()) // id is invalid, representing no pthread + out << "thread::id of a non-executing thread"; + else + out << id.__cpp_thread_t; + return out; + } + + template <> + struct hash + { + typedef size_t result_type; + typedef thread::id argument_type; + size_t operator()(const thread::id& id) const noexcept + { + return hash()(id.__cpp_thread_t); + } + }; + + namespace this_thread + { + inline thread::id get_id() noexcept + { + return thread::id(pthread_self()); + } + + inline void yield() noexcept + { + sched_yield(); + } + + template + inline void sleep_for(const chrono::duration& rel_time) + { + if (rel_time <= rel_time.zero()) // less than zero, no need to sleep + return; + auto milli_secs = chrono::duration_cast(rel_time); + // the precision is limited by rt-thread thread API + rt_thread_mdelay(milli_secs.count()); + } + + template + inline void sleep_until(const chrono::time_point& abs_time) + { + auto now = Clock::now(); + if (abs_time > now) + sleep_for(abs_time - now); + } + + } +} -- cgit v1.3.1