14#include "arcane/utils/IThreadImplementationService.h"
15#include "arcane/utils/IThreadBarrier.h"
16#include "arcane/utils/NotImplementedException.h"
17#include "arcane/utils/IFunctor.h"
18#include "arcane/utils/Mutex.h"
19#include "arcane/utils/PlatformUtils.h"
20#include "arccore/base/internal/DependencyInjection.h"
22#include "arcane/parallel/thread/ArcaneThreadMisc.h"
25#define ARCANE_TBB_USE_STDTHREAD
44typedef std::thread::id ThreadId;
45typedef std::thread ThreadType;
50inline Int64 arcaneGetThisThreadId()
52 Int64 v =
static_cast<Int64>(std::hash<std::thread::id>{}(std::this_thread::get_id()));
85 TBBBarrier() =
default;
91 m_nb_thread = nb_thread;
92 m_nb_thread_finished = 0;
98 Int32 ts = m_timestamp;
99 int remaining_thread = m_nb_thread - m_nb_thread_finished.fetch_add(1) - 1;
100 if (remaining_thread > 0) {
103 while (m_timestamp == ts) {
115 m_nb_thread_finished = 0;
121 Int32 m_nb_thread = 0;
122 std::atomic<Int32> m_nb_thread_finished = 0;
123 std::atomic<Int32> m_timestamp = 0;
129extern "C" IThreadBarrier*
130createGlibThreadBarrier();
138class TBBThreadImplementation
144 void addReference()
override { ReferenceCounterImpl::addReference(); }
145 void removeReference()
override { ReferenceCounterImpl::removeReference(); }
156 void operator()()
const { m_f->executeFunctor(); }
162 TBBThreadImplementation()
165 m_use_tbb_barrier =
true;
166 m_std_thread_implementation = Arccore::Concurrency::createStdThreadImplementation();
172 GlobalMutex::destroy();
173 if (m_global_mutex_impl)
174 this->destroyMutex(m_global_mutex_impl);
183 void initialize()
override
185 m_global_mutex_impl = createMutex();
191 ThreadImpl* createThread(IFunctor* f)
override
193 return reinterpret_cast<ThreadImpl*
>(
new ThreadType(
StartFunc(f)));
195 void joinThread(ThreadImpl* t)
override
197 auto* tt =
reinterpret_cast<ThreadType*
>(t);
200 void destroyThread(ThreadImpl* t)
override
202 auto* tt =
reinterpret_cast<ThreadType*
>(t);
206 void createSpinLock(
Int64* spin_lock_addr)
override
208 void* addr = spin_lock_addr;
209 new (addr) tbb::spin_mutex();
211 void lockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
213 auto* s =
reinterpret_cast<tbb::spin_mutex*
>(spin_lock_addr);
214 auto* sl =
new (scoped_spin_lock_addr) tbb::spin_mutex::scoped_lock();
217 void unlockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
219 ARCANE_UNUSED(spin_lock_addr);
220 auto* s =
reinterpret_cast<tbb::spin_mutex::scoped_lock*
>(scoped_spin_lock_addr);
225 MutexImpl* createMutex()
override
227 auto* m =
new TBBMutexImpl();
228 return reinterpret_cast<MutexImpl*
>(m);
230 void destroyMutex(MutexImpl* mutex)
override
232 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
235 void lockMutex(MutexImpl* mutex)
override
237 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
240 void unlockMutex(MutexImpl* mutex)
override
242 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
246 Int64 currentThread()
override
248 Int64 v = arcaneGetThisThreadId();
252 IThreadBarrier* createBarrier()
override
258 if (m_use_tbb_barrier)
259 return new TBBBarrier();
260 return m_std_thread_implementation->createBarrier();
265 bool m_use_tbb_barrier =
false;
266 MutexImpl* m_global_mutex_impl =
nullptr;
267 Ref<IThreadImplementation> m_std_thread_implementation;
273class TBBThreadImplementationService
278 TBBThreadImplementationService() =
default;
296 DependencyInjection::ProviderProperty(
"TBBThreadImplementationService"),
298 ARCANE_DI_EMPTY_CONSTRUCTOR());
#define ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS()
Macro to define methods managing counters of references.
static void init(MutexImpl *p)
Initializes the global mutex. Internal to Arccore. Must be allocated by new.
Interface of a barrier between threads.
Interface of a thread management service.
Interface of a service implementing thread support.
Reference to an instance.
Thread-safe implementation of a reference counter.
void destroy() override
Destroys the barrier.
void wait() override
Blocks and waits until all threads call this method.
void init(Integer nb_thread) override
Initializes the barrier for nb_thread.
Implementation of threads using TBB (Intel Threads Building Blocks).
-- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature --
std::int64_t Int64
Signed integer type of 64 bits.
void arcaneDoCPUPause(Int32 count)
Uses the CPU 'pause' instruction if possible.
Int32 Integer
Type representing an integer.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Creates a reference on a pointer.
std::int32_t Int32
Signed integer type of 32 bits.