PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
barrier.c File Reference
#include "postgres.h"
#include "storage/barrier.h"
Include dependency graph for barrier.c:

Go to the source code of this file.

Functions

static bool BarrierDetachImpl (Barrier *barrier, bool arrive)
 
void BarrierInit (Barrier *barrier, int participants)
 
bool BarrierArriveAndWait (Barrier *barrier, uint32 wait_event_info)
 
bool BarrierArriveAndDetach (Barrier *barrier)
 
bool BarrierArriveAndDetachExceptLast (Barrier *barrier)
 
int BarrierAttach (Barrier *barrier)
 
bool BarrierDetach (Barrier *barrier)
 
int BarrierPhase (Barrier *barrier)
 
int BarrierParticipants (Barrier *barrier)
 

Function Documentation

◆ BarrierArriveAndDetach()

bool BarrierArriveAndDetach ( Barrier barrier)

Definition at line 203 of file barrier.c.

204{
205 return BarrierDetachImpl(barrier, true);
206}
static bool BarrierDetachImpl(Barrier *barrier, bool arrive)
Definition: barrier.c:300
static THREAD_BARRIER_T barrier
Definition: pgbench.c:480

References barrier, and BarrierDetachImpl().

Referenced by ExecHashTableDetach(), and ExecHashTableDetachBatch().

◆ BarrierArriveAndDetachExceptLast()

bool BarrierArriveAndDetachExceptLast ( Barrier barrier)

Definition at line 213 of file barrier.c.

214{
215 SpinLockAcquire(&barrier->mutex);
216 if (barrier->participants > 1)
217 {
218 --barrier->participants;
219 SpinLockRelease(&barrier->mutex);
220
221 return false;
222 }
223 Assert(barrier->participants == 1);
224 ++barrier->phase;
225 SpinLockRelease(&barrier->mutex);
226
227 return true;
228}
#define Assert(condition)
Definition: c.h:812
#define SpinLockRelease(lock)
Definition: spin.h:61
#define SpinLockAcquire(lock)
Definition: spin.h:59

References Assert, barrier, SpinLockAcquire, and SpinLockRelease.

Referenced by ExecHashTableDetachBatch(), and ExecParallelPrepHashTableForUnmatched().

◆ BarrierArriveAndWait()

bool BarrierArriveAndWait ( Barrier barrier,
uint32  wait_event_info 
)

Definition at line 125 of file barrier.c.

126{
127 bool release = false;
128 bool elected;
129 int start_phase;
130 int next_phase;
131
132 SpinLockAcquire(&barrier->mutex);
133 start_phase = barrier->phase;
134 next_phase = start_phase + 1;
135 ++barrier->arrived;
136 if (barrier->arrived == barrier->participants)
137 {
138 release = true;
139 barrier->arrived = 0;
140 barrier->phase = next_phase;
141 barrier->elected = next_phase;
142 }
143 SpinLockRelease(&barrier->mutex);
144
145 /*
146 * If we were the last expected participant to arrive, we can release our
147 * peers and return true to indicate that this backend has been elected to
148 * perform any serial work.
149 */
150 if (release)
151 {
152 ConditionVariableBroadcast(&barrier->condition_variable);
153
154 return true;
155 }
156
157 /*
158 * Otherwise we have to wait for the last participant to arrive and
159 * advance the phase.
160 */
161 elected = false;
162 ConditionVariablePrepareToSleep(&barrier->condition_variable);
163 for (;;)
164 {
165 /*
166 * We know that phase must either be start_phase, indicating that we
167 * need to keep waiting, or next_phase, indicating that the last
168 * participant that we were waiting for has either arrived or detached
169 * so that the next phase has begun. The phase cannot advance any
170 * further than that without this backend's participation, because
171 * this backend is attached.
172 */
173 SpinLockAcquire(&barrier->mutex);
174 Assert(barrier->phase == start_phase || barrier->phase == next_phase);
175 release = barrier->phase == next_phase;
176 if (release && barrier->elected != next_phase)
177 {
178 /*
179 * Usually the backend that arrives last and releases the other
180 * backends is elected to return true (see above), so that it can
181 * begin processing serial work while it has a CPU timeslice.
182 * However, if the barrier advanced because someone detached, then
183 * one of the backends that is awoken will need to be elected.
184 */
185 barrier->elected = barrier->phase;
186 elected = true;
187 }
188 SpinLockRelease(&barrier->mutex);
189 if (release)
190 break;
191 ConditionVariableSleep(&barrier->condition_variable, wait_event_info);
192 }
194
195 return elected;
196}
bool ConditionVariableCancelSleep(void)
void ConditionVariableBroadcast(ConditionVariable *cv)
void ConditionVariablePrepareToSleep(ConditionVariable *cv)
void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)

