ECCE @ EIC Software
Reference for
ECCE @ EIC
simulation and reconstruction software on GitHub
Home page
Related Pages
Modules
Namespaces
Classes
Files
External Links
File List
File Members
All
Classes
Namespaces
Files
Functions
Variables
Typedefs
Enumerations
Enumerator
Friends
Macros
Groups
Pages
G4MTBarrier.hh
Go to the documentation of this file.
Or view
the newest version in sPHENIX GitHub for file G4MTBarrier.hh
1
//
2
// ********************************************************************
3
// * License and Disclaimer *
4
// * *
5
// * The Geant4 software is copyright of the Copyright Holders of *
6
// * the Geant4 Collaboration. It is provided under the terms and *
7
// * conditions of the Geant4 Software License, included in the file *
8
// * LICENSE and available at http://cern.ch/geant4/license . These *
9
// * include a list of copyright holders. *
10
// * *
11
// * Neither the authors of this software system, nor their employing *
12
// * institutes,nor the agencies providing financial support for this *
13
// * work make any representation or warranty, express or implied, *
14
// * regarding this software system or assume any liability for its *
15
// * use. Please see the license in the file LICENSE and URL above *
16
// * for the full disclaimer and the limitation of liability. *
17
// * *
18
// * This code implementation is the result of the scientific and *
19
// * technical work of the GEANT4 collaboration. *
20
// * By using, copying, modifying or distributing the software (or *
21
// * any work based on the software) you agree to acknowledge its *
22
// * use in resulting scientific publications, and indicate your *
23
// * acceptance of all terms of the Geant4 Software license. *
24
// ********************************************************************
25
//
26
//
27
// ---------------------------------------------------------------
28
// GEANT 4 class header file
29
//
30
// Class Description:
31
//
32
// This class defines a synchronization point between threads: a master
33
// and a pool of workers.
34
// A barrier is a (shared) instance of this class. Master sets the number
35
// of active threads to wait for, then it waits for workers to become ready
36
// calling the method WaitForReadyWorkers(). The master thread will block on this
37
// call.
38
// Each of the workers calls ThisWorkerReady() when it is ready to continue.
39
// It will block on this call.
40
// When all worker threads have called ThisWorkerReady and are waiting the
41
// master will release the barrier and execution will continue.
42
//
43
// User code can implement more advanced barriers that require exchange
44
// of a message between master and threads inheriting from this class as in:
45
// class Derived : public G4MTBarrier {
46
// G4Mutex mutexForMessage;
47
// SomeType message;
48
// void MethodCalledByWorkers() {
49
// G4MTBarrirer::ThisWorkerReady();
50
// G4AutoLock l(&mutexForMessage);
51
// [... process message ...]
52
// }
53
// void WaitForReadyWorkers() override {
54
// Wait(); <== Mandatory
55
// [.. process message ...] <== User code between the two calls
56
// ReleaseBarrier(); <== Mandatory
57
// }
58
// void MethodCalledByMaster() { WaitForReadyWorkers(); }
59
// }
60
// User code can also achieve the same results as before using the granular
61
// methods LoopWaitingWorkers and ResetCounterAndBroadcast methods in the
62
// master. For examples of usage of this class see G4MTRunManager
63
//
64
// G4MTBarrier.hh
65
//
66
// Created on: Feb 10, 2016
67
// Author: adotti
68
//
69
// =====================================
70
// Barriers mechanism
71
// =====================================
72
// We want to implement barriers.
73
// We define a barrier has a point in which threads synchronize.
74
// When workers threads reach a barrier they wait for the master thread a
75
// signal that they can continue. The master thread broadcast this signal
76
// only when all worker threads have reached this point.
77
// Currently only three points require this sync in the life-time of a G4 applicattion:
78
// Just before and just after the for-loop controlling the thread event-loop.
79
// Between runs.
80
//
81
// The basic algorithm of each barrier works like this:
82
// In the master:
83
// WaitWorkers() {
84
// while (true)
85
// {
86
// G4AutoLock l(&counterMutex); || Mutex is locked (1)
87
// if ( counter == nActiveThreads ) break;
88
// G4CONDITIONWAIT( &conditionOnCounter, &counterMutex); || Mutex is atomically released and wait, upon return locked (2)
89
// } || unlock mutex
90
// G4AutoLock l(&counterMutex); || lock again mutex (3)
91
// G4CONDITIONBROADCAST( &doSomethingCanStart ); || Here mutex is locked (4)
92
// } || final unlock (5)
93
// In the workers:
94
// WaitSignalFromMaster() {
95
// G4AutoLock l(&counterMutex); || (6)
96
// ++counter;
97
// G4CONDITIONBROADCAST(&conditionOnCounter); || (7)
98
// G4CONDITIONWAIT( &doSomethingCanStart , &counterMutex);|| (8)
99
// }
100
// Each barriers requires 2 conditions and one mutex, plus a counter.
101
// Important note: the thread calling broadcast should hold the mutex
102
// before calling broadcast to obtain predictible behavior
103
// http://pubs.opengroup.org/onlinepubs/7908799/xsh/pthread_cond_broadcast.html
104
// Also remember that the wait for condition will atomically release the mutex
105
// and wait on condition, but it will lock again on mutex when returning
106
// Here it is how the control flows.
107
// Imagine master starts and only one worker (nActiveThreads==1)
108
// Master | Worker | counter | Who holds mutex
109
// Gets to (1) | Blocks on (6) | 0 | M
110
// Waits in (2) | | 0 | -
111
// | Arrives to (7) | 1 | W
112
// | Waits in (8) | 1 | -
113
// Gets to (1) | | 1 | M
114
// Jumps to (3) | | 1 | M
115
// End | | 1 | -
116
// | End | 1 | -
117
// Similarly for more than one worker threads or if worker starts
118
119
#ifndef G4MTBARRIER_HH_
120
#define G4MTBARRIER_HH_
121
122
#include "
G4Threading.hh
"
123
124
class
G4MTBarrier
125
{
126
public
:
127
G4MTBarrier
() :
G4MTBarrier
(1) {}
128
virtual
~G4MTBarrier
() {}
129
G4MTBarrier
(
const
G4MTBarrier
&) =
delete
;
130
G4MTBarrier
&
operator=
(
const
G4MTBarrier
&) =
delete
;
131
//on explicitly defaulted move at
132
//https://msdn.microsoft.com/en-us/library/dn457344.aspx
133
//G4MTBarrier(G4MTBarrier&&) = default;
134
//G4MTBarrier& operator=(G4MTBarrier&&) = default;
135
G4MTBarrier
(
unsigned
int
numThreads );
136
void
ThisWorkerReady
();
137
virtual
void
WaitForReadyWorkers
();
138
inline
void
SetActiveThreads
(
unsigned
int
val ) {
m_numActiveThreads
= val; }
139
void
ResetCounter
();
140
unsigned
int
GetCounter
();
141
void
Wait
();
142
void
ReleaseBarrier
();
143
inline
void
Wait
(
unsigned
int
numt ) {
144
SetActiveThreads
( numt );
145
Wait
();
146
}
147
private
:
148
unsigned
int
m_numActiveThreads
;
149
unsigned
int
m_counter
;
150
G4Mutex
m_mutex
;
151
G4Condition
m_counterChanged
;
152
G4Condition
m_continue
;
153
};
154
155
#endif
/* G4MTBARRIER_HH_ */
geant4
tree
geant4-10.6-release
source
global
management
include
G4MTBarrier.hh
Built by
Jin Huang
. updated:
Wed Jun 29 2022 17:25:21
using
1.8.2 with
ECCE GitHub integration