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()));
82 TBBBarrier() =
default;
88 m_nb_thread = nb_thread;
89 m_nb_thread_finished = 0;
95 Int32 ts = m_timestamp;
96 int remaining_thread = m_nb_thread - m_nb_thread_finished.fetch_add(1) - 1;
97 if (remaining_thread > 0) {
100 while (m_timestamp==ts){
112 m_nb_thread_finished = 0;
118 Int32 m_nb_thread = 0;
119 std::atomic<Int32> m_nb_thread_finished = 0;
120 std::atomic<Int32> m_timestamp = 0;
126extern "C" IThreadBarrier*
127createGlibThreadBarrier();
134class TBBThreadImplementation
138 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
140 void addReference()
override { ReferenceCounterImpl::addReference(); }
141 void removeReference()
override { ReferenceCounterImpl::removeReference(); }
152 void operator()()
const { m_f->executeFunctor(); }
158 TBBThreadImplementation()
161 m_use_tbb_barrier =
true;
162 m_std_thread_implementation = Arccore::Concurrency::createStdThreadImplementation();
168 GlobalMutex::destroy();
169 if (m_global_mutex_impl)
170 this->destroyMutex(m_global_mutex_impl);
179 void initialize()
override
181 m_global_mutex_impl = createMutex();
187 ThreadImpl* createThread(IFunctor* f)
override
189 return reinterpret_cast<ThreadImpl*
>(
new ThreadType(
StartFunc(f)));
191 void joinThread(ThreadImpl* t)
override
193 auto* tt =
reinterpret_cast<ThreadType*
>(t);
196 void destroyThread(ThreadImpl* t)
override
198 auto* tt =
reinterpret_cast<ThreadType*
>(t);
202 void createSpinLock(
Int64* spin_lock_addr)
override
204 void* addr = spin_lock_addr;
205 new (addr) tbb::spin_mutex();
207 void lockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
209 auto* s =
reinterpret_cast<tbb::spin_mutex*
>(spin_lock_addr);
210 auto* sl =
new (scoped_spin_lock_addr) tbb::spin_mutex::scoped_lock();
213 void unlockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
215 ARCANE_UNUSED(spin_lock_addr);
216 auto* s =
reinterpret_cast<tbb::spin_mutex::scoped_lock*
>(scoped_spin_lock_addr);
221 MutexImpl* createMutex()
override
223 auto* m =
new TBBMutexImpl();
224 return reinterpret_cast<MutexImpl*
>(m);
226 void destroyMutex(MutexImpl* mutex)
override
228 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
231 void lockMutex(MutexImpl* mutex)
override
233 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
236 void unlockMutex(MutexImpl* mutex)
override
238 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
242 Int64 currentThread()
override
244 Int64 v = arcaneGetThisThreadId();
248 IThreadBarrier* createBarrier()
override
254 if (m_use_tbb_barrier)
255 return new TBBBarrier();
256 return m_std_thread_implementation->createBarrier();
261 bool m_use_tbb_barrier =
false;
262 MutexImpl* m_global_mutex_impl =
nullptr;
263 Ref<IThreadImplementation> m_std_thread_implementation;
269class TBBThreadImplementationService
274 TBBThreadImplementationService() =
default;
290 DependencyInjection::ProviderProperty(
"TBBThreadImplementationService"),
292 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 wait() override
Bloque et attend que tous les threads appellent cette méthode.
void init(Integer nb_thread) override
Initialise la barrière pour nb_thread.
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.