References Assert, barrier, ConditionVariableBroadcast(), ConditionVariableCancelSleep(), ConditionVariablePrepareToSleep(), ConditionVariableSleep(), SpinLockAcquire, and SpinLockRelease.

Referenced by ExecHashJoinImpl(), ExecHashTableCreate(), ExecParallelHashIncreaseNumBatches(), ExecParallelHashIncreaseNumBuckets(), ExecParallelHashJoinNewBatch(), ExecParallelHashJoinSetUpBatches(), and MultiExecParallelHash().

◆ BarrierAttach()

int BarrierAttach ( Barrier barrier)

Definition at line 236 of file barrier.c.

237{
238 int phase;
239
240 Assert(!barrier->static_party);
241
242 SpinLockAcquire(&barrier->mutex);
243 ++barrier->participants;
244 phase = barrier->phase;
245 SpinLockRelease(&barrier->mutex);
246
247 return phase;
248}

References Assert, barrier, SpinLockAcquire, and SpinLockRelease.

Referenced by ExecHashTableCreate(), ExecParallelHashJoinNewBatch(), ExecParallelHashJoinSetUpBatches(), and MultiExecParallelHash().

◆ BarrierDetach()

bool BarrierDetach ( Barrier barrier)

Definition at line 256 of file barrier.c.

257{
258 return BarrierDetachImpl(barrier, false);
259}

References barrier, and BarrierDetachImpl().

Referenced by ExecParallelHashJoinNewBatch(), ExecParallelHashJoinSetUpBatches(), and MultiExecParallelHash().

◆ BarrierDetachImpl()

static bool BarrierDetachImpl ( Barrier barrier,
bool  arrive 
)
inlinestatic

Definition at line 300 of file barrier.c.

301{
302 bool release;
303 bool last;
304
305 Assert(!barrier->static_party);
306
307 SpinLockAcquire(&barrier->mutex);
308 Assert(barrier->participants > 0);
309 --barrier->participants;
310
311 /*
312 * If any other participants are waiting and we were the last participant
313 * waited for, release them. If no other participants are waiting, but
314 * this is a BarrierArriveAndDetach() call, then advance the phase too.
315 */
316 if ((arrive || barrier->participants > 0) &&
317 barrier->arrived == barrier->participants)
318 {
319 release = true;
320 barrier->arrived = 0;
321 ++barrier->phase;
322 }
323 else
324 release = false;
325
326 last = barrier->participants == 0;
327 SpinLockRelease(&barrier->mutex);
328
329 if (release)
330 ConditionVariableBroadcast(&barrier->condition_variable);
331
332 return last;
333}

References Assert, barrier, ConditionVariableBroadcast(), SpinLockAcquire, and SpinLockRelease.

Referenced by BarrierArriveAndDetach(), and BarrierDetach().

◆ BarrierInit()

void BarrierInit ( Barrier barrier,
int  participants 
)

Definition at line 100 of file barrier.c.

101{
102 SpinLockInit(&barrier->mutex);
103 barrier->participants = participants;
104 barrier->arrived = 0;
105 barrier->phase = 0;
106 barrier->elected = 0;
107 barrier->static_party = participants > 0;
108 ConditionVariableInit(&barrier->condition_variable);
109}
void ConditionVariableInit(ConditionVariable *cv)
#define SpinLockInit(lock)
Definition: spin.h:57

References barrier, ConditionVariableInit(), and SpinLockInit.

Referenced by ExecHashJoinInitializeDSM(), ExecHashJoinReInitializeDSM(), and ExecParallelHashJoinSetUpBatches().

◆ BarrierParticipants()

int BarrierParticipants ( Barrier barrier)

Definition at line 281 of file barrier.c.

282{
283 int participants;
284
285 SpinLockAcquire(&barrier->mutex);
286 participants = barrier->participants;
287 SpinLockRelease(&barrier->mutex);
288
289 return participants;
290}

References barrier, SpinLockAcquire, and SpinLockRelease.

◆ BarrierPhase()

int BarrierPhase ( Barrier barrier)

Definition at line 265 of file barrier.c.

266{
267 /*
268 * It is OK to read barrier->phase without locking, because it can't
269 * change without us (we are attached to it), and we executed a memory
270 * barrier when we either attached or participated in changing it last
271 * time.
272 */
273 return barrier->phase;
274}

References barrier.

Referenced by ExecHashJoinImpl(), ExecHashTableCreate(), ExecHashTableDetach(), ExecHashTableDetachBatch(), ExecParallelHashIncreaseNumBatches(), ExecParallelHashIncreaseNumBuckets(), ExecParallelHashJoinNewBatch(), ExecParallelHashJoinSetUpBatches(), ExecParallelHashTableInsert(), ExecParallelHashTupleAlloc(), ExecParallelPrepHashTableForUnmatched(), and MultiExecParallelHash().