37 #ifndef FIX8_THREAD_HPP_
38 #define FIX8_THREAD_HPP_
43 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
46 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
55 template<
typename T>
using f8_atomic = std::atomic <T>;
57 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
59 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
67 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
70 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
71 std::unique_ptr<std::thread> _thread;
74 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
76 static void *
_run(
void *what) {
return reinterpret_cast<void *
>((*
static_cast<T *
>(what))()); }
79 static void _run(
void *what) { (*
static_cast<T *
>(what))(); }
86 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
87 return pthread_create(&_tid, &_attr, _run<T>, sub);
88 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
89 _thread.reset(
new std::thread(_run<T>, sub));
97 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
100 if (pthread_attr_init(&_attr))
111 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
112 pthread_attr_destroy(&_attr);
118 virtual int start() = 0;
126 virtual int join(
int timeoutInMs = 0)
128 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
130 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
141 int yield()
const {
return sched_yield(); }
145 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
146 return pthread_yield();
147 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
148 std::this_thread::yield();
159 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
161 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
162 return _thread.get() ? _thread->get_id() : std::thread::id();
170 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
171 return pthread_self();
172 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
173 return std::this_thread::get_id();
182 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
183 return pthread_equal(_tid, that.
_tid);
194 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
195 return !pthread_equal(_tid, that.
_tid);
223 operator bool()
const {
return stop_requested(); }
255 : _what(what), _method(method), _cancellation_token_method(cancellation_token_method) {}
261 const int ret((_what.*_method)());
265 catch(
const std::exception&)
280 f8_thread(std::reference_wrapper<T> what,
int (T::*method)()=&T::operator(),
282 : _sub(what, method, cancellation_token_method) {}
289 int start() {
return _start<_helper>(
static_cast<void *
>(&_sub)); }
298 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
306 if (pthread_mutex_init(&_pmutex, 0))
312 void lock() { pthread_mutex_lock(&_pmutex); }
313 bool try_lock() {
return pthread_mutex_trylock(&_pmutex) == 0; }
314 void unlock() { pthread_mutex_unlock(&_pmutex); }
333 f8_spin_lock() : _isLocked(false) {}
339 while(!__sync_bool_compare_and_swap(&_isLocked,
false,
true))
348 bool try_lock() {
return _isLocked; }
352 while(!__sync_bool_compare_and_swap(&_isLocked,
true,
false))
363 #if (FIX8_THREAD_SYSTEM == FIX8_THREAD_PTHREAD)
371 if (pthread_spin_init(&_psl, PTHREAD_PROCESS_PRIVATE))
377 void lock() { pthread_spin_lock(&_psl); }
378 bool try_lock() {
return pthread_spin_trylock(&_psl) == 0; }
379 void unlock() { pthread_spin_unlock(&_psl); }
381 #elif (FIX8_THREAD_SYSTEM == FIX8_THREAD_STDTHREAD)
382 using f8_mutex = std::mutex;
395 _sl.clear(std::memory_order_relaxed);
398 ~f8_spin_lock() =
default;
400 void lock() {
while (!try_lock()); }
401 bool try_lock() {
return !_sl.test_and_set(std::memory_order_acquire); }
402 void unlock() { _sl.clear(std::memory_order_release); }
410 T *_local_mutex =
nullptr;
411 bool _disabled =
false;
430 _local_mutex = &mutex;
435 bool result(mutex.try_lock());
437 _local_mutex = &mutex;
443 if (!_disabled && _local_mutex)
445 _local_mutex->unlock();
446 _local_mutex =
nullptr;
459 #endif // FIX8_THREAD_HPP_
static thread_id_t getid()
bool try_acquire(T &mutex)
virtual ~_f8_threadcore()
Dtor.
virtual void request_stop()=0
generic pthread_mutex wrapper
_f8_threadcore & operator=(const _f8_threadcore &)=delete
ThreadState
Thread state enumerations.
Thread wrapper. Ctor provides T instance and specifies ptr to member to call or defaults to operator(...
f8_thread_cancellation_token()
ctor
bool stop_requested() const
Thread cancellation token.
virtual ~f8_thread()
Dtor.
_helper(T &what, int(T::*method)(), f8_thread_cancellation_token &(T::*cancellation_token_method)())
virtual int join(int timeoutInMs=0)
f8_scoped_lock_impl(T &mutex)
void thread_state(ThreadState state)
f8_thread(std::reference_wrapper< T > what, int(T::*method)()=&T::operator(), f8_thread_cancellation_token &(T::*cancellation_token_method)()=&T::cancellation_token)
A pthread attribute error occured.
static void * _run(void *what)
std::atomic< T > f8_atomic
generic spin_lock wrapper
f8_atomic< int > _thread_state
pthread wrapper abstract base
bool operator!=(const _f8_threadcore &that) const
bool operator==(const _f8_threadcore &that) const
f8_thread_cancellation_token & cancellation_token()
std::thread::id thread_id_t
f8_scoped_lock_impl(T &mutex, bool disable)
f8_thread_cancellation_token &(T::* _cancellation_token_method)()
thread_id_t get_threadid() const
void request_stop()
Tell the thread to stop.