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