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){
114 m_nb_thread_finished = 0;
120 Int32 m_nb_thread = 0;
121 std::atomic<Int32> m_nb_thread_finished = 0;
122 std::atomic<Int32> m_timestamp = 0;
128extern "C" IThreadBarrier*
129createGlibThreadBarrier();
136class TBBThreadImplementation
140 ARCCORE_DEFINE_REFERENCE_COUNTED_INCLASS_METHODS();
142 void addReference()
override { ReferenceCounterImpl::addReference(); }
143 void removeReference()
override { ReferenceCounterImpl::removeReference(); }
154 void operator()()
const { m_f->executeFunctor(); }
160 TBBThreadImplementation()
163 m_use_tbb_barrier =
true;
164 m_std_thread_implementation = Arccore::Concurrency::createStdThreadImplementation();
170 GlobalMutex::destroy();
171 if (m_global_mutex_impl)
172 this->destroyMutex(m_global_mutex_impl);
181 void initialize()
override
183 m_global_mutex_impl = createMutex();
189 ThreadImpl* createThread(IFunctor* f)
override
191 return reinterpret_cast<ThreadImpl*
>(
new ThreadType(
StartFunc(f)));
193 void joinThread(ThreadImpl* t)
override
195 auto* tt =
reinterpret_cast<ThreadType*
>(t);
198 void destroyThread(ThreadImpl* t)
override
200 auto* tt =
reinterpret_cast<ThreadType*
>(t);
204 void createSpinLock(
Int64* spin_lock_addr)
override
206 void* addr = spin_lock_addr;
207 new (addr) tbb::spin_mutex();
209 void lockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
211 auto* s =
reinterpret_cast<tbb::spin_mutex*
>(spin_lock_addr);
212 auto* sl =
new (scoped_spin_lock_addr) tbb::spin_mutex::scoped_lock();
215 void unlockSpinLock(
Int64* spin_lock_addr,
Int64* scoped_spin_lock_addr)
override
217 ARCANE_UNUSED(spin_lock_addr);
218 auto* s =
reinterpret_cast<tbb::spin_mutex::scoped_lock*
>(scoped_spin_lock_addr);
223 MutexImpl* createMutex()
override
225 auto* m =
new TBBMutexImpl();
226 return reinterpret_cast<MutexImpl*
>(m);
228 void destroyMutex(MutexImpl* mutex)
override
230 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
233 void lockMutex(MutexImpl* mutex)
override
235 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
238 void unlockMutex(MutexImpl* mutex)
override
240 auto* tm =
reinterpret_cast<TBBMutexImpl*
>(mutex);
244 Int64 currentThread()
override
246 Int64 v = arcaneGetThisThreadId();
250 IThreadBarrier* createBarrier()
override
256 if (m_use_tbb_barrier)
257 return new TBBBarrier();
258 return m_std_thread_implementation->createBarrier();
263 bool m_use_tbb_barrier =
false;
264 MutexImpl* m_global_mutex_impl =
nullptr;
265 Ref<IThreadImplementation> m_std_thread_implementation;
271class TBBThreadImplementationService
276 TBBThreadImplementationService() =
default;
292 DependencyInjection::ProviderProperty(
"TBBThreadImplementationService"),
294 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.