agora inbox for [email protected]
help / color / mirror / Atom feed[PATCH v25 3/9] Row pattern recognition patch (rewriter).
32+ messages / 2 participants
[nested] [flat]
* [PATCH v25 3/9] Row pattern recognition patch (rewriter).
@ 2024-12-21 06:19 Tatsuo Ishii <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Tatsuo Ishii @ 2024-12-21 06:19 UTC (permalink / raw)
---
src/backend/utils/adt/ruleutils.c | 103 ++++++++++++++++++++++++++++++
1 file changed, 103 insertions(+)
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index be1f1f50b7..f58392f0aa 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -435,6 +435,10 @@ static void get_rule_groupingset(GroupingSet *gset, List *targetlist,
bool omit_parens, deparse_context *context);
static void get_rule_orderby(List *orderList, List *targetList,
bool force_colno, deparse_context *context);
+static void get_rule_pattern(List *patternVariable, List *patternRegexp,
+ bool force_colno, deparse_context *context);
+static void get_rule_define(List *defineClause, List *patternVariables,
+ bool force_colno, deparse_context *context);
static void get_rule_windowclause(Query *query, deparse_context *context);
static void get_rule_windowspec(WindowClause *wc, List *targetList,
deparse_context *context);
@@ -6667,6 +6671,67 @@ get_rule_orderby(List *orderList, List *targetList,
}
}
+/*
+ * Display a PATTERN clause.
+ */
+static void
+get_rule_pattern(List *patternVariable, List *patternRegexp,
+ bool force_colno, deparse_context *context)
+{
+ StringInfo buf = context->buf;
+ const char *sep;
+ ListCell *lc_var,
+ *lc_reg = list_head(patternRegexp);
+
+ sep = "";
+ appendStringInfoChar(buf, '(');
+ foreach(lc_var, patternVariable)
+ {
+ char *variable = strVal((String *) lfirst(lc_var));
+ char *regexp = NULL;
+
+ if (lc_reg != NULL)
+ {
+ regexp = strVal((String *) lfirst(lc_reg));
+
+ lc_reg = lnext(patternRegexp, lc_reg);
+ }
+
+ appendStringInfo(buf, "%s%s", sep, variable);
+ if (regexp !=NULL)
+ appendStringInfoString(buf, regexp);
+
+ sep = " ";
+ }
+ appendStringInfoChar(buf, ')');
+}
+
+/*
+ * Display a DEFINE clause.
+ */
+static void
+get_rule_define(List *defineClause, List *patternVariables,
+ bool force_colno, deparse_context *context)
+{
+ StringInfo buf = context->buf;
+ const char *sep;
+ ListCell *lc_var,
+ *lc_def;
+
+ sep = " ";
+ Assert(list_length(patternVariables) == list_length(defineClause));
+
+ forboth(lc_var, patternVariables, lc_def, defineClause)
+ {
+ char *varName = strVal(lfirst(lc_var));
+ TargetEntry *te = (TargetEntry *) lfirst(lc_def);
+
+ appendStringInfo(buf, "%s%s AS ", sep, varName);
+ get_rule_expr((Node *) te->expr, context, false);
+ sep = ",\n ";
+ }
+}
+
/*
* Display a WINDOW clause.
*
@@ -6804,6 +6869,44 @@ get_rule_windowspec(WindowClause *wc, List *targetList,
appendStringInfoString(buf, "EXCLUDE GROUP ");
else if (wc->frameOptions & FRAMEOPTION_EXCLUDE_TIES)
appendStringInfoString(buf, "EXCLUDE TIES ");
+ /* RPR */
+ if (wc->rpSkipTo == ST_NEXT_ROW)
+ appendStringInfoString(buf,
+ "\n AFTER MATCH SKIP TO NEXT ROW ");
+ else if (wc->rpSkipTo == ST_PAST_LAST_ROW)
+ appendStringInfoString(buf,
+ "\n AFTER MATCH SKIP PAST LAST ROW ");
+ else if (wc->rpSkipTo == ST_FIRST_VARIABLE)
+ appendStringInfo(buf,
+ "\n AFTER MATCH SKIP TO FIRST %s ",
+ wc->rpSkipVariable);
+ else if (wc->rpSkipTo == ST_LAST_VARIABLE)
+ appendStringInfo(buf,
+ "\n AFTER MATCH SKIP TO LAST %s ",
+ wc->rpSkipVariable);
+ else if (wc->rpSkipTo == ST_VARIABLE)
+ appendStringInfo(buf,
+ "\n AFTER MATCH SKIP TO %s ",
+ wc->rpSkipVariable);
+
+ if (wc->initial)
+ appendStringInfoString(buf, "\n INITIAL");
+
+ if (wc->patternVariable)
+ {
+ appendStringInfoString(buf, "\n PATTERN ");
+ get_rule_pattern(wc->patternVariable, wc->patternRegexp,
+ false, context);
+ }
+
+ if (wc->defineClause)
+ {
+ appendStringInfoString(buf, "\n DEFINE\n");
+ get_rule_define(wc->defineClause, wc->patternVariable,
+ false, context);
+ appendStringInfoChar(buf, ' ');
+ }
+
/* we will now have a trailing space; remove it */
buf->len--;
}
--
2.25.1
----Next_Part(Sat_Dec_21_18_20_04_2024_526)--
Content-Type: Text/X-Patch; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
filename="v25-0004-Row-pattern-recognition-patch-planner.patch"
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
* [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics
@ 2026-07-09 20:04 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 32+ messages in thread
From: Nathan Bossart @ 2026-07-09 20:04 UTC (permalink / raw)
---
src/backend/utils/sort/tuplesort.c | 30 ++++++++----------------------
1 file changed, 8 insertions(+), 22 deletions(-)
diff --git a/src/backend/utils/sort/tuplesort.c b/src/backend/utils/sort/tuplesort.c
index c0e7527b9ca..81e0b2816d6 100644
--- a/src/backend/utils/sort/tuplesort.c
+++ b/src/backend/utils/sort/tuplesort.c
@@ -104,6 +104,7 @@
#include "commands/tablespace.h"
#include "miscadmin.h"
#include "pg_trace.h"
+#include "port/atomics.h"
#include "port/pg_bitutils.h"
#include "storage/shmem.h"
#include "utils/guc.h"
@@ -340,9 +341,6 @@ struct Tuplesortstate
*/
struct Sharedsort
{
- /* mutex protects all fields prior to tapes */
- slock_t mutex;
-
/*
* currentWorker generates ordinal identifier numbers for parallel sort
* workers. These start from 0, and are always gapless.
@@ -351,8 +349,8 @@ struct Sharedsort
* is equal to state.nParticipants within the leader, leader is ready to
* merge worker runs.
*/
- int currentWorker;
- int workersFinished;
+ pg_atomic_uint32 currentWorker;
+ pg_atomic_uint32 workersFinished;
/* Temporary file space */
SharedFileSet fileset;
@@ -3252,9 +3250,8 @@ tuplesort_initialize_shared(Sharedsort *shared, int nWorkers, dsm_segment *seg)
Assert(nWorkers > 0);
- SpinLockInit(&shared->mutex);
- shared->currentWorker = 0;
- shared->workersFinished = 0;
+ pg_atomic_init_u32(&shared->currentWorker, 0);
+ pg_atomic_init_u32(&shared->workersFinished, 0);
SharedFileSetInit(&shared->fileset, seg);
shared->nTapes = nWorkers;
for (i = 0; i < nWorkers; i++)
@@ -3291,16 +3288,9 @@ tuplesort_attach_shared(Sharedsort *shared, dsm_segment *seg)
static int
worker_get_identifier(Tuplesortstate *state)
{
- Sharedsort *shared = state->shared;
- int worker;
-
Assert(WORKER(state));
- SpinLockAcquire(&shared->mutex);
- worker = shared->currentWorker++;
- SpinLockRelease(&shared->mutex);
-
- return worker;
+ return pg_atomic_fetch_add_u32(&state->shared->currentWorker, 1);
}
/*
@@ -3342,10 +3332,8 @@ worker_freeze_result_tape(Tuplesortstate *state)
LogicalTapeFreeze(state->result_tape, &output);
/* Store properties of output tape, and update finished worker count */
- SpinLockAcquire(&shared->mutex);
shared->tapes[state->worker] = output;
- shared->workersFinished++;
- SpinLockRelease(&shared->mutex);
+ pg_atomic_fetch_add_u32(&shared->workersFinished, 1);
}
/*
@@ -3387,9 +3375,7 @@ leader_takeover_tapes(Tuplesortstate *state)
Assert(LEADER(state));
Assert(nParticipants >= 1);
- SpinLockAcquire(&shared->mutex);
- workersFinished = shared->workersFinished;
- SpinLockRelease(&shared->mutex);
+ workersFinished = pg_atomic_read_membarrier_u32(&shared->workersFinished);
if (nParticipants != workersFinished)
elog(ERROR, "cannot take over tapes before all workers finish");
--
2.50.1 (Apple Git-155)
--Ot5x3ffkWEuxilWO
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment;
filename=v1-0006-convert-SharedFileSet-refcnt-to-an-atomic.patch
^ permalink raw reply [nested|flat] 32+ messages in thread
end of thread, other threads:[~2026-07-09 20:04 UTC | newest]
Thread overview: 32+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2024-12-21 06:19 [PATCH v25 3/9] Row pattern recognition patch (rewriter). Tatsuo Ishii <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
2026-07-09 20:04 [PATCH v1 5/8] convert Sharedsort->{currentWorker,workersFinished} to atomics Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions
for how to clone and mirror all data and code used for this inbox