Arcane  v3.16.0.0
Documentation utilisateur
Chargement...
Recherche...
Aucune correspondance
GlibThreadImplementation.cc
1// -*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
2//-----------------------------------------------------------------------------
3// Copyright 2000-2025 CEA (www.cea.fr) IFPEN (www.ifpenergiesnouvelles.com)
4// See the top-level COPYRIGHT file for details.
5// SPDX-License-Identifier: Apache-2.0
6//-----------------------------------------------------------------------------
7/*---------------------------------------------------------------------------*/
8/* GlibThreadImplementation.cc (C) 2000-2025 */
9/* */
10/* Implémentation des threads utilisant la glib. */
11/*---------------------------------------------------------------------------*/
12/*---------------------------------------------------------------------------*/
13
14#include "arccore/base/NotImplementedException.h"
15#include "arccore/base/IFunctor.h"
16
17#include "arccore/concurrency/GlibThreadImplementation.h"
18#include "arccore/concurrency/IThreadBarrier.h"
19#include "arccore/concurrency/Mutex.h"
20#include "arccore/concurrency/GlibAdapter.h"
21
22#include <new>
23#include <glib.h>
24
25/*---------------------------------------------------------------------------*/
26/*---------------------------------------------------------------------------*/
27
28namespace Arcane
29{
30
31/*---------------------------------------------------------------------------*/
32/*---------------------------------------------------------------------------*/
33
34static void* _GlibStartFunc(void* f)
35{
36 IFunctor* ff = reinterpret_cast<IFunctor*>(f);
37 ff->executeFunctor();
38 return 0;
39}
40
41/*---------------------------------------------------------------------------*/
42/*---------------------------------------------------------------------------*/
43
44class GlibThreadBarrier
45: public IThreadBarrier
46{
47 public:
48
49 GlibThreadBarrier()
50 : m_wait_mutex(nullptr)
51 , m_wait(nullptr)
52 , m_nb_thread(0)
53 , m_current_reached(0)
54 {}
55
56 public:
57
58 virtual void init(Integer nb_thread)
59 {
60 m_nb_thread = nb_thread;
61 m_current_reached = 0;
62 m_wait_mutex = new GlibMutex();
63 m_wait = new GlibCond();
64 }
65
66 virtual void destroy()
67 {
68 m_nb_thread = 0;
69 m_current_reached = 0;
70 delete m_wait_mutex;
71 delete m_wait;
72 delete this;
73 }
74
75 virtual bool wait()
76 {
77 bool is_last = false;
78 m_wait_mutex->lock();
79 ++m_current_reached;
80 //cout << "ADD BARRIER N=" << m_current_reached << '\n';
81 if (m_current_reached == m_nb_thread) {
82 m_current_reached = 0;
83 is_last = true;
84 //cout << "BROADCAST BARRIER N=" << m_current_reached << '\n';
85 m_wait->broadcast();
86 }
87 else
88 m_wait->wait(m_wait_mutex);
89 m_wait_mutex->unlock();
90 return is_last;
91 }
92
93 private:
94
95 GlibMutex* m_wait_mutex;
96 GlibCond* m_wait;
97 Integer m_nb_thread;
98 Integer m_current_reached;
99};
100
101/*---------------------------------------------------------------------------*/
102/*---------------------------------------------------------------------------*/
103
104extern "C" ARCCORE_CONCURRENCY_EXPORT IThreadBarrier*
105createGlibThreadBarrier()
106{
107 return new GlibThreadBarrier();
108}
109
110/*---------------------------------------------------------------------------*/
111/*---------------------------------------------------------------------------*/
112
113GlibThreadImplementation::
114GlibThreadImplementation()
115: m_global_mutex_impl(nullptr)
116{
117}
118
119GlibThreadImplementation::
120~GlibThreadImplementation()
121{
122 GlobalMutex::destroy();
123 if (m_global_mutex_impl)
124 destroyMutex(m_global_mutex_impl);
125}
126
127void GlibThreadImplementation::
128initialize()
129{
130 m_global_mutex_impl = createMutex();
131 GlobalMutex::init(m_global_mutex_impl);
132}
133
134ThreadImpl* GlibThreadImplementation::
135createThread(IFunctor* f)
136{
137 return reinterpret_cast<ThreadImpl*>(g_thread_new(nullptr, &_GlibStartFunc, f));
138}
139
140void GlibThreadImplementation::
141joinThread(ThreadImpl* t)
142{
143 GThread* tt = reinterpret_cast<GThread*>(t);
144 g_thread_join(tt);
145}
146
147void GlibThreadImplementation::
148destroyThread(ThreadImpl* t)
149{
150 ARCCORE_UNUSED(t);
151}
152
153void GlibThreadImplementation::
154createSpinLock(Int64* spin_lock_addr)
155{
156 volatile gint* v = (gint*)spin_lock_addr;
157 g_bit_unlock(v, 0);
158}
159
160void GlibThreadImplementation::
161lockSpinLock(Int64* spin_lock_addr, Int64* scoped_spin_lock_addr)
162{
163 ARCCORE_UNUSED(scoped_spin_lock_addr);
164
165 volatile gint* v = (gint*)spin_lock_addr;
166 if (!g_bit_trylock(v, 0)) {
167 do {
168 //TODO: Faire Pause
169 } while (!g_bit_trylock(v, 0));
170 }
171}
172
173void GlibThreadImplementation::
174unlockSpinLock(Int64* spin_lock_addr, Int64* scoped_spin_lock_addr)
175{
176 ARCCORE_UNUSED(scoped_spin_lock_addr);
177
178 volatile gint* v = (gint*)spin_lock_addr;
179 g_bit_unlock(v, 0);
180}
181
182MutexImpl* GlibThreadImplementation::
183createMutex()
184{
185 GlibMutex* m = new GlibMutex();
186 return reinterpret_cast<MutexImpl*>(m);
187}
188
189void GlibThreadImplementation::
190destroyMutex(MutexImpl* mutex)
191{
192 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
193 delete m;
194}
195
196void GlibThreadImplementation::
197lockMutex(MutexImpl* mutex)
198{
199 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
200 m->lock();
201}
202
203void GlibThreadImplementation::
204unlockMutex(MutexImpl* mutex)
205{
206 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
207 m->unlock();
208}
209
210Int64 GlibThreadImplementation::
211currentThread()
212{
213 Int64 v = reinterpret_cast<Int64>(g_thread_self());
214 return v;
215}
216
217IThreadBarrier* GlibThreadImplementation::
218createBarrier()
219{
220 return new GlibThreadBarrier();
221}
222
223/*---------------------------------------------------------------------------*/
224/*---------------------------------------------------------------------------*/
225
226} // namespace Arcane
227
228/*---------------------------------------------------------------------------*/
229/*---------------------------------------------------------------------------*/
virtual void init(Integer nb_thread)
Initialise la barrière pour nb_thread.
virtual bool wait()
Bloque et attend que tous les threads appellent cette méthode.
virtual void destroy()
Détruit la barrière.
static void init(MutexImpl *p)
Initialise le mutex global. Interne a Arccore. Doit être alloué par new.
Definition Mutex.cc:60
virtual void executeFunctor()=0
Exécute la méthode associé
-*- tab-width: 2; indent-tabs-mode: nil; coding: utf-8-with-signature -*-
std::int64_t Int64
Type entier signé sur 64 bits.
Int32 Integer
Type représentant un entier.