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
39typedef std::thread::id ThreadId;
40typedef std::thread ThreadType;
45inline Int64 arcaneGetThisThreadId()
47 Int64 v =
static_cast<Int64>(std::hash<std::thread::id>{}(std::this_thread::get_id()));
77 TBBBarrier() =
default;
83 m_nb_thread = nb_thread;
84 m_nb_thread_finished = 0;
90 Int32 ts = m_timestamp;
91 int remaining_thread = m_nb_thread - m_nb_thread_finished.fetch_add(1) - 1;
92 if (remaining_thread > 0) {
95 while (m_timestamp==ts){
109 m_nb_thread_finished = 0;
115 Int32 m_nb_thread = 0;
116 std::atomic<Int32> m_nb_thread_finished = 0;
117 std::atomic<Int32> m_timestamp = 0;
123extern "C" IThreadBarrier*
124createGlibThreadBarrier();
131class TBBThreadImplementation
135 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
137 void addReference()
override { ReferenceCounterImpl::addReference(); }
138 void removeReference()
override { ReferenceCounterImpl::removeReference(); }
149 void operator()()
const { m_f->executeFunctor(); }
155 TBBThreadImplementation()
158 m_use_tbb_barrier =
true;
159 m_std_thread_implementation = Arccore::Concurrency::createStdThreadImplementation();
165 GlobalMutex::destroy();
166 if (m_global_mutex_impl)
167 this->destroyMutex(m_global_mutex_impl);
176 void initialize()
override
178 m_global_mutex_impl = createMutex();
184 ThreadImpl* createThread(IFunctor* f)
override
186 return reinterpret_cast<ThreadImpl*
>(
new ThreadType(
StartFunc(f)));
188 void joinThread(ThreadImpl* t)
override
190 auto* tt =
reinterpret_cast<ThreadType*
>(t);
193 void destroyThread(ThreadImpl* t)
override
195 auto* tt =
reinterpret_cast<ThreadType*
>(t);
199 void createSpinLock(
Int64* spin_lock_addr)
override
201 void* addr = spin_lock_addr;
202 new (addr) tbb::spin_mutex();
204 void lockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
206 auto* s =
reinterpret_cast<tbb::spin_mutex*
>(spin_lock_addr);
207 auto* sl =
new (scoped_spin_lock_addr) tbb::spin_mutex::scoped_lock();
210 void unlockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
212 ARCANE_UNUSED(spin_lock_addr);
213 auto* s =
reinterpret_cast<tbb::spin_mutex::scoped_lock*
>(scoped_spin_lock_addr);
218 MutexImpl* createMutex()
override
220 auto* m =
new TBBMutexImpl();
221 return reinterpret_cast<MutexImpl*
>(m);
223 void destroyMutex(MutexImpl* mutex)
override
225 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
228 void lockMutex(MutexImpl* mutex)
override
230 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
233 void unlockMutex(MutexImpl* mutex)
override
235 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
239 Int64 currentThread()
override
241 Int64 v = arcaneGetThisThreadId();
245 IThreadBarrier* createBarrier()
override
251 if (m_use_tbb_barrier)
252 return new TBBBarrier();
253 return m_std_thread_implementation->createBarrier();
258 bool m_use_tbb_barrier =
false;
259 MutexImpl* m_global_mutex_impl =
nullptr;
260 Ref<IThreadImplementation> m_std_thread_implementation;
266class TBBThreadImplementationService
271 TBBThreadImplementationService() =
default;
287 DependencyInjection::ProviderProperty(
"TBBThreadImplementationService"),
289 ARCANE_DI_EMPTY_CONSTRUCTOR());
static void init(MutexImpl *p)
Initialise le mutex global. Interne a Arccore. Doit être alloué par new.
Interface d'une barrière entre threads.
Interface d'un service de gestion des threads.
Interface d'un service implémentant le support des threads.
Référence à une instance.
Implémentation thread-safe d'un compteur de référence.
void destroy() override
Détruit la barrière.
void init(Integer nb_thread) override
Initialise la barrière pour nb_thread.
bool wait() override
Bloque et attend que tous les threads appellent cette méthode.
Implémentation des threads utilisant TBB (Intel Threads Building Blocks).
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
void arcaneDoCPUPause(Int32 count)
Utilise l'instruction 'pause' du CPU si possible.
Int32 Integer
Type représentant un entier.
auto makeRef(InstanceType *t) -> Ref< InstanceType >
Créé une référence sur un pointeur.
std::int32_t Int32
Type entier signé sur 32 bits.