summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Munro2020-11-19 05:09:50 +0000
committerThomas Munro2020-11-19 05:13:46 +0000
commit7888b0999488511e4266f2134053fa3a6505a155 (patch)
tree4f22410c81fa8b08530d71d71fda71b199c93915
parent13b58f8934e6252868231c3493d49b8c2b363e5d (diff)
Add BarrierArriveAndDetachExceptLast().
Provide a way for one process to continue the remaining phases of a (previously) parallel computation alone. Later patches will use this to extend Parallel Hash Join. Author: Melanie Plageman <[email protected]> Reviewed-by: Thomas Munro <[email protected]> Discussion: https://postgr.es/m/CA%2BhUKG%2BA6ftXPz4oe92%2Bx8Er%2BxpGZqto70-Q_ERwRaSyA%3DafNg%40mail.gmail.com
-rw-r--r--src/backend/storage/ipc/barrier.c22
-rw-r--r--src/include/storage/barrier.h1
2 files changed, 23 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3e200e02cc2..69afd586898 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -206,6 +206,28 @@ BarrierArriveAndDetach(Barrier *barrier)
}
/*
+ * Arrive at a barrier, and detach all but the last to arrive. Returns true if
+ * the caller was the last to arrive, and is therefore still attached.
+ */
+bool
+BarrierArriveAndDetachExceptLast(Barrier *barrier)
+{
+ SpinLockAcquire(&barrier->mutex);
+ if (barrier->participants > 1)
+ {
+ --barrier->participants;
+ SpinLockRelease(&barrier->mutex);
+
+ return false;
+ }
+ Assert(barrier->participants == 1);
+ ++barrier->phase;
+ SpinLockRelease(&barrier->mutex);
+
+ return true;
+}
+
+/*
* Attach to a barrier. All waiting participants will now wait for this
* participant to call BarrierArriveAndWait(), BarrierDetach() or
* BarrierArriveAndDetach(). Return the current phase.
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index d71927cc2f7..e0de24378bf 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -37,6 +37,7 @@ typedef struct Barrier
extern void BarrierInit(Barrier *barrier, int num_workers);
extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
extern bool BarrierArriveAndDetach(Barrier *barrier);
+extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier);
extern int BarrierAttach(Barrier *barrier);
extern bool BarrierDetach(Barrier *barrier);
extern int BarrierPhase(Barrier *barrier);