agora inbox for [email protected]
help / color / mirror / Atom feed[PATCH v1 3/3] LO frontend PQexecParams
183+ messages / 1 participants
[nested] [flat]
* [PATCH v1 3/3] LO frontend PQexecParams
@ 2026-05-26 16:12 Nathan Bossart <[email protected]>
0 siblings, 0 replies; 183+ messages in thread
From: Nathan Bossart @ 2026-05-26 16:12 UTC (permalink / raw)
---
src/interfaces/libpq/fe-connect.c | 1 -
src/interfaces/libpq/fe-lobj.c | 236 ++++--------------------------
src/interfaces/libpq/libpq-int.h | 1 -
3 files changed, 26 insertions(+), 212 deletions(-)
diff --git a/src/interfaces/libpq/fe-connect.c b/src/interfaces/libpq/fe-connect.c
index 01c9735f276..9f6aa01dc0e 100644
--- a/src/interfaces/libpq/fe-connect.c
+++ b/src/interfaces/libpq/fe-connect.c
@@ -692,7 +692,6 @@ pqDropServerData(PGconn *conn)
conn->in_hot_standby = PG_BOOL_UNKNOWN;
conn->scram_sha_256_iterations = SCRAM_SHA_256_DEFAULT_ITERATIONS;
conn->sversion = 0;
- conn->lobjprepared = false;
/* Reset assorted other per-connection state */
conn->last_sqlstate[0] = '\0';
diff --git a/src/interfaces/libpq/fe-lobj.c b/src/interfaces/libpq/fe-lobj.c
index 41573c22c80..17c1d699a48 100644
--- a/src/interfaces/libpq/fe-lobj.c
+++ b/src/interfaces/libpq/fe-lobj.c
@@ -41,89 +41,6 @@
#define LO_BUFSIZE 8192
-typedef struct PGlobjfuncs
-{
- char *name;
- char *args;
- int nargs;
- int version;
-} PGlobjfuncs;
-
-static const PGlobjfuncs lobjfuncs[] =
-{
- {
- "lo_open",
- "$1::pg_catalog.oid, $2::pg_catalog.int4",
- 2
- },
- {
- "lo_close",
- "$1::pg_catalog.int4",
- 1
- },
- {
- "lo_creat",
- "$1::pg_catalog.int4",
- 1
- },
- {
- "lo_create",
- "$1::pg_catalog.oid",
- 1,
- 80100
- },
- {
- "lo_unlink",
- "$1::pg_catalog.oid",
- 1
- },
- {
- "lo_lseek",
- "$1::pg_catalog.int4, $2::pg_catalog.int4, $3::pg_catalog.int4",
- 3
- },
- {
- "lo_lseek64",
- "$1::pg_catalog.int4, $2::pg_catalog.int8, $3::pg_catalog.int4",
- 3,
- 90300
- },
- {
- "lo_tell",
- "$1::pg_catalog.int4",
- 1
- },
- {
- "lo_tell64",
- "$1::pg_catalog.int4",
- 1,
- 90300
- },
- {
- "lo_truncate",
- "$1::pg_catalog.int4, $2::pg_catalog.int4",
- 2,
- 80300
- },
- {
- "lo_truncate64",
- "$1::pg_catalog.int4, $2::pg_catalog.int8",
- 2,
- 90300
- },
- {
- "loread",
- "$1::pg_catalog.int4, $2::pg_catalog.int4",
- 2
- },
- {
- "lowrite",
- "$1::pg_catalog.int4, $2::pg_catalog.bytea",
- 2
- }
-};
-
-static int lo_initialize(PGconn *conn);
static Oid lo_import_internal(PGconn *conn, const char *filename, Oid oid);
static bool
@@ -153,17 +70,14 @@ lo_open(PGconn *conn, Oid lobjId, int mode)
int argFormats[] = {1, 1};
PGresult *res;
- if (lo_initialize(conn) < 0)
- return -1;
-
lobjId = pg_hton32(lobjId);
argv[0] = (char *) &lobjId;
mode = pg_hton32(mode);
argv[1] = (char *) &mode;
- res = PQexecPrepared(conn, "libpq_internal_lo_open", 2,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_open($1::pg_catalog.oid, $2::pg_catalog.int4)", 2, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(fd)))
{
@@ -194,14 +108,11 @@ lo_close(PGconn *conn, int fd)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
fd = pg_hton32(fd);
argv[0] = (char *) &fd;
- res = PQexecPrepared(conn, "libpq_internal_lo_close", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_close($1::pg_catalog.int4)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -232,9 +143,6 @@ lo_truncate(PGconn *conn, int fd, size_t len)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
if (PQserverVersion(conn) < 80300)
{
libpq_append_conn_error(conn, "server does not support function \"%s\"",
@@ -263,8 +171,8 @@ lo_truncate(PGconn *conn, int fd, size_t len)
len = pg_hton32(len);
argv[1] = (char *) &len;
- res = PQexecPrepared(conn, "libpq_internal_lo_truncate", 2,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_truncate($1::pg_catalog.int4, $2::pg_catalog.int4)", 2, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -295,9 +203,6 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
if (PQserverVersion(conn) < 90300)
{
libpq_append_conn_error(conn, "server does not support function \"%s\"",
@@ -311,8 +216,8 @@ lo_truncate64(PGconn *conn, int fd, int64_t len)
len = pg_hton64(len);
argv[1] = (char *) &len;
- res = PQexecPrepared(conn, "ligpq_internal_lo_truncate64", 2,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_truncate64($1::pg_catalog.int4, $2::pg_catalog.int8)", 2, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -343,9 +248,6 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
int argFormats[] = {1, 1};
PGresult *res;
- if (lo_initialize(conn) < 0)
- return -1;
-
/*
* Long ago, somebody thought it'd be a good idea to declare this function
* as taking size_t ... but the underlying backend function only accepts a
@@ -364,8 +266,8 @@ lo_read(PGconn *conn, int fd, char *buf, size_t len)
len = pg_hton32(len);
argv[1] = (char *) &len;
- res = PQexecPrepared(conn, "libpq_internal_loread", 2,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.loread($1::pg_catalog.int4, $2::pg_catalog.int4)", 2, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, -1))
{
@@ -401,9 +303,6 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
/*
* Long ago, somebody thought it'd be a good idea to declare this function
* as taking size_t ... but the underlying backend function only accepts a
@@ -421,8 +320,8 @@ lo_write(PGconn *conn, int fd, const char *buf, size_t len)
argv[1] = unconstify(char *, buf);
- res = PQexecPrepared(conn, "libpq_internal_lowrite", 2,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lowrite($1::pg_catalog.int4, $2::pg_catalog.bytea)", 2, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -450,9 +349,6 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
fd = pg_hton32(fd);
argv[0] = (char *) &fd;
@@ -462,8 +358,8 @@ lo_lseek(PGconn *conn, int fd, int offset, int whence)
whence = pg_hton32(whence);
argv[2] = (char *) &whence;
- res = PQexecPrepared(conn, "libpq_internal_lseek", 3,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lseek($1::pg_catalog.int4, $2::pg_catalog.int4, $3::pg_catalog.int4)", 3, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -491,9 +387,6 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int whence)
PGresult *res;
int64 retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
if (PQserverVersion(conn) < 90300)
{
libpq_append_conn_error(conn, "server does not support function \"%s\"",
@@ -510,8 +403,8 @@ lo_lseek64(PGconn *conn, int fd, int64_t offset, int whence)
whence = pg_hton32(whence);
argv[2] = (char *) &whence;
- res = PQexecPrepared(conn, "ligpq_internal_lo_lseek64", 3,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_lseek64($1::pg_catalog.int4, $2::pg_catalog.int8, $3::pg_catalog.int4)", 3, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
memcpy(&retval, PQgetvalue(res, 0, 0), sizeof(retval));
@@ -542,14 +435,11 @@ lo_creat(PGconn *conn, int mode)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return InvalidOid;
-
mode = pg_hton32(mode);
argv[0] = (char *) &mode;
- res = PQexecPrepared(conn, "libpq_internal_lo_creat", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_creat($1::pg_catalog.int4)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -581,9 +471,6 @@ lo_create(PGconn *conn, Oid lobjId)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return InvalidOid;
-
if (PQserverVersion(conn) < 80100)
{
libpq_append_conn_error(conn, "server does not support function \"%s\"",
@@ -594,8 +481,8 @@ lo_create(PGconn *conn, Oid lobjId)
lobjId = pg_hton32(lobjId);
argv[0] = (char *) &lobjId;
- res = PQexecPrepared(conn, "libpq_internal_lo_create", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_create($1::pg_catalog.oid)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -624,14 +511,11 @@ lo_tell(PGconn *conn, int fd)
int argFormats[] = {1};
PGresult *res;
- if (lo_initialize(conn) < 0)
- return -1;
-
fd = pg_hton32(fd);
argv[0] = (char *) &fd;
- res = PQexecPrepared(conn, "libpq_internal_lo_tell", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_tell($1::pg_catalog.int4)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -659,9 +543,6 @@ lo_tell64(PGconn *conn, int fd)
int argFormats[] = {1};
PGresult *res;
- if (lo_initialize(conn) < 0)
- return -1;
-
if (PQserverVersion(conn) < 90300)
{
libpq_append_conn_error(conn, "server does not support functions \"%s\"",
@@ -672,8 +553,8 @@ lo_tell64(PGconn *conn, int fd)
fd = pg_hton32(fd);
argv[0] = (char *) &fd;
- res = PQexecPrepared(conn, "libpq_internal_lo_tell64", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_tell64($1::pg_catalog.int4)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -702,14 +583,11 @@ lo_unlink(PGconn *conn, Oid lobjId)
PGresult *res;
int retval;
- if (lo_initialize(conn) < 0)
- return -1;
-
lobjId = pg_hton32(lobjId);
argv[0] = (char *) &lobjId;
- res = PQexecPrepared(conn, "libpq_internal_lo_unlink", 1,
- (const char *const *) argv, argLens, argFormats, 1);
+ res = PQexecParams(conn, "SELECT pg_catalog.lo_unlink($1::pg_catalog.oid)", 1, NULL,
+ (const char *const *) argv, argLens, argFormats, 1);
if (lo_result_is_valid(res, sizeof(retval)))
{
@@ -938,65 +816,3 @@ lo_export(PGconn *conn, Oid lobjId, const char *filename)
return result;
}
-
-
-/*
- * lo_initialize
- *
- * Initialize for a new large-object operation on an existing connection.
- * Return 0 if OK, -1 on failure.
- *
- * If we haven't previously done so, we prepared statements for all the
- * functions that are required for large object operations.
- */
-static int
-lo_initialize(PGconn *conn)
-{
- /* Nothing we can do with no connection */
- if (conn == NULL)
- return -1;
-
- /* Since this is the beginning of a query cycle, reset the error state */
- pqClearConnErrorState(conn);
-
- /* Nothing else to do if we already prepared the statements */
- if (conn->lobjprepared)
- return 0;
-
- for (int i = 0; i < lengthof(lobjfuncs); i++)
- {
- PGresult *res;
- ExecStatusType status;
- PQExpBufferData pname;
- PQExpBufferData pquery;
-
- if (PQserverVersion(conn) < lobjfuncs[i].version)
- continue;
-
- initPQExpBuffer(&pname);
- initPQExpBuffer(&pquery);
-
- appendPQExpBuffer(&pname, "libpq_internal_%s",
- lobjfuncs[i].name);
- appendPQExpBuffer(&pquery, "SELECT pg_catalog.%s(%s)",
- lobjfuncs[i].name, lobjfuncs[i].args);
-
- res = PQprepare(conn, pname.data, pquery.data,
- lobjfuncs[i].nargs, NULL);
- status = PQresultStatus(res);
- if (res)
- PQclear(res);
-
- termPQExpBuffer(&pname);
- termPQExpBuffer(&pquery);
-
- if (status == PGRES_COMMAND_OK)
- continue;
-
- libpq_append_conn_error(conn, "query to prepare large object statements failed");
- return -1;
- }
-
- conn->lobjprepared = true;
- return 0;
-}
diff --git a/src/interfaces/libpq/libpq-int.h b/src/interfaces/libpq/libpq-int.h
index 9dd0f42b6b7..cf968f1519b 100644
--- a/src/interfaces/libpq/libpq-int.h
+++ b/src/interfaces/libpq/libpq-int.h
@@ -544,7 +544,6 @@ struct pg_conn
PGTernaryBool in_hot_standby; /* in_hot_standby */
PGVerbosity verbosity; /* error/notice message verbosity */
PGContextVisibility show_context; /* whether to show CONTEXT field */
- bool lobjprepared; /* whether LO statements have been prepared */
pg_prng_state prng_state; /* prng state for load balancing connections */
--
2.50.1 (Apple Git-155)
--NDf4SqMA2rj1ZNJ4--
^ permalink raw reply [nested|flat] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ 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; 183+ 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] 183+ messages in thread
end of thread, other threads:[~2026-07-09 20:04 UTC | newest]
Thread overview: 183+ messages (download: mbox mbox.gz follow: Atom feed)
-- links below jump to the message on this page --
2026-05-26 16:12 [PATCH v1 3/3] LO frontend PQexecParams 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]>
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]>
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]>
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]>
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]>
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