v6-0001-Convert-wait_event_info-to-64-t-bits-expose-lower.patch
text/x-patch
Filename: v6-0001-Convert-wait_event_info-to-64-t-bits-expose-lower.patch
Type: text/x-patch
Part: 5
Patch
Same data as JSON:
GET /api/v1/attachments/:id/patch
the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes.
API reference →
Format: format-patch
Series: patch v6-0001
Subject: Convert wait_event_info to 64-t bits, expose lower 32-bit as new wait_event_arg
| File | + | − |
|---|---|---|
| contrib/dblink/dblink.c | 3 | 3 |
| contrib/postgres_fdw/connection.c | 3 | 3 |
| src/backend/access/transam/xlogarchive.c | 1 | 1 |
| src/backend/access/transam/xlogwait.c | 1 | 1 |
| src/backend/catalog/system_views.sql | 1 | 0 |
| src/backend/replication/walsender.c | 5 | 5 |
| src/backend/storage/buffer/bufmgr.c | 1 | 1 |
| src/backend/storage/file/fd.c | 9 | 9 |
| src/backend/storage/ipc/barrier.c | 1 | 1 |
| src/backend/storage/ipc/latch.c | 2 | 2 |
| src/backend/storage/ipc/standby.c | 6 | 4 |
| src/backend/storage/ipc/waiteventset.c | 1 | 1 |
| src/backend/storage/lmgr/condition_variable.c | 2 | 2 |
| src/backend/storage/lmgr/lwlock.c | 2 | 2 |
| src/backend/storage/lmgr/proc.c | 3 | 3 |
| src/backend/storage/lmgr/s_lock.c | 1 | 1 |
| src/backend/storage/smgr/md.c | 0 | 1 |
| src/backend/utils/activity/backend_status.c | 2 | 1 |
| src/backend/utils/activity/generate-wait_event_types.pl | 24 | 8 |
| src/backend/utils/activity/wait_event.c | 60 | 37 |
| src/backend/utils/adt/misc.c | 1 | 1 |
| src/backend/utils/adt/pgstatfuncs.c | 66 | 57 |
| src/backend/utils/adt/waitfuncs.c | 1 | 3 |
| src/include/access/xlogarchive.h | 1 | 1 |
| src/include/catalog/pg_proc.dat | 3 | 3 |
| src/include/libpq/libpq-be-fe-helpers.h | 10 | 10 |
| src/include/storage/barrier.h | 1 | 1 |
| src/include/storage/condition_variable.h | 2 | 2 |
| src/include/storage/fd.h | 11 | 11 |
| src/include/storage/latch.h | 2 | 2 |
| src/include/storage/lwlock.h | 1 | 1 |
| src/include/storage/proc.h | 2 | 2 |
| src/include/storage/waiteventset.h | 1 | 1 |
| src/include/utils/wait_classes.h | 10 | 10 |
| src/include/utils/wait_event.h | 24 | 18 |
| src/test/modules/injection_points/injection_points.c | 1 | 1 |
| src/test/modules/test_shm_mq/setup.c | 1 | 1 |
| src/test/modules/test_shm_mq/test.c | 1 | 1 |
| src/test/modules/worker_spi/worker_spi.c | 1 | 1 |
| src/test/regress/expected/rules.out | 5 | 4 |
From 561a6cac20e049da60ba4b95c8e9fee3f3f075eb Mon Sep 17 00:00:00 2001
From: Jakub Wartak <jakub.wartak@enterprisedb.com>
Date: Thu, 12 Feb 2026 12:28:47 +0100
Subject: [PATCH v6 1/6] Convert wait_event_info to 64-t bits, expose lower
32-bit as new wait_event_arg
Implement some very basic uses of wait_event_arg for the following wait events:
- Timeout/PgSleep
- IPC/RecoveryConflictTablespace
Due to (Win32-based) compiler limitations, we need to resign from use of enums
as they do not always allow use of 64-bit integers.
Author: Jakub Wartak <jakub.wartak@enterprisedb.com>
Reviewed-by:
Discussion: https://www.postgresql.org/message-id/flat/CAKZiRmyKcTaeSGzMYDN6aRR-BwYGPeZbzDRKvGkJhxAghfb4LQ%40mail.gmail.com
---
contrib/dblink/dblink.c | 6 +-
contrib/postgres_fdw/connection.c | 6 +-
src/backend/access/transam/xlogarchive.c | 2 +-
src/backend/access/transam/xlogwait.c | 2 +-
src/backend/catalog/system_views.sql | 1 +
src/backend/replication/walsender.c | 10 +-
src/backend/storage/buffer/bufmgr.c | 2 +-
src/backend/storage/file/fd.c | 18 +--
src/backend/storage/ipc/barrier.c | 2 +-
src/backend/storage/ipc/latch.c | 4 +-
src/backend/storage/ipc/standby.c | 10 +-
src/backend/storage/ipc/waiteventset.c | 2 +-
src/backend/storage/lmgr/condition_variable.c | 4 +-
src/backend/storage/lmgr/lwlock.c | 4 +-
src/backend/storage/lmgr/proc.c | 6 +-
src/backend/storage/lmgr/s_lock.c | 2 +-
src/backend/storage/smgr/md.c | 1 -
src/backend/utils/activity/backend_status.c | 3 +-
.../activity/generate-wait_event_types.pl | 32 +++--
src/backend/utils/activity/wait_event.c | 97 ++++++++------
src/backend/utils/adt/misc.c | 2 +-
src/backend/utils/adt/pgstatfuncs.c | 123 ++++++++++--------
src/backend/utils/adt/waitfuncs.c | 4 +-
src/include/access/xlogarchive.h | 2 +-
src/include/catalog/pg_proc.dat | 6 +-
src/include/libpq/libpq-be-fe-helpers.h | 20 +--
src/include/storage/barrier.h | 2 +-
src/include/storage/condition_variable.h | 4 +-
src/include/storage/fd.h | 22 ++--
src/include/storage/latch.h | 4 +-
src/include/storage/lwlock.h | 2 +-
src/include/storage/proc.h | 4 +-
src/include/storage/waiteventset.h | 2 +-
src/include/utils/wait_classes.h | 20 +--
src/include/utils/wait_event.h | 42 +++---
.../injection_points/injection_points.c | 2 +-
src/test/modules/test_shm_mq/setup.c | 2 +-
src/test/modules/test_shm_mq/test.c | 2 +-
src/test/modules/worker_spi/worker_spi.c | 2 +-
src/test/regress/expected/rules.out | 9 +-
40 files changed, 273 insertions(+), 217 deletions(-)
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 2498d80c8e7..07859ba1ddf 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -143,9 +143,9 @@ static remoteConn *pconn = NULL;
static HTAB *remoteConnHash = NULL;
/* custom wait event values, retrieved from shared memory */
-static uint32 dblink_we_connect = 0;
-static uint32 dblink_we_get_conn = 0;
-static uint32 dblink_we_get_result = 0;
+static uint64 dblink_we_connect = 0;
+static uint64 dblink_we_get_conn = 0;
+static uint64 dblink_we_get_result = 0;
/*
* Following is hash that holds multiple remote connections.
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 311936406f2..dfa0f8f0b71 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -86,9 +86,9 @@ static unsigned int prep_stmt_number = 0;
static bool xact_got_connection = false;
/* custom wait event values, retrieved from shared memory */
-static uint32 pgfdw_we_cleanup_result = 0;
-static uint32 pgfdw_we_connect = 0;
-static uint32 pgfdw_we_get_result = 0;
+static uint64 pgfdw_we_cleanup_result = 0;
+static uint64 pgfdw_we_connect = 0;
+static uint64 pgfdw_we_get_result = 0;
/*
* Milliseconds to wait to cancel an in-progress query or execute a cleanup
diff --git a/src/backend/access/transam/xlogarchive.c b/src/backend/access/transam/xlogarchive.c
index aa0c2fe3afd..60815b0b3cd 100644
--- a/src/backend/access/transam/xlogarchive.c
+++ b/src/backend/access/transam/xlogarchive.c
@@ -293,7 +293,7 @@ not_available:
*/
void
ExecuteRecoveryCommand(const char *command, const char *commandName,
- bool failOnSignal, uint32 wait_event_info)
+ bool failOnSignal, uint64 wait_event_info)
{
char *xlogRecoveryCmd;
char lastRestartPointFname[MAXPGPATH];
diff --git a/src/backend/access/transam/xlogwait.c b/src/backend/access/transam/xlogwait.c
index d286ff63123..19344afa54e 100644
--- a/src/backend/access/transam/xlogwait.c
+++ b/src/backend/access/transam/xlogwait.c
@@ -71,7 +71,7 @@ struct WaitLSNState *waitLSNState = NULL;
* Wait event for each WaitLSNType, used with WaitLatch() to report
* the wait in pg_stat_activity.
*/
-static const uint32 WaitLSNWaitEvents[] = {
+static const uint64 WaitLSNWaitEvents[] = {
[WAIT_LSN_TYPE_STANDBY_REPLAY] = WAIT_EVENT_WAIT_FOR_WAL_REPLAY,
[WAIT_LSN_TYPE_STANDBY_WRITE] = WAIT_EVENT_WAIT_FOR_WAL_WRITE,
[WAIT_LSN_TYPE_STANDBY_FLUSH] = WAIT_EVENT_WAIT_FOR_WAL_FLUSH,
diff --git a/src/backend/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 1ea8f1faa9e..492566cd85b 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -936,6 +936,7 @@ CREATE VIEW pg_stat_activity AS
S.state_change,
S.wait_event_type,
S.wait_event,
+ S.wait_event_arg,
S.state,
S.backend_xid,
S.backend_xmin,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 2cde8ebc729..a367bf163e5 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -282,7 +282,7 @@ static void WalSndKeepalive(bool requestReply, XLogRecPtr writePtr);
static void WalSndKeepaliveIfNecessary(void);
static void WalSndCheckTimeOut(void);
static long WalSndComputeSleeptime(TimestampTz now);
-static void WalSndWait(uint32 socket_events, long timeout, uint32 wait_event);
+static void WalSndWait(uint32 socket_events, long timeout, uint64 wait_event);
static void WalSndPrepareWrite(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write);
static void WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid, bool last_write);
static void WalSndUpdateProgress(LogicalDecodingContext *ctx, XLogRecPtr lsn, TransactionId xid,
@@ -1781,7 +1781,7 @@ PhysicalWakeupLogicalWalSnd(void)
* wait_event; otherwise, wait_event is set to 0.
*/
static bool
-NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint32 *wait_event)
+NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint64 *wait_event)
{
int elevel = got_STOPPING ? ERROR : WARNING;
bool failover_slot;
@@ -1814,7 +1814,7 @@ NeedToWaitForStandbys(XLogRecPtr flushed_lsn, uint32 *wait_event)
*/
static bool
NeedToWaitForWal(XLogRecPtr target_lsn, XLogRecPtr flushed_lsn,
- uint32 *wait_event)
+ uint64 *wait_event)
{
/* Check if we need to wait for WALs to be flushed to disk */
if (target_lsn > flushed_lsn)
@@ -1844,7 +1844,7 @@ static XLogRecPtr
WalSndWaitForWal(XLogRecPtr loc)
{
int wakeEvents;
- uint32 wait_event = 0;
+ uint64 wait_event = 0;
static XLogRecPtr RecentFlushPtr = InvalidXLogRecPtr;
TimestampTz last_flush = 0;
@@ -3828,7 +3828,7 @@ WalSndWakeup(bool physical, bool logical)
* on postmaster death.
*/
static void
-WalSndWait(uint32 socket_events, long timeout, uint32 wait_event)
+WalSndWait(uint32 socket_events, long timeout, uint64 wait_event)
{
WaitEvent event;
diff --git a/src/backend/storage/buffer/bufmgr.c b/src/backend/storage/buffer/bufmgr.c
index d1babaff023..92c924bc64e 100644
--- a/src/backend/storage/buffer/bufmgr.c
+++ b/src/backend/storage/buffer/bufmgr.c
@@ -5778,7 +5778,7 @@ BufferLockAcquire(Buffer buffer, BufferDesc *buf_hdr, BufferLockMode mode)
for (;;)
{
- uint32 wait_event = 0; /* initialized to avoid compiler warning */
+ uint64 wait_event = 0; /* initialized to avoid compiler warning */
bool mustwait;
/*
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index 5d07b64a1ef..95896b380f9 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2063,7 +2063,7 @@ FileClose(File file)
* this.
*/
int
-FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
Assert(FileIsValid(file));
@@ -2119,7 +2119,7 @@ retry:
}
void
-FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
+FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint64 wait_event_info)
{
int returnCode;
@@ -2146,7 +2146,7 @@ FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info)
ssize_t
FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
ssize_t returnCode;
Vfd *vfdP;
@@ -2203,7 +2203,7 @@ retry:
int
FileStartReadV(PgAioHandle *ioh, File file,
int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
int returnCode;
Vfd *vfdP;
@@ -2228,7 +2228,7 @@ FileStartReadV(PgAioHandle *ioh, File file,
ssize_t
FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
ssize_t returnCode;
Vfd *vfdP;
@@ -2332,7 +2332,7 @@ retry:
}
int
-FileSync(File file, uint32 wait_event_info)
+FileSync(File file, uint64 wait_event_info)
{
int returnCode;
@@ -2359,7 +2359,7 @@ FileSync(File file, uint32 wait_event_info)
* appropriate error.
*/
int
-FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FileZero(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
int returnCode;
ssize_t written;
@@ -2404,7 +2404,7 @@ FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
* appropriate error.
*/
int
-FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info)
+FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info)
{
#ifdef HAVE_POSIX_FALLOCATE
int returnCode;
@@ -2461,7 +2461,7 @@ FileSize(File file)
}
int
-FileTruncate(File file, pgoff_t offset, uint32 wait_event_info)
+FileTruncate(File file, pgoff_t offset, uint64 wait_event_info)
{
int returnCode;
diff --git a/src/backend/storage/ipc/barrier.c b/src/backend/storage/ipc/barrier.c
index 3fba281a75c..563ba6add90 100644
--- a/src/backend/storage/ipc/barrier.c
+++ b/src/backend/storage/ipc/barrier.c
@@ -122,7 +122,7 @@ BarrierInit(Barrier *barrier, int participants)
* phase of work that must be done serially while other participants wait.
*/
bool
-BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info)
+BarrierArriveAndWait(Barrier *barrier, uint64 wait_event_info)
{
bool release = false;
bool elected;
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index 8537e9fef2d..61fd4d4c0dd 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -170,7 +170,7 @@ DisownLatch(Latch *latch)
*/
int
WaitLatch(Latch *latch, int wakeEvents, long timeout,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
WaitEvent event;
@@ -221,7 +221,7 @@ WaitLatch(Latch *latch, int wakeEvents, long timeout,
*/
int
WaitLatchOrSocket(Latch *latch, int wakeEvents, pgsocket sock,
- long timeout, uint32 wait_event_info)
+ long timeout, uint64 wait_event_info)
{
int ret = 0;
int rc;
diff --git a/src/backend/storage/ipc/standby.c b/src/backend/storage/ipc/standby.c
index d83afbfb9d6..3b9ff6b1804 100644
--- a/src/backend/storage/ipc/standby.c
+++ b/src/backend/storage/ipc/standby.c
@@ -72,7 +72,7 @@ static volatile sig_atomic_t got_standby_lock_timeout = false;
static void ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
RecoveryConflictReason reason,
- uint32 wait_event_info,
+ uint64 wait_event_info,
bool report_waiting);
static void SendRecoveryConflictWithBufferPin(RecoveryConflictReason reason);
static XLogRecPtr LogCurrentRunningXacts(RunningTransactions CurrRunningXacts);
@@ -231,7 +231,7 @@ static int standbyWait_us = STANDBY_INITIAL_WAIT_US;
* more then we return true, if we can wait some more return false.
*/
static bool
-WaitExceedsMaxStandbyDelay(uint32 wait_event_info)
+WaitExceedsMaxStandbyDelay(uint64 wait_event_info)
{
TimestampTz ltime;
@@ -359,7 +359,7 @@ LogRecoveryConflict(RecoveryConflictReason reason, TimestampTz wait_start,
static void
ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
RecoveryConflictReason reason,
- uint32 wait_event_info,
+ uint64 wait_event_info,
bool report_waiting)
{
TimestampTz waitStart = 0;
@@ -557,12 +557,14 @@ ResolveRecoveryConflictWithTablespace(Oid tsid)
* them.
*
* We don't wait for commit because drop tablespace is non-transactional.
+ *
+ * We pass tablespaceId as wait_event_arg.
*/
temp_file_users = GetConflictingVirtualXIDs(InvalidTransactionId,
InvalidOid);
ResolveRecoveryConflictWithVirtualXIDs(temp_file_users,
RECOVERY_CONFLICT_TABLESPACE,
- WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE,
+ WAIT_EVENT_RECOVERY_CONFLICT_TABLESPACE | tsid,
true);
}
diff --git a/src/backend/storage/ipc/waiteventset.c b/src/backend/storage/ipc/waiteventset.c
index 772e350a0c0..91fea371c55 100644
--- a/src/backend/storage/ipc/waiteventset.c
+++ b/src/backend/storage/ipc/waiteventset.c
@@ -1038,7 +1038,7 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event)
int
WaitEventSetWait(WaitEventSet *set, long timeout,
WaitEvent *occurred_events, int nevents,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
int returned_events = 0;
instr_time start_time;
diff --git a/src/backend/storage/lmgr/condition_variable.c b/src/backend/storage/lmgr/condition_variable.c
index 1f16b3f7475..51519cd730a 100644
--- a/src/backend/storage/lmgr/condition_variable.c
+++ b/src/backend/storage/lmgr/condition_variable.c
@@ -95,7 +95,7 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
* wait_event_type and wait_event columns while waiting.
*/
void
-ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
+ConditionVariableSleep(ConditionVariable *cv, uint64 wait_event_info)
{
(void) ConditionVariableTimedSleep(cv, -1 /* no timeout */ ,
wait_event_info);
@@ -112,7 +112,7 @@ ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info)
*/
bool
ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
long cur_timeout = -1;
instr_time start_time;
diff --git a/src/backend/storage/lmgr/lwlock.c b/src/backend/storage/lmgr/lwlock.c
index 517c55375b4..d44ac5071fb 100644
--- a/src/backend/storage/lmgr/lwlock.c
+++ b/src/backend/storage/lmgr/lwlock.c
@@ -718,7 +718,7 @@ LWLockInitialize(LWLock *lock, int tranche_id)
static inline void
LWLockReportWaitStart(LWLock *lock)
{
- pgstat_report_wait_start(PG_WAIT_LWLOCK | lock->tranche);
+ pgstat_report_wait_start(PG_WAIT_LWLOCK | ((uint64_t) lock->tranche << 32));
}
/*
@@ -770,7 +770,7 @@ GetLWTrancheName(uint16 trancheId)
* Return an identifier for an LWLock based on the wait class and event.
*/
const char *
-GetLWLockIdentifier(uint32 classId, uint16 eventId)
+GetLWLockIdentifier(uint64 classId, uint16 eventId)
{
Assert(classId == PG_WAIT_LWLOCK);
/* The event IDs are just tranche numbers. */
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 771b006b522..79b29bbc155 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -508,7 +508,7 @@ InitProcess(void)
Assert(dlist_is_empty(&MyProc->lockGroupMembers));
/* Initialize wait event information. */
- MyProc->wait_event_info = 0;
+ pg_atomic_init_u64(&MyProc->wait_event_info, 0);
/* Initialize fields for group transaction status update. */
MyProc->clogGroupMember = false;
@@ -1444,7 +1444,7 @@ ProcSleep(LOCALLOCK *locallock)
else
{
(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
- PG_WAIT_LOCK | locallock->tag.lock.locktag_type);
+ PG_WAIT_LOCK | ((uint64_t) locallock->tag.lock.locktag_type << 32));
ResetLatch(MyLatch);
/* check for deadlocks first, as that's probably log-worthy */
if (got_deadlock_timeout)
@@ -1968,7 +1968,7 @@ GetLockHoldersAndWaiters(LOCALLOCK *locallock, StringInfo lock_holders_sbuf,
* wait again if not.
*/
void
-ProcWaitForSignal(uint32 wait_event_info)
+ProcWaitForSignal(uint64 wait_event_info)
{
(void) WaitLatch(MyLatch, WL_LATCH_SET | WL_EXIT_ON_PM_DEATH, 0,
wait_event_info);
diff --git a/src/backend/storage/lmgr/s_lock.c b/src/backend/storage/lmgr/s_lock.c
index 6df568eccb3..a474d3b3682 100644
--- a/src/backend/storage/lmgr/s_lock.c
+++ b/src/backend/storage/lmgr/s_lock.c
@@ -66,7 +66,7 @@
* s_lock_test.
*/
static uint32 local_my_wait_event_info;
-uint32 *my_wait_event_info = &local_my_wait_event_info;
+uint64 *my_wait_event_info = &local_my_wait_event_info;
#endif
static int spins_per_delay = DEFAULT_SPINS_PER_DELAY;
diff --git a/src/backend/storage/smgr/md.c b/src/backend/storage/smgr/md.c
index 443434e4ea8..ad82829c6cc 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -748,7 +748,6 @@ mdprefetch(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
int nblocks)
{
#ifdef USE_PREFETCH
-
Assert((io_direct_flags & IO_DIRECT_DATA) == 0);
if ((uint64) blocknum + nblocks > (uint64) MaxBlockNumber + 1)
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index cd087129469..35b81b1b969 100644
--- a/src/backend/utils/activity/backend_status.c
+++ b/src/backend/utils/activity/backend_status.c
@@ -20,6 +20,7 @@
#include "storage/proc.h" /* for MyProc */
#include "storage/procarray.h"
#include "utils/ascii.h"
+#include "utils/dsa.h"
#include "utils/guc.h" /* for application_name */
#include "utils/memutils.h"
@@ -601,7 +602,7 @@ pgstat_report_activity(BackendState state, const char *cmd_str)
beentry->st_xact_start_timestamp = 0;
beentry->st_query_id = INT64CONST(0);
beentry->st_plan_id = INT64CONST(0);
- proc->wait_event_info = 0;
+ pg_atomic_write_u64(&proc->wait_event_info, 0);
PGSTAT_END_WRITE_ACTIVITY(beentry);
}
return;
diff --git a/src/backend/utils/activity/generate-wait_event_types.pl b/src/backend/utils/activity/generate-wait_event_types.pl
index d39a30d0478..938ca47f868 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -22,7 +22,6 @@ my $output_path = '.';
my $gen_docs = 0;
my $gen_code = 0;
-my $continue = "\n";
my %hashwe;
GetOptions(
@@ -160,6 +159,9 @@ if ($gen_code)
*
* It has been GENERATED by src/backend/utils/activity/generate-wait_event_types.pl
*
+ * We cannot use enums here, as certain compilers do not allow 64-bit based types
+ * within enums.
+ *
*-------------------------------------------------------------------------
*/
@@ -192,6 +194,7 @@ if ($gen_code)
my $lastlc = lc $last;
my $firstpass = 1;
my $pg_wait_class;
+ my $counter;
printf $c
"static const char *\npgstat_get_wait_$lastlc($waitclass w)\n{\n";
@@ -200,17 +203,22 @@ if ($gen_code)
foreach my $wev (@{ $hashwe{$waitclass} })
{
+ $pg_wait_class = "PG_WAIT_" . $lastuc;
if ($firstpass)
{
- printf $h "typedef enum\n{\n";
- $pg_wait_class = "PG_WAIT_" . $lastuc;
- printf $h "\t%s = %s", $wev->[0], $pg_wait_class;
- $continue = ",\n";
+ # mingw/MSVC does not allow enforcing 64-bit types within enums
+ #printf $h "typedef enum : uint64_t\n{\n";
+ printf $h "typedef uint64_t %s;\n", $waitclass;
+ printf $h "#define %s\t%s\n", $wev->[0], $pg_wait_class;
+ $counter = 1;
}
else
{
- printf $h "%s\t%s", $continue, $wev->[0];
- $continue = ",\n";
+ # we emit values like:
+ # WAIT_EVENT_DATA_FILE_READ = PG_WAIT_IO + (21ULL << 32)
+ # as C doesnt allow for defining custom jumps
+ printf $h "#define %s\t(%s+(%dULL << 32))\n", $wev->[0], $pg_wait_class, $counter;
+ $counter++;
}
$firstpass = 0;
@@ -220,7 +228,15 @@ if ($gen_code)
$wev->[1];
}
- printf $h "\n} $waitclass;\n\n";
+ # Dummy value to force some compilers to interpret the enum as 64-bits
+ printf $h "#define %s\t0xFFFFFFFFFFFFFFFFULL\n", $pg_wait_class . "_MAX";
+ #printf $h "\n} $waitclass;\n\n";
+ printf $h "\n\n";
+
+ # Generate final e.g. PG_WAIT_IO_MAX to supress compiler warnings about
+ # unhandled enum
+ printf $c "\t\t case %s:\n", $pg_wait_class . "_MAX";
+ printf $c "\t\t\t Assert(true);\n\t\t\t break;\n";
printf $c
"\t\t\t /* no default case, so that compiler will warn */\n";
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index aca2c8fc742..e878c892379 100644
--- a/src/backend/utils/activity/wait_event.c
+++ b/src/backend/utils/activity/wait_event.c
@@ -22,6 +22,7 @@
*/
#include "postgres.h"
+#include "port/atomics.h"
#include "storage/lmgr.h" /* for GetLockNameFromTagType */
#include "storage/lwlock.h" /* for GetLWLockIdentifier */
#include "storage/spin.h"
@@ -36,11 +37,14 @@ static const char *pgstat_get_wait_timeout(WaitEventTimeout w);
static const char *pgstat_get_wait_io(WaitEventIO w);
-static uint32 local_my_wait_event_info;
-uint32 *my_wait_event_info = &local_my_wait_event_info;
+static volatile pg_atomic_uint64 local_my_wait_event_info;
+volatile pg_atomic_uint64 *my_wait_event_info = &local_my_wait_event_info;
-#define WAIT_EVENT_CLASS_MASK 0xFF000000
-#define WAIT_EVENT_ID_MASK 0x0000FFFF
+#define WAIT_EVENT_CLASS_MASK 0xFF00000000000000
+#define WAIT_EVENT_ID_MASK 0x0000FFFF00000000
+#define WAIT_EVENT_ARG_MASK 0x00000000FFFFFFFF
+/* just upper 24bits for decoding wait_event into name */
+#define WAIT_EVENT_CLASSID_MASK (WAIT_EVENT_CLASS_MASK | WAIT_EVENT_ID_MASK)
/*
* Hash tables for storing custom wait event ids and their names in
@@ -69,21 +73,21 @@ static HTAB *WaitEventCustomHashByName; /* find infos from names */
/* hash table entries */
typedef struct WaitEventCustomEntryByInfo
{
- uint32 wait_event_info; /* hash key */
+ uint64 wait_event_info; /* hash key */
char wait_event_name[NAMEDATALEN]; /* custom wait event name */
} WaitEventCustomEntryByInfo;
typedef struct WaitEventCustomEntryByName
{
char wait_event_name[NAMEDATALEN]; /* hash key */
- uint32 wait_event_info;
+ uint64 wait_event_info;
} WaitEventCustomEntryByName;
/* dynamic allocation counter for custom wait events */
typedef struct WaitEventCustomCounterData
{
- int nextId; /* next ID to assign */
+ int nextId; /* next ID to assign */
slock_t mutex; /* protects the counter */
} WaitEventCustomCounterData;
@@ -93,8 +97,8 @@ static WaitEventCustomCounterData *WaitEventCustomCounter;
/* first event ID of custom wait events */
#define WAIT_EVENT_CUSTOM_INITIAL_ID 1
-static uint32 WaitEventCustomNew(uint32 classId, const char *wait_event_name);
-static const char *GetWaitEventCustomIdentifier(uint32 wait_event_info);
+static uint64 WaitEventCustomNew(uint64 classId, const char *wait_event_name);
+static const char *GetWaitEventCustomIdentifier(uint64 wait_event_info);
/*
* Return the space for dynamic shared hash tables and dynamic allocation counter.
@@ -133,7 +137,7 @@ WaitEventCustomShmemInit(void)
}
/* initialize or attach the hash tables to store custom wait events */
- info.keysize = sizeof(uint32);
+ info.keysize = sizeof(uint64);
info.entrysize = sizeof(WaitEventCustomEntryByInfo);
WaitEventCustomHashByInfo =
ShmemInitHash("WaitEventCustom hash by wait event information",
@@ -158,27 +162,31 @@ WaitEventCustomShmemInit(void)
*
* If the wait event name is already defined, this does not allocate a new
* entry; it returns the wait event information associated to the name.
+ *
+ * XXX: maybe we should return safe u64 struct here so that extension
+ * writers will get clear error message about need to change the type
*/
-uint32
+uint64
WaitEventExtensionNew(const char *wait_event_name)
{
return WaitEventCustomNew(PG_WAIT_EXTENSION, wait_event_name);
}
-uint32
+uint64
WaitEventInjectionPointNew(const char *wait_event_name)
{
return WaitEventCustomNew(PG_WAIT_INJECTIONPOINT, wait_event_name);
+
}
-static uint32
-WaitEventCustomNew(uint32 classId, const char *wait_event_name)
+static uint64
+WaitEventCustomNew(uint64 classId, const char *wait_event_name)
{
- uint16 eventId;
+ uint64 eventId;
bool found;
WaitEventCustomEntryByName *entry_by_name;
WaitEventCustomEntryByInfo *entry_by_info;
- uint32 wait_event_info;
+ uint64 wait_event_info;
/* Check the limit of the length of the event name */
if (strlen(wait_event_name) >= NAMEDATALEN)
@@ -197,7 +205,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
LWLockRelease(WaitEventCustomLock);
if (found)
{
- uint32 oldClassId;
+ uint64 oldClassId;
oldClassId = entry_by_name->wait_event_info & WAIT_EVENT_CLASS_MASK;
if (oldClassId != classId)
@@ -206,7 +214,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
errmsg("wait event \"%s\" already exists in type \"%s\"",
wait_event_name,
pgstat_get_wait_event_type(entry_by_name->wait_event_info))));
- return entry_by_name->wait_event_info;
+ return entry_by_name->wait_event_info | classId;
}
/*
@@ -221,7 +229,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
HASH_FIND, &found);
if (found)
{
- uint32 oldClassId;
+ uint64 oldClassId;
LWLockRelease(WaitEventCustomLock);
oldClassId = entry_by_name->wait_event_info & WAIT_EVENT_CLASS_MASK;
@@ -231,7 +239,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
errmsg("wait event \"%s\" already exists in type \"%s\"",
wait_event_name,
pgstat_get_wait_event_type(entry_by_name->wait_event_info))));
- return entry_by_name->wait_event_info;
+ return entry_by_name->wait_event_info | classId;
}
/* Allocate a new event Id */
@@ -245,12 +253,16 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
errmsg("too many custom wait events"));
}
- eventId = WaitEventCustomCounter->nextId++;
+ /*
+ * We shift the resulting nextId it as it needs to land in higher 32-bits
+ * part of the 64-bit word (see WAIT_EVENT_ID_MASK).
+ */
+ eventId = (uint64) (WaitEventCustomCounter->nextId++) << 32;
SpinLockRelease(&WaitEventCustomCounter->mutex);
/* Register the new wait event */
- wait_event_info = classId | eventId;
+ wait_event_info = classId | (uint64) eventId;
entry_by_info = (WaitEventCustomEntryByInfo *)
hash_search(WaitEventCustomHashByInfo, &wait_event_info,
HASH_ENTER, &found);
@@ -273,7 +285,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
* Return the name of a custom wait event information.
*/
static const char *
-GetWaitEventCustomIdentifier(uint32 wait_event_info)
+GetWaitEventCustomIdentifier(uint64 wait_event_info)
{
bool found;
WaitEventCustomEntryByInfo *entry;
@@ -291,7 +303,7 @@ GetWaitEventCustomIdentifier(uint32 wait_event_info)
if (!entry)
elog(ERROR,
- "could not find custom name for wait event information %u",
+ "could not find custom name for wait event information %" PRIu64,
wait_event_info);
return entry->wait_event_name;
@@ -303,7 +315,7 @@ GetWaitEventCustomIdentifier(uint32 wait_event_info)
* a palloc'd array, with the number of elements saved in *nwaitevents.
*/
char **
-GetWaitEventCustomNames(uint32 classId, int *nwaitevents)
+GetWaitEventCustomNames(uint64 classId, int *nwaitevents)
{
char **waiteventnames;
WaitEventCustomEntryByName *hentry;
@@ -346,7 +358,7 @@ GetWaitEventCustomNames(uint32 classId, int *nwaitevents)
* into shared memory.
*/
void
-pgstat_set_wait_event_storage(uint32 *wait_event_info)
+pgstat_set_wait_event_storage(volatile pg_atomic_uint64 *wait_event_info)
{
my_wait_event_info = wait_event_info;
}
@@ -370,9 +382,9 @@ pgstat_reset_wait_event_storage(void)
* waiting on.
*/
const char *
-pgstat_get_wait_event_type(uint32 wait_event_info)
+pgstat_get_wait_event_type(uint64 wait_event_info)
{
- uint32 classId;
+ uint64 classId;
const char *event_type;
/* report process as not waiting. */
@@ -428,9 +440,9 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
* waiting on.
*/
const char *
-pgstat_get_wait_event(uint32 wait_event_info)
+pgstat_get_wait_event(uint64 wait_event_info)
{
- uint32 classId;
+ uint64 classId;
uint16 eventId;
const char *event_name;
@@ -439,7 +451,7 @@ pgstat_get_wait_event(uint32 wait_event_info)
return NULL;
classId = wait_event_info & WAIT_EVENT_CLASS_MASK;
- eventId = wait_event_info & WAIT_EVENT_ID_MASK;
+ eventId = (uint16) ((wait_event_info & WAIT_EVENT_ID_MASK) >> 32);
switch (classId)
{
@@ -453,44 +465,48 @@ pgstat_get_wait_event(uint32 wait_event_info)
case PG_WAIT_INJECTIONPOINT:
event_name = GetWaitEventCustomIdentifier(wait_event_info);
break;
+ /* for the below ones we need to mask lower 32-bits */
case PG_WAIT_BUFFER:
{
- WaitEventBuffer w = (WaitEventBuffer) wait_event_info;
+ WaitEventBuffer w = (WaitEventBuffer) wait_event_info & WAIT_EVENT_CLASSID_MASK;
event_name = pgstat_get_wait_buffer(w);
break;
}
case PG_WAIT_ACTIVITY:
{
- WaitEventActivity w = (WaitEventActivity) wait_event_info;
+ WaitEventActivity w = (WaitEventActivity) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_activity(w);
break;
}
case PG_WAIT_CLIENT:
{
- WaitEventClient w = (WaitEventClient) wait_event_info;
+ WaitEventClient w = (WaitEventClient) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_client(w);
break;
}
case PG_WAIT_IPC:
{
- WaitEventIPC w = (WaitEventIPC) wait_event_info;
+ WaitEventIPC w = (WaitEventIPC) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
event_name = pgstat_get_wait_ipc(w);
break;
}
case PG_WAIT_TIMEOUT:
{
- WaitEventTimeout w = (WaitEventTimeout) wait_event_info;
+ WaitEventTimeout w = (WaitEventTimeout) wait_event_info & WAIT_EVENT_CLASSID_MASK;
event_name = pgstat_get_wait_timeout(w);
break;
}
case PG_WAIT_IO:
{
- WaitEventIO w = (WaitEventIO) wait_event_info;
+ WaitEventIO w = (WaitEventIO) wait_event_info & WAIT_EVENT_CLASSID_MASK;
event_name = pgstat_get_wait_io(w);
break;
@@ -503,4 +519,11 @@ pgstat_get_wait_event(uint32 wait_event_info)
return event_name;
}
+uint32
+pgstat_get_wait_event_arg(uint64 wait_event_info)
+{
+ uint32 arg = wait_event_info & WAIT_EVENT_ARG_MASK;
+ return arg;
+}
+
#include "utils/pgstat_wait_event.c"
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 32a787d7df7..daee8bec7e5 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -377,7 +377,7 @@ pg_sleep(PG_FUNCTION_ARGS)
(void) WaitLatch(MyLatch,
WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH,
delay_ms,
- WAIT_EVENT_PG_SLEEP);
+ WAIT_EVENT_PG_SLEEP | (uint32_t) secs/USECS_PER_SEC);
ResetLatch(MyLatch);
}
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index b1df96e7b0b..901aa5aa807 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -30,9 +30,10 @@
#include "storage/procarray.h"
#include "utils/acl.h"
#include "utils/builtins.h"
+#include "utils/dsa.h"
#include "utils/timestamp.h"
-#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
+#define UINT64_ACCESS_ONCE(var) ((uint64)(*((volatile uint64 *)&(var))))
#define HAS_PGSTAT_PERMISSIONS(role) (has_privs_of_role(GetUserId(), ROLE_PG_READ_ALL_STATS) || has_privs_of_role(GetUserId(), role))
@@ -351,7 +352,7 @@ pg_stat_get_progress_info(PG_FUNCTION_ARGS)
Datum
pg_stat_get_activity(PG_FUNCTION_ARGS)
{
-#define PG_STAT_GET_ACTIVITY_COLS 31
+#define PG_STAT_GET_ACTIVITY_COLS 32
int num_backends = pgstat_fetch_stat_numbackends();
int curr_backend;
int pid = PG_ARGISNULL(0) ? -1 : PG_GETARG_INT32(0);
@@ -370,6 +371,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
PGPROC *proc;
const char *wait_event_type = NULL;
const char *wait_event = NULL;
+ uint32 wait_event_arg = 0;
/* Get the next one in the list */
local_beentry = pgstat_get_local_beentry_by_index(curr_backend);
@@ -398,14 +400,14 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[3] = true;
if (TransactionIdIsValid(local_beentry->backend_xid))
- values[15] = TransactionIdGetDatum(local_beentry->backend_xid);
+ values[16] = TransactionIdGetDatum(local_beentry->backend_xid);
else
- nulls[15] = true;
+ nulls[16] = true;
if (TransactionIdIsValid(local_beentry->backend_xmin))
- values[16] = TransactionIdGetDatum(local_beentry->backend_xmin);
+ values[17] = TransactionIdGetDatum(local_beentry->backend_xmin);
else
- nulls[16] = true;
+ nulls[17] = true;
/* Values only available to role member or pg_read_all_stats */
if (HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
@@ -445,7 +447,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
pfree(clipped_activity);
/* leader_pid */
- nulls[29] = true;
+ nulls[30] = true;
proc = BackendPidGetProc(beentry->st_procpid);
@@ -466,12 +468,13 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (proc != NULL)
{
- uint32 raw_wait_event;
+ uint64 raw_wait_event;
PGPROC *leader;
- raw_wait_event = UINT32_ACCESS_ONCE(proc->wait_event_info);
+ raw_wait_event = UINT64_ACCESS_ONCE(proc->wait_event_info);
wait_event_type = pgstat_get_wait_event_type(raw_wait_event);
wait_event = pgstat_get_wait_event(raw_wait_event);
+ wait_event_arg = pgstat_get_wait_event_arg(raw_wait_event);
leader = proc->lockGroupLeader;
@@ -482,8 +485,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (leader && leader->pid != beentry->st_procpid)
{
- values[29] = Int32GetDatum(leader->pid);
- nulls[29] = false;
+ values[30] = Int32GetDatum(leader->pid);
+ nulls[30] = false;
}
else if (beentry->st_backendType == B_BG_WORKER)
{
@@ -491,8 +494,8 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (leader_pid != InvalidPid)
{
- values[29] = Int32GetDatum(leader_pid);
- nulls[29] = false;
+ values[30] = Int32GetDatum(leader_pid);
+ nulls[30] = false;
}
}
}
@@ -507,6 +510,11 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
else
nulls[7] = true;
+ if (wait_event_arg)
+ values[8] = UInt32GetDatum(wait_event_arg);
+ else
+ nulls[8] = true;
+
/*
* Don't expose transaction time for walsenders; it confuses
* monitoring, particularly because we don't keep the time up-to-
@@ -514,32 +522,32 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
*/
if (beentry->st_xact_start_timestamp != 0 &&
beentry->st_backendType != B_WAL_SENDER)
- values[8] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
+ values[9] = TimestampTzGetDatum(beentry->st_xact_start_timestamp);
else
- nulls[8] = true;
+ nulls[9] = true;
if (beentry->st_activity_start_timestamp != 0)
- values[9] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
+ values[10] = TimestampTzGetDatum(beentry->st_activity_start_timestamp);
else
- nulls[9] = true;
+ nulls[10] = true;
if (beentry->st_proc_start_timestamp != 0)
- values[10] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
+ values[11] = TimestampTzGetDatum(beentry->st_proc_start_timestamp);
else
- nulls[10] = true;
+ nulls[11] = true;
if (beentry->st_state_start_timestamp != 0)
- values[11] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
+ values[12] = TimestampTzGetDatum(beentry->st_state_start_timestamp);
else
- nulls[11] = true;
+ nulls[12] = true;
/* A zeroed client addr means we don't know */
if (pg_memory_is_all_zeros(&beentry->st_clientaddr,
sizeof(beentry->st_clientaddr)))
{
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
else
{
@@ -560,20 +568,20 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
if (ret == 0)
{
clean_ipv6_addr(beentry->st_clientaddr.addr.ss_family, remote_host);
- values[12] = DirectFunctionCall1(inet_in,
+ values[13] = DirectFunctionCall1(inet_in,
CStringGetDatum(remote_host));
if (beentry->st_clienthostname &&
beentry->st_clienthostname[0])
- values[13] = CStringGetTextDatum(beentry->st_clienthostname);
+ values[14] = CStringGetTextDatum(beentry->st_clienthostname);
else
- nulls[13] = true;
- values[14] = Int32GetDatum(atoi(remote_port));
+ nulls[14] = true;
+ values[15] = Int32GetDatum(atoi(remote_port));
}
else
{
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
}
else if (beentry->st_clientaddr.addr.ss_family == AF_UNIX)
@@ -584,16 +592,16 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
* connections we have no permissions to view, or with
* errors.
*/
- nulls[12] = true;
nulls[13] = true;
- values[14] = Int32GetDatum(-1);
+ nulls[14] = true;
+ values[15] = Int32GetDatum(-1);
}
else
{
/* Unknown address type, should never happen */
- nulls[12] = true;
nulls[13] = true;
nulls[14] = true;
+ nulls[15] = true;
}
}
/* Add backend type */
@@ -603,68 +611,68 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
bgw_type = GetBackgroundWorkerTypeByPid(beentry->st_procpid);
if (bgw_type)
- values[17] = CStringGetTextDatum(bgw_type);
+ values[18] = CStringGetTextDatum(bgw_type);
else
- nulls[17] = true;
+ nulls[18] = true;
}
else
- values[17] =
+ values[18] =
CStringGetTextDatum(GetBackendTypeDesc(beentry->st_backendType));
/* SSL information */
if (beentry->st_ssl)
{
- values[18] = BoolGetDatum(true); /* ssl */
- values[19] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
- values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
- values[21] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
+ values[19] = BoolGetDatum(true); /* ssl */
+ values[20] = CStringGetTextDatum(beentry->st_sslstatus->ssl_version);
+ values[21] = CStringGetTextDatum(beentry->st_sslstatus->ssl_cipher);
+ values[22] = Int32GetDatum(beentry->st_sslstatus->ssl_bits);
if (beentry->st_sslstatus->ssl_client_dn[0])
- values[22] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
+ values[23] = CStringGetTextDatum(beentry->st_sslstatus->ssl_client_dn);
else
- nulls[22] = true;
+ nulls[23] = true;
if (beentry->st_sslstatus->ssl_client_serial[0])
- values[23] = DirectFunctionCall3(numeric_in,
+ values[24] = DirectFunctionCall3(numeric_in,
CStringGetDatum(beentry->st_sslstatus->ssl_client_serial),
ObjectIdGetDatum(InvalidOid),
Int32GetDatum(-1));
else
- nulls[23] = true;
+ nulls[24] = true;
if (beentry->st_sslstatus->ssl_issuer_dn[0])
- values[24] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
+ values[25] = CStringGetTextDatum(beentry->st_sslstatus->ssl_issuer_dn);
else
- nulls[24] = true;
+ nulls[25] = true;
}
else
{
- values[18] = BoolGetDatum(false); /* ssl */
- nulls[19] = nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = true;
+ values[19] = BoolGetDatum(false); /* ssl */
+ nulls[20] = nulls[21] = nulls[22] = nulls[23] = nulls[24] = nulls[25] = true;
}
/* GSSAPI information */
if (beentry->st_gss)
{
- values[25] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
- values[26] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
- values[27] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
- values[28] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
+ values[26] = BoolGetDatum(beentry->st_gssstatus->gss_auth); /* gss_auth */
+ values[27] = CStringGetTextDatum(beentry->st_gssstatus->gss_princ);
+ values[28] = BoolGetDatum(beentry->st_gssstatus->gss_enc); /* GSS Encryption in use */
+ values[29] = BoolGetDatum(beentry->st_gssstatus->gss_delegation); /* GSS credentials
* delegated */
}
else
{
- values[25] = BoolGetDatum(false); /* gss_auth */
- nulls[26] = true; /* No GSS principal */
- values[27] = BoolGetDatum(false); /* GSS Encryption not in
+ values[26] = BoolGetDatum(false); /* gss_auth */
+ nulls[27] = true; /* No GSS principal */
+ values[28] = BoolGetDatum(false); /* GSS Encryption not in
* use */
- values[28] = BoolGetDatum(false); /* GSS credentials not
+ values[29] = BoolGetDatum(false); /* GSS credentials not
* delegated */
}
if (beentry->st_query_id == INT64CONST(0))
- nulls[30] = true;
+ nulls[31] = true;
else
- values[30] = Int64GetDatum(beentry->st_query_id);
+ values[31] = Int64GetDatum(beentry->st_query_id);
}
else
{
@@ -694,6 +702,7 @@ pg_stat_get_activity(PG_FUNCTION_ARGS)
nulls[28] = true;
nulls[29] = true;
nulls[30] = true;
+ nulls[31] = true;
}
tuplestore_putvalues(rsinfo->setResult, rsinfo->setDesc, values, nulls);
@@ -830,7 +839,7 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
if (!proc)
proc = AuxiliaryPidGetProc(beentry->st_procpid);
if (proc)
- wait_event_type = pgstat_get_wait_event_type(proc->wait_event_info);
+ wait_event_type = pgstat_get_wait_event_type(pg_atomic_read_u64((&proc->wait_event_info)));
}
if (!wait_event_type)
@@ -857,7 +866,7 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
if (!proc)
proc = AuxiliaryPidGetProc(beentry->st_procpid);
if (proc)
- wait_event = pgstat_get_wait_event(proc->wait_event_info);
+ wait_event = pgstat_get_wait_event(pg_atomic_read_u64((&proc->wait_event_info)));
}
if (!wait_event)
diff --git a/src/backend/utils/adt/waitfuncs.c b/src/backend/utils/adt/waitfuncs.c
index 135e7ba8a7a..5dde2fa75f4 100644
--- a/src/backend/utils/adt/waitfuncs.c
+++ b/src/backend/utils/adt/waitfuncs.c
@@ -20,8 +20,6 @@
#include "utils/fmgrprotos.h"
#include "utils/wait_event.h"
-#define UINT32_ACCESS_ONCE(var) ((uint32)(*((volatile uint32 *)&(var))))
-
/*
* pg_isolation_test_session_is_blocked - support function for isolationtester
@@ -56,7 +54,7 @@ pg_isolation_test_session_is_blocked(PG_FUNCTION_ARGS)
if (proc == NULL)
PG_RETURN_BOOL(false); /* session gone: definitely unblocked */
wait_event_type =
- pgstat_get_wait_event_type(UINT32_ACCESS_ONCE(proc->wait_event_info));
+ pgstat_get_wait_event_type(pg_atomic_read_u64(&proc->wait_event_info));
if (wait_event_type && strcmp("InjectionPoint", wait_event_type) == 0)
PG_RETURN_BOOL(true);
diff --git a/src/include/access/xlogarchive.h b/src/include/access/xlogarchive.h
index c8a97372e35..50e2c1d376c 100644
--- a/src/include/access/xlogarchive.h
+++ b/src/include/access/xlogarchive.h
@@ -21,7 +21,7 @@ extern bool RestoreArchivedFile(char *path, const char *xlogfname,
const char *recovername, off_t expectedSize,
bool cleanupEnabled);
extern void ExecuteRecoveryCommand(const char *command, const char *commandName,
- bool failOnSignal, uint32 wait_event_info);
+ bool failOnSignal, uint64 wait_event_info);
extern void KeepFileRestoredFromArchive(const char *path, const char *xlogfname);
extern void XLogArchiveNotify(const char *xlog);
extern void XLogArchiveNotifySeg(XLogSegNo segno, TimeLineID tli);
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index dac40992cbc..17260361495 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5663,9 +5663,9 @@
proname => 'pg_stat_get_activity', prorows => '100', proisstrict => 'f',
proretset => 't', provolatile => 's', proparallel => 'r',
prorettype => 'record', proargtypes => 'int4',
- proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8}',
- proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
- proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
+ proallargtypes => '{int4,oid,int4,oid,text,text,text,text,text,int4,timestamptz,timestamptz,timestamptz,timestamptz,inet,text,int4,xid,xid,text,bool,text,text,int4,text,numeric,text,bool,text,bool,bool,int4,int8}',
+ proargmodes => '{i,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o,o}',
+ proargnames => '{pid,datid,pid,usesysid,application_name,state,query,wait_event_type,wait_event,wait_event_arg,xact_start,query_start,backend_start,state_change,client_addr,client_hostname,client_port,backend_xid,backend_xmin,backend_type,ssl,sslversion,sslcipher,sslbits,ssl_client_dn,ssl_client_serial,ssl_issuer_dn,gss_auth,gss_princ,gss_enc,gss_delegation,leader_pid,query_id}',
prosrc => 'pg_stat_get_activity' },
{ oid => '6318', descr => 'describe wait events',
proname => 'pg_get_wait_events', procost => '10', prorows => '250',
diff --git a/src/include/libpq/libpq-be-fe-helpers.h b/src/include/libpq/libpq-be-fe-helpers.h
index 85d8b63f019..ca4e5ee2139 100644
--- a/src/include/libpq/libpq-be-fe-helpers.h
+++ b/src/include/libpq/libpq-be-fe-helpers.h
@@ -39,9 +39,9 @@
static inline void libpqsrv_connect_prepare(void);
-static inline void libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info);
-static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info);
-static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info);
+static inline void libpqsrv_connect_internal(PGconn *conn, uint64 wait_event_info);
+static inline PGresult *libpqsrv_get_result_last(PGconn *conn, uint64 wait_event_info);
+static inline PGresult *libpqsrv_get_result(PGconn *conn, uint64 wait_event_info);
/*
@@ -53,7 +53,7 @@ static inline PGresult *libpqsrv_get_result(PGconn *conn, uint32 wait_event_info
* check if connection establishment succeeded.
*/
static inline PGconn *
-libpqsrv_connect(const char *conninfo, uint32 wait_event_info)
+libpqsrv_connect(const char *conninfo, uint64 wait_event_info)
{
PGconn *conn = NULL;
@@ -74,7 +74,7 @@ static inline PGconn *
libpqsrv_connect_params(const char *const *keywords,
const char *const *values,
int expand_dbname,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
PGconn *conn = NULL;
@@ -147,7 +147,7 @@ libpqsrv_connect_prepare(void)
* Helper function for all connection establishment functions.
*/
static inline void
-libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)
+libpqsrv_connect_internal(PGconn *conn, uint64 wait_event_info)
{
/*
* With conn == NULL libpqsrv_disconnect() wouldn't release the FD. So do
@@ -243,7 +243,7 @@ libpqsrv_connect_internal(PGconn *conn, uint32 wait_event_info)
* notably, PQexec() would silently discard any prior query results.
*/
static inline PGresult *
-libpqsrv_exec(PGconn *conn, const char *query, uint32 wait_event_info)
+libpqsrv_exec(PGconn *conn, const char *query, uint64 wait_event_info)
{
if (!PQsendQuery(conn, query))
return NULL;
@@ -264,7 +264,7 @@ libpqsrv_exec_params(PGconn *conn,
const int *paramLengths,
const int *paramFormats,
int resultFormat,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
if (!PQsendQueryParams(conn, command, nParams, paramTypes, paramValues,
paramLengths, paramFormats, resultFormat))
@@ -277,7 +277,7 @@ libpqsrv_exec_params(PGconn *conn,
* terminal state. Return the last non-NULL result or the terminal state.
*/
static inline PGresult *
-libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)
+libpqsrv_get_result_last(PGconn *conn, uint64 wait_event_info)
{
PGresult *lastResult = NULL;
@@ -310,7 +310,7 @@ libpqsrv_get_result_last(PGconn *conn, uint32 wait_event_info)
* Perform the equivalent of PQgetResult(), but watch for interrupts.
*/
static inline PGresult *
-libpqsrv_get_result(PGconn *conn, uint32 wait_event_info)
+libpqsrv_get_result(PGconn *conn, uint64 wait_event_info)
{
/*
* Collect data until PQgetResult is ready to get the result without
diff --git a/src/include/storage/barrier.h b/src/include/storage/barrier.h
index 81b29d5cd52..0db4ed3a3f9 100644
--- a/src/include/storage/barrier.h
+++ b/src/include/storage/barrier.h
@@ -35,7 +35,7 @@ typedef struct Barrier
} Barrier;
extern void BarrierInit(Barrier *barrier, int participants);
-extern bool BarrierArriveAndWait(Barrier *barrier, uint32 wait_event_info);
+extern bool BarrierArriveAndWait(Barrier *barrier, uint64 wait_event_info);
extern bool BarrierArriveAndDetach(Barrier *barrier);
extern bool BarrierArriveAndDetachExceptLast(Barrier *barrier);
extern int BarrierAttach(Barrier *barrier);
diff --git a/src/include/storage/condition_variable.h b/src/include/storage/condition_variable.h
index 14bd6dd55c0..ddac3cf1e2a 100644
--- a/src/include/storage/condition_variable.h
+++ b/src/include/storage/condition_variable.h
@@ -53,9 +53,9 @@ extern void ConditionVariableInit(ConditionVariable *cv);
* be called to ensure that the process is no longer in the wait list for
* the condition variable.
*/
-extern void ConditionVariableSleep(ConditionVariable *cv, uint32 wait_event_info);
+extern void ConditionVariableSleep(ConditionVariable *cv, uint64 wait_event_info);
extern bool ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern bool ConditionVariableCancelSleep(void);
/*
diff --git a/src/include/storage/fd.h b/src/include/storage/fd.h
index 8ac466fd346..81151299f65 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -134,17 +134,17 @@ extern File PathNameOpenFile(const char *fileName, int fileFlags);
extern File PathNameOpenFilePerm(const char *fileName, int fileFlags, mode_t fileMode);
extern File OpenTemporaryFile(bool interXact);
extern void FileClose(File file);
-extern int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
-extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint32 wait_event_info);
-extern int FileSync(File file, uint32 wait_event_info);
-extern int FileZero(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
-extern int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint32 wait_event_info);
+extern int FilePrefetch(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
+extern ssize_t FileReadV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern ssize_t FileWriteV(File file, const struct iovec *iov, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern int FileStartReadV(struct PgAioHandle *ioh, File file, int iovcnt, pgoff_t offset, uint64 wait_event_info);
+extern int FileSync(File file, uint64 wait_event_info);
+extern int FileZero(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
+extern int FileFallocate(File file, pgoff_t offset, pgoff_t amount, uint64 wait_event_info);
extern pgoff_t FileSize(File file);
-extern int FileTruncate(File file, pgoff_t offset, uint32 wait_event_info);
-extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint32 wait_event_info);
+extern int FileTruncate(File file, pgoff_t offset, uint64 wait_event_info);
+extern void FileWriteback(File file, pgoff_t offset, pgoff_t nbytes, uint64 wait_event_info);
extern char *FilePathName(File file);
extern int FileGetRawDesc(File file);
extern int FileGetRawFlags(File file);
@@ -223,7 +223,7 @@ extern int data_sync_elevel(int elevel);
static inline ssize_t
FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
struct iovec iov = {
.iov_base = buffer,
@@ -235,7 +235,7 @@ FileRead(File file, void *buffer, size_t amount, pgoff_t offset,
static inline ssize_t
FileWrite(File file, const void *buffer, size_t amount, pgoff_t offset,
- uint32 wait_event_info)
+ uint64 wait_event_info)
{
struct iovec iov = {
.iov_base = unconstify(void *, buffer),
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index fbdadc86959..bc3dda333dc 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -132,9 +132,9 @@ extern void SetLatch(Latch *latch);
extern void ResetLatch(Latch *latch);
extern int WaitLatch(Latch *latch, int wakeEvents, long timeout,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern int WaitLatchOrSocket(Latch *latch, int wakeEvents,
- pgsocket sock, long timeout, uint32 wait_event_info);
+ pgsocket sock, long timeout, uint64 wait_event_info);
extern void InitializeLatchWaitSet(void);
#endif /* LATCH_H */
diff --git a/src/include/storage/lwlock.h b/src/include/storage/lwlock.h
index 9a0290391d0..d4417a94f7e 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -138,7 +138,7 @@ extern Size LWLockShmemSize(void);
extern void CreateLWLocks(void);
extern void InitLWLockAccess(void);
-extern const char *GetLWLockIdentifier(uint32 classId, uint16 eventId);
+extern const char *GetLWLockIdentifier(uint64 classId, uint16 eventId);
/*
* Extensions (or core code) can obtain an LWLocks by calling
diff --git a/src/include/storage/proc.h b/src/include/storage/proc.h
index a8d2e7db1a1..0e9790b57cd 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -373,7 +373,7 @@ typedef struct PGPROC
* Status reporting
************************************************************************/
- uint32 wait_event_info; /* proc's wait information */
+ volatile pg_atomic_uint64 wait_event_info; /* proc's wait information */
}
/*
@@ -575,7 +575,7 @@ extern void GetLockHoldersAndWaiters(LOCALLOCK *locallock,
StringInfo lock_waiters_sbuf,
int *lockHoldersNum);
-extern void ProcWaitForSignal(uint32 wait_event_info);
+extern void ProcWaitForSignal(uint64 wait_event_info);
extern void ProcSendSignal(ProcNumber procNumber);
extern PGPROC *AuxiliaryPidGetProc(int pid);
diff --git a/src/include/storage/waiteventset.h b/src/include/storage/waiteventset.h
index 5341267f0a0..e987fb32dfa 100644
--- a/src/include/storage/waiteventset.h
+++ b/src/include/storage/waiteventset.h
@@ -86,7 +86,7 @@ extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events,
struct Latch *latch);
extern int WaitEventSetWait(WaitEventSet *set, long timeout,
WaitEvent *occurred_events, int nevents,
- uint32 wait_event_info);
+ uint64 wait_event_info);
extern int GetNumRegisteredWaitEvents(WaitEventSet *set);
extern bool WaitEventSetCanReportClosed(void);
diff --git a/src/include/utils/wait_classes.h b/src/include/utils/wait_classes.h
index b91690a22c6..edfff7ddb42 100644
--- a/src/include/utils/wait_classes.h
+++ b/src/include/utils/wait_classes.h
@@ -15,15 +15,15 @@
* Wait Classes
* ----------
*/
-#define PG_WAIT_LWLOCK 0x01000000U
-#define PG_WAIT_LOCK 0x03000000U
-#define PG_WAIT_BUFFER 0x04000000U
-#define PG_WAIT_ACTIVITY 0x05000000U
-#define PG_WAIT_CLIENT 0x06000000U
-#define PG_WAIT_EXTENSION 0x07000000U
-#define PG_WAIT_IPC 0x08000000U
-#define PG_WAIT_TIMEOUT 0x09000000U
-#define PG_WAIT_IO 0x0A000000U
-#define PG_WAIT_INJECTIONPOINT 0x0B000000U
+#define PG_WAIT_LWLOCK 0x0100000000000000ULL
+#define PG_WAIT_LOCK 0x0300000000000000ULL
+#define PG_WAIT_BUFFER 0x0400000000000000ULL
+#define PG_WAIT_ACTIVITY 0x0500000000000000ULL
+#define PG_WAIT_CLIENT 0x0600000000000000ULL
+#define PG_WAIT_EXTENSION 0x0700000000000000ULL
+#define PG_WAIT_IPC 0x0800000000000000ULL
+#define PG_WAIT_TIMEOUT 0x0900000000000000ULL
+#define PG_WAIT_IO 0x0A00000000000000ULL
+#define PG_WAIT_INJECTIONPOINT 0x0B00000000000000ULL
#endif /* WAIT_CLASSES_H */
diff --git a/src/include/utils/wait_event.h b/src/include/utils/wait_event.h
index 34c27cc3dc3..a3a33bfd208 100644
--- a/src/include/utils/wait_event.h
+++ b/src/include/utils/wait_event.h
@@ -12,15 +12,17 @@
/* enums for wait events */
#include "utils/wait_event_types.h"
+#include "port/atomics.h"
-extern const char *pgstat_get_wait_event(uint32 wait_event_info);
-extern const char *pgstat_get_wait_event_type(uint32 wait_event_info);
-static inline void pgstat_report_wait_start(uint32 wait_event_info);
+extern const char *pgstat_get_wait_event(uint64 wait_event_info);
+extern const char *pgstat_get_wait_event_type(uint64 wait_event_info);
+extern uint32 pgstat_get_wait_event_arg(uint64 wait_event_info);
+static inline void pgstat_report_wait_start(uint64 wait_event_info);
static inline void pgstat_report_wait_end(void);
-extern void pgstat_set_wait_event_storage(uint32 *wait_event_info);
+extern void pgstat_set_wait_event_storage(volatile pg_atomic_uint64 *wait_event_info);
extern void pgstat_reset_wait_event_storage(void);
-extern PGDLLIMPORT uint32 *my_wait_event_info;
+extern PGDLLIMPORT volatile pg_atomic_uint64 *my_wait_event_info;
/*
@@ -39,23 +41,27 @@ extern PGDLLIMPORT uint32 *my_wait_event_info;
*
* The ID retrieved can be used with pgstat_report_wait_start() or equivalent.
*/
-extern uint32 WaitEventExtensionNew(const char *wait_event_name);
-extern uint32 WaitEventInjectionPointNew(const char *wait_event_name);
+extern uint64 WaitEventExtensionNew(const char *wait_event_name);
+extern uint64 WaitEventInjectionPointNew(const char *wait_event_name);
extern void WaitEventCustomShmemInit(void);
extern Size WaitEventCustomShmemSize(void);
-extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
+extern char **GetWaitEventCustomNames(uint64 classId, int *nwaitevents);
/* ----------
* pgstat_report_wait_start() -
*
* Called from places where server process needs to wait. This is called
* to report wait event information. The wait information is stored
- * as 4-bytes where first byte represents the wait event class (type of
- * wait, for different types of wait, refer WaitClass) and the next
- * 3-bytes represent the actual wait event. Currently 2-bytes are used
- * for wait event which is sufficient for current usage, 1-byte is
- * reserved for future usage.
+ * as 8-bytes where:
+ * - first byte represents the wait event class (type of wait, for different
+ * types of wait, refer WaitClass)
+ * - the next 3-bytes represent the actual wait event. Out of which:
+ * -- currently 2-bytes are used for wait event which is sufficient for
+ * current usage,
+ * -- 1-byte is reserved for future usage.
+ * - the remaining 4-bytes are used to store additional per wait-event
+ * details
*
* Historically we used to make this reporting conditional on
* pgstat_track_activities, but the check for that seems to add more cost
@@ -66,13 +72,13 @@ extern char **GetWaitEventCustomNames(uint32 classId, int *nwaitevents);
* ----------
*/
static inline void
-pgstat_report_wait_start(uint32 wait_event_info)
+pgstat_report_wait_start(uint64 wait_event_info)
{
/*
- * Since this is a four-byte field which is always read and written as
- * four-bytes, updates are atomic.
+ * Since this is a eight-byte field which is always read and written as
+ * eight-bytes, updates should be on most platforms atomic.
*/
- *(volatile uint32 *) my_wait_event_info = wait_event_info;
+ pg_atomic_write_u64(my_wait_event_info, wait_event_info);
}
/* ----------
@@ -85,7 +91,7 @@ static inline void
pgstat_report_wait_end(void)
{
/* see pgstat_report_wait_start() */
- *(volatile uint32 *) my_wait_event_info = 0;
+ pg_atomic_write_u64(my_wait_event_info, 0);
}
diff --git a/src/test/modules/injection_points/injection_points.c b/src/test/modules/injection_points/injection_points.c
index 3de0491e0ec..15dfe7a3d72 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -267,7 +267,7 @@ injection_wait(const char *name, const void *private_data, void *arg)
{
uint32 old_wait_counts = 0;
int index = -1;
- uint32 injection_wait_event = 0;
+ uint64 injection_wait_event = 0;
const InjectionPointCondition *condition = private_data;
if (inj_state == NULL)
diff --git a/src/test/modules/test_shm_mq/setup.c b/src/test/modules/test_shm_mq/setup.c
index 36bb255922c..783cb954222 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -41,7 +41,7 @@ static void wait_for_workers_to_become_ready(worker_state *wstate,
static bool check_worker_status(worker_state *wstate);
/* value cached, fetched from shared memory */
-static uint32 we_bgworker_startup = 0;
+static uint64 we_bgworker_startup = 0;
/*
* Set up a dynamic shared memory segment and zero or more background workers
diff --git a/src/test/modules/test_shm_mq/test.c b/src/test/modules/test_shm_mq/test.c
index ce97e6e1aa4..20d4d2192c4 100644
--- a/src/test/modules/test_shm_mq/test.c
+++ b/src/test/modules/test_shm_mq/test.c
@@ -30,7 +30,7 @@ static void verify_message(Size origlen, char *origdata, Size newlen,
char *newdata);
/* value cached, fetched from shared memory */
-static uint32 we_message_queue = 0;
+static uint64 we_message_queue = 0;
/*
* Simple test of the shared memory message queue infrastructure.
diff --git a/src/test/modules/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index d1e4a2bd952..3f51706d7fb 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -53,7 +53,7 @@ static char *worker_spi_database = NULL;
static char *worker_spi_role = NULL;
/* value cached, fetched from shared memory */
-static uint32 worker_spi_wait_event_main = 0;
+static uint64 worker_spi_wait_event_main = 0;
typedef struct worktable
{
diff --git a/src/test/regress/expected/rules.out b/src/test/regress/expected/rules.out
index 78a37d9fc8f..27d508bd2a3 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1792,13 +1792,14 @@ pg_stat_activity| SELECT s.datid,
s.state_change,
s.wait_event_type,
s.wait_event,
+ s.wait_event_arg,
s.state,
s.backend_xid,
s.backend_xmin,
s.query_id,
s.query,
s.backend_type
- FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
LEFT JOIN pg_database d ON ((s.datid = d.oid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_all_indexes| SELECT c.oid AS relid,
@@ -1928,7 +1929,7 @@ pg_stat_gssapi| SELECT pid,
gss_princ AS principal,
gss_enc AS encrypted,
gss_delegation AS credentials_delegated
- FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
WHERE (client_port IS NOT NULL);
pg_stat_io| SELECT backend_type,
object,
@@ -2158,7 +2159,7 @@ pg_stat_replication| SELECT s.pid,
w.sync_priority,
w.sync_state,
w.reply_time
- FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM ((pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
JOIN pg_stat_get_wal_senders() w(pid, state, sent_lsn, write_lsn, flush_lsn, replay_lsn, write_lag, flush_lag, replay_lag, sync_priority, sync_state, reply_time) ON ((s.pid = w.pid)))
LEFT JOIN pg_authid u ON ((s.usesysid = u.oid)));
pg_stat_replication_slots| SELECT s.slot_name,
@@ -2195,7 +2196,7 @@ pg_stat_ssl| SELECT pid,
ssl_client_dn AS client_dn,
ssl_client_serial AS client_serial,
ssl_issuer_dn AS issuer_dn
- FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
+ FROM pg_stat_get_activity(NULL::integer) s(datid, pid, usesysid, application_name, state, query, wait_event_type, wait_event, wait_event_arg, xact_start, query_start, backend_start, state_change, client_addr, client_hostname, client_port, backend_xid, backend_xmin, backend_type, ssl, sslversion, sslcipher, sslbits, ssl_client_dn, ssl_client_serial, ssl_issuer_dn, gss_auth, gss_princ, gss_enc, gss_delegation, leader_pid, query_id)
WHERE (client_port IS NOT NULL);
pg_stat_subscription| SELECT su.oid AS subid,
su.subname,
--
2.43.0