Arcane  v4.1.7.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-2026 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-2026 */
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() = default;
50
51 public:
52
53 void init(Integer nb_thread) override
54 {
55 m_nb_thread = nb_thread;
56 m_current_reached = 0;
57 m_wait_mutex = new GlibMutex();
58 m_wait = new GlibCond();
59 }
60
61 void destroy() override
62 {
63 m_nb_thread = 0;
64 m_current_reached = 0;
65 delete m_wait_mutex;
66 delete m_wait;
67 delete this;
68 }
69
70 void wait() override
71 {
72 m_wait_mutex->lock();
73 ++m_current_reached;
74 //cout << "ADD BARRIER N=" << m_current_reached << '\n';
75 if (m_current_reached == m_nb_thread) {
76 m_current_reached = 0;
77 //cout << "BROADCAST BARRIER N=" << m_current_reached << '\n';
78 m_wait->broadcast();
79 }
80 else
81 m_wait->wait(m_wait_mutex);
82 m_wait_mutex->unlock();
83 }
84
85 private:
86
87 GlibMutex* m_wait_mutex = nullptr;
88 GlibCond* m_wait = nullptr;
89 Int32 m_nb_thread = 0;
90 Int32 m_current_reached = 0;
91};
92
93/*---------------------------------------------------------------------------*/
94/*---------------------------------------------------------------------------*/
95
96extern "C" ARCCORE_CONCURRENCY_EXPORT IThreadBarrier*
97createGlibThreadBarrier()
98{
99 return new GlibThreadBarrier();
100}
101
102/*---------------------------------------------------------------------------*/
103/*---------------------------------------------------------------------------*/
104
105GlibThreadImplementation::
106GlibThreadImplementation()
107: m_global_mutex_impl(nullptr)
108{
109}
110
111GlibThreadImplementation::
112~GlibThreadImplementation()
113{
114 GlobalMutex::destroy();
115 if (m_global_mutex_impl)
116 destroyMutex(m_global_mutex_impl);
117}
118
119void GlibThreadImplementation::
120initialize()
121{
122 m_global_mutex_impl = createMutex();
123 GlobalMutex::init(m_global_mutex_impl);
124}
125
126ThreadImpl* GlibThreadImplementation::
127createThread(IFunctor* f)
128{
129 return reinterpret_cast<ThreadImpl*>(g_thread_new(nullptr, &_GlibStartFunc, f));
130}
131
132void GlibThreadImplementation::
133joinThread(ThreadImpl* t)
134{
135 GThread* tt = reinterpret_cast<GThread*>(t);
136 g_thread_join(tt);
137}
138
139void GlibThreadImplementation::
140destroyThread(ThreadImpl* t)
141{
142 ARCCORE_UNUSED(t);
143}
144
145void GlibThreadImplementation::
146createSpinLock(Int64* spin_lock_addr)
147{
148 volatile gint* v = (gint*)spin_lock_addr;
149 g_bit_unlock(v, 0);
150}
151
152void GlibThreadImplementation::
153lockSpinLock(Int64* spin_lock_addr, Int64* scoped_spin_lock_addr)
154{
155 ARCCORE_UNUSED(scoped_spin_lock_addr);
156
157 volatile gint* v = (gint*)spin_lock_addr;
158 if (!g_bit_trylock(v, 0)) {
159 do {
160 //TODO: Faire Pause
161 } while (!g_bit_trylock(v, 0));
162 }
163}
164
165void GlibThreadImplementation::
166unlockSpinLock(Int64* spin_lock_addr, Int64* scoped_spin_lock_addr)
167{
168 ARCCORE_UNUSED(scoped_spin_lock_addr);
169
170 volatile gint* v = (gint*)spin_lock_addr;
171 g_bit_unlock(v, 0);
172}
173
174MutexImpl* GlibThreadImplementation::
175createMutex()
176{
177 GlibMutex* m = new GlibMutex();
178 return reinterpret_cast<MutexImpl*>(m);
179}
180
181void GlibThreadImplementation::
182destroyMutex(MutexImpl* mutex)
183{
184 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
185 delete m;
186}
187
188void GlibThreadImplementation::
189lockMutex(MutexImpl* mutex)
190{
191 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
192 m->lock();
193}
194
195void GlibThreadImplementation::
196unlockMutex(MutexImpl* mutex)
197{
198 GlibMutex* m = reinterpret_cast<GlibMutex*>(mutex);
199 m->unlock();
200}
201
202Int64 GlibThreadImplementation::
203currentThread()
204{
205 Int64 v = reinterpret_cast<Int64>(g_thread_self());
206 return v;
207}
208
209IThreadBarrier* GlibThreadImplementation::
210createBarrier()
211{
212 return new GlibThreadBarrier();
213}
214
215/*---------------------------------------------------------------------------*/
216/*---------------------------------------------------------------------------*/
217
218} // namespace Arcane
219
220/*---------------------------------------------------------------------------*/
221/*---------------------------------------------------------------------------*/
void init(Integer nb_thread) override
Initialise la barrière pour nb_thread.
void wait() override
Bloque et attend que tous les threads appellent cette méthode.
void destroy() override
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.
std::int32_t Int32
Type entier signé sur 32 bits.