From 342c2d5037620763ac20f571a3af3d4d06516b82 Mon Sep 17 00:00:00 2001
From: Jakub Wartak <jakub.wartak@enterprisedb.com>
Date: Wed, 12 Nov 2025 12:14:16 +0100
Subject: [PATCH v3 1/2] Convert wait_event_info to 64-bits, expose lower
 32-bit as new wait_event_arg

Provide also some very basic wait_event_arg demos.
---
 contrib/dblink/dblink.c                       |   2 +-
 contrib/postgres_fdw/connection.c             |   6 +-
 src/backend/access/transam/xlogarchive.c      |   2 +-
 src/backend/catalog/system_views.sql          |   1 +
 src/backend/replication/syncrep.c             |  48 ++++++-
 src/backend/replication/walsender.c           |  10 +-
 src/backend/storage/aio/aio_io.c              |   6 +-
 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             |   6 +-
 src/backend/storage/ipc/waiteventset.c        |   2 +-
 src/backend/storage/lmgr/condition_variable.c |   4 +-
 src/backend/storage/lmgr/lwlock.c             |   5 +-
 src/backend/storage/lmgr/proc.c               |   7 +-
 src/backend/storage/lmgr/s_lock.c             |   2 +-
 src/backend/storage/smgr/md.c                 |   3 +-
 src/backend/utils/activity/backend_status.c   |   3 +-
 .../activity/generate-wait_event_types.pl     |  12 +-
 src/backend/utils/activity/wait_event.c       |  88 ++++++++-----
 src/backend/utils/adt/misc.c                  |   3 +-
 src/backend/utils/adt/pgstatfuncs.c           | 124 ++++++++++--------
 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                |  43 +++---
 .../injection_points/injection_points.c       |   2 +-
 src/test/modules/test_shm_mq/setup.c          |   2 +-
 src/test/modules/worker_spi/worker_spi.c      |   2 +-
 src/test/regress/expected/rules.out           |   9 +-
 39 files changed, 301 insertions(+), 207 deletions(-)

diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index 8bf8fc8ea2f..aa4ae8ec480 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -144,7 +144,7 @@ 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 uint64 dblink_we_get_conn = 0;
 static uint32 dblink_we_get_result = 0;
 
 /*
diff --git a/contrib/postgres_fdw/connection.c b/contrib/postgres_fdw/connection.c
index 953c2e0ab82..49e80029465 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 1ef1713c91a..59547e1e3da 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/catalog/system_views.sql b/src/backend/catalog/system_views.sql
index 086c4c8fb6f..b8bd711f0e3 100644
--- a/src/backend/catalog/system_views.sql
+++ b/src/backend/catalog/system_views.sql
@@ -915,6 +915,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/syncrep.c b/src/backend/replication/syncrep.c
index a0c79958fd5..c624bb919b6 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -78,6 +78,7 @@
 #include "common/int.h"
 #include "miscadmin.h"
 #include "pgstat.h"
+#include "portability/instr_time.h"
 #include "replication/syncrep.h"
 #include "replication/walsender.h"
 #include "replication/walsender_private.h"
@@ -270,7 +271,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
 	 */
 	for (;;)
 	{
-		int			rc;
+		int			rc, i;
+		uint32_t	wait_event_arg_pid;
 
 		/* Must reset the latch before testing state. */
 		ResetLatch(MyLatch);
@@ -328,8 +330,48 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
 		 * Wait on latch.  Any condition that should wake us up will set the
 		 * latch, so no need for timeout.
 		 */
-		rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
-					   WAIT_EVENT_SYNC_REP);
+
+
+		/*
+		 * XXX/DEMO syncrep get pid of LSN, performance impact of spinlocking here is unknown
+		 */
+		for (i = 0; i < max_wal_senders; i++)
+		{
+			WalSnd *walsnd = &WalSndCtl->walsnds[i];
+			XLogRecPtr wallsn;
+			pid_t walpid;
+
+			/* potentially we could NOT take those spinlocks to not loose performance? */
+			SpinLockAcquire(&walsnd->mutex);
+			walpid = walsnd->pid;
+			switch (mode)
+			{
+				case SYNC_REP_WAIT_WRITE:
+					wallsn = walsnd->write;
+					break;
+				case SYNC_REP_WAIT_FLUSH:
+					wallsn = walsnd->flush;
+					break;
+				case SYNC_REP_WAIT_APPLY:
+					wallsn = walsnd->apply;
+					break;
+				default:
+					wallsn = InvalidXLogRecPtr;
+			}
+			SpinLockRelease(&walsnd->mutex);
+			if (walpid == 0)
+				continue;
+
+			//elog(LOG, "walpid %d analysis, our LSN=%X/%08X walsndLSN=%X/%08X", walpid, LSN_FORMAT_ARGS(lsn), LSN_FORMAT_ARGS(wallsn));
+
+			if(wallsn <= lsn) {
+				elog(LOG, "walpid %d selected", walpid);
+				wait_event_arg_pid = walpid;
+				break;
+			}
+		}
+		rc = WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_TIMEOUT, 100,
+					   WAIT_EVENT_SYNC_REP | wait_event_arg_pid);
 
 		/*
 		 * If the postmaster dies, we'll probably never get an acknowledgment,
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index fc8f8559073..76c9e0273c5 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,
@@ -1754,7 +1754,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;
@@ -1787,7 +1787,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)
@@ -1817,7 +1817,7 @@ static XLogRecPtr
 WalSndWaitForWal(XLogRecPtr loc)
 {
 	int			wakeEvents;
-	uint32		wait_event = 0;
+	uint64		wait_event = 0;
 	static XLogRecPtr RecentFlushPtr = InvalidXLogRecPtr;
 	TimestampTz last_flush = 0;
 
@@ -3811,7 +3811,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/aio/aio_io.c b/src/backend/storage/aio/aio_io.c
index 7d11d40284a..4efd76e7671 100644
--- a/src/backend/storage/aio/aio_io.c
+++ b/src/backend/storage/aio/aio_io.c
@@ -124,14 +124,16 @@ pgaio_io_perform_synchronously(PgAioHandle *ioh)
 	switch ((PgAioOp) ioh->op)
 	{
 		case PGAIO_OP_READV:
-			pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_READ);
+			/* FIXME DEMO just use fd for short demo, as i dont know how to get relationId from here */
+			pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_READ | ioh->op_data.read.fd);
 			result = pg_preadv(ioh->op_data.read.fd, iov,
 							   ioh->op_data.read.iov_length,
 							   ioh->op_data.read.offset);
 			pgstat_report_wait_end();
 			break;
 		case PGAIO_OP_WRITEV:
-			pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_WRITE);
+			/* FIXME DEMO just use fd for short demo, as i dont know how to get relationId from here */
+			pgstat_report_wait_start(WAIT_EVENT_DATA_FILE_WRITE | ioh->op_data.write.fd);
 			result = pg_pwritev(ioh->op_data.write.fd, iov,
 								ioh->op_data.write.iov_length,
 								ioh->op_data.write.offset);
diff --git a/src/backend/storage/file/fd.c b/src/backend/storage/file/fd.c
index e9eaaf9c829..c549832e39d 100644
--- a/src/backend/storage/file/fd.c
+++ b/src/backend/storage/file/fd.c
@@ -2077,7 +2077,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));
 
@@ -2133,7 +2133,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;
 
@@ -2160,7 +2160,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;
@@ -2217,7 +2217,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;
@@ -2242,7 +2242,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;
@@ -2346,7 +2346,7 @@ retry:
 }
 
 int
-FileSync(File file, uint32 wait_event_info)
+FileSync(File file, uint64 wait_event_info)
 {
 	int			returnCode;
 
@@ -2373,7 +2373,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;
@@ -2418,7 +2418,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;
@@ -2475,7 +2475,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 cb99c5f06b0..27bfadbf2e4 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 beadeb5e46a..92902a2c7b6 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 4222bdab078..65b3ed9cbd4 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,
 												   ProcSignalReason reason,
-												   uint32 wait_event_info,
+												   uint64 wait_event_info,
 												   bool report_waiting);
 static void SendRecoveryConflictWithBufferPin(ProcSignalReason 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;
 
@@ -358,7 +358,7 @@ LogRecoveryConflict(ProcSignalReason reason, TimestampTz wait_start,
  */
 static void
 ResolveRecoveryConflictWithVirtualXIDs(VirtualTransactionId *waitlist,
-									   ProcSignalReason reason, uint32 wait_event_info,
+									   ProcSignalReason reason, uint64 wait_event_info,
 									   bool report_waiting)
 {
 	TimestampTz waitStart = 0;
diff --git a/src/backend/storage/ipc/waiteventset.c b/src/backend/storage/ipc/waiteventset.c
index 465cee40ccc..57770a4e08e 100644
--- a/src/backend/storage/ipc/waiteventset.c
+++ b/src/backend/storage/ipc/waiteventset.c
@@ -1037,7 +1037,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 59abc080ed2..2713d9536c0 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 255cfa8fa95..e703d6ae807 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,8 +770,9 @@ 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)
 {
+	// FIXME
 	Assert(classId == PG_WAIT_LWLOCK);
 	/* The event IDs are just tranche numbers. */
 	return GetLWTrancheName(eventId);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 1504fafe6d8..83bb46d9afa 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -523,7 +523,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;
@@ -1460,8 +1460,9 @@ ProcSleep(LOCALLOCK *locallock)
 		}
 		else
 		{
+			/* FIXME/review later */
 			(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) | locallock->tag.lock.locktag_field2);
 			ResetLatch(MyLatch);
 			/* check for deadlocks first, as that's probably log-worthy */
 			if (got_deadlock_timeout)
@@ -1981,7 +1982,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 d26e192f4bc..fe113b2b92d 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 e3f335a8340..a56d73ec2e4 100644
--- a/src/backend/storage/smgr/md.c
+++ b/src/backend/storage/smgr/md.c
@@ -890,7 +890,8 @@ mdreadv(SMgrRelation reln, ForkNumber forknum, BlockNumber blocknum,
 												reln->smgr_rlocator.locator.relNumber,
 												reln->smgr_rlocator.backend);
 			nbytes = FileReadV(v->mdfd_vfd, iov, iovcnt, seekpos,
-							   WAIT_EVENT_DATA_FILE_READ);
+							   WAIT_EVENT_DATA_FILE_READ | (uint32_t) v->mdfd_vfd);
+							   //WAIT_EVENT_DATA_FILE_READ | (uint32_t) reln->smgr_rlocator.locator.relNumber);
 			TRACE_POSTGRESQL_SMGR_MD_READ_DONE(forknum, blocknum,
 											   reln->smgr_rlocator.locator.spcOid,
 											   reln->smgr_rlocator.locator.dbOid,
diff --git a/src/backend/utils/activity/backend_status.c b/src/backend/utils/activity/backend_status.c
index a290cc4c975..2e3b5642dc9 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 5db13419f25..ec48b2a8098 100644
--- a/src/backend/utils/activity/generate-wait_event_types.pl
+++ b/src/backend/utils/activity/generate-wait_event_types.pl
@@ -192,6 +192,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 +201,24 @@ 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";
+				$counter = 1;
 			}
 			else
 			{
-				printf $h "%s\t%s", $continue, $wev->[0];
+				# Instead of simple emission of enum type like:
+				#	WAIT_EVENT_DATA_FILE_READ
+				# we emit for enum proper value like:
+				#	WAIT_EVENT_DATA_FILE_READ = PG_WAIT_IO + (21ULL << 32)
+				# because C doesnt allow for defining custom jumps
+				printf $h "%s\t%s = %s + (%dULL << 32)", $continue, $wev->[0], $pg_wait_class, $counter;
 				$continue = ",\n";
+				$counter++;
 			}
 			$firstpass = 0;
 
diff --git a/src/backend/utils/activity/wait_event.c b/src/backend/utils/activity/wait_event.c
index d9b8f34a355..8c0ce90442c 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,14 +73,14 @@ 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;
 
 
@@ -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;
 	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 */
@@ -250,7 +258,7 @@ WaitEventCustomNew(uint32 classId, const char *wait_event_name)
 	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 +281,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 +299,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 +311,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 +354,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 +378,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 +436,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 +447,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 +461,49 @@ 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_BUFFERPIN:
 			{
-				WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info;
+				WaitEventBufferPin w = (WaitEventBufferPin) wait_event_info & WAIT_EVENT_CLASSID_MASK;
+
 
 				event_name = pgstat_get_wait_bufferpin(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 +516,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 "pgstat_wait_event.c"
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index a365c432d34..7b28e775f5b 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -374,10 +374,11 @@ pg_sleep(PG_FUNCTION_ARGS)
 		else
 			break;
 
+		/* FIXME DEMO: we just save number of seconds into wait_event_arg */
 		(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 7e2ed69138a..24dbb195fae 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -30,9 +30,11 @@
 #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 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 +353,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 +372,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 +401,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 +448,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 +469,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 +486,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 +495,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 +511,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 +523,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 +569,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 +593,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 +612,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 +703,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);
@@ -825,7 +835,7 @@ pg_stat_get_backend_wait_event_type(PG_FUNCTION_ARGS)
 	else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
 		wait_event_type = "<insufficient privilege>";
 	else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
-		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)
 		PG_RETURN_NULL();
@@ -846,7 +856,7 @@ pg_stat_get_backend_wait_event(PG_FUNCTION_ARGS)
 	else if (!HAS_PGSTAT_PERMISSIONS(beentry->st_userid))
 		wait_event = "<insufficient privilege>";
 	else if ((proc = BackendPidGetProc(beentry->st_procpid)) != NULL)
-		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)
 		PG_RETURN_NULL();
diff --git a/src/backend/utils/adt/waitfuncs.c b/src/backend/utils/adt/waitfuncs.c
index f01cad72a0f..346844f22d4 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 6ed47e99f12..110ae2b1680 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 66af2d96d67..f15cb2587c5 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -5653,9 +5653,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 1c4a342090c..5adf391935a 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 4d8a95f4a4a..5bce133f22c 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 526c4ee1051..2137538b246 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 a1bdefec4a5..07158748fe3 100644
--- a/src/include/storage/fd.h
+++ b/src/include/storage/fd.h
@@ -107,17 +107,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);
@@ -196,7 +196,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,
@@ -208,7 +208,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 e41dc70785a..ddce0036519 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 8e0d0d233b4..54e72cd8860 100644
--- a/src/include/storage/lwlock.h
+++ b/src/include/storage/lwlock.h
@@ -142,7 +142,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 c6f5ebceefd..9c2258000e9 100644
--- a/src/include/storage/proc.h
+++ b/src/include/storage/proc.h
@@ -299,7 +299,7 @@ struct PGPROC
 	 */
 	TransactionId procArrayGroupMemberXid;
 
-	uint32		wait_event_info;	/* proc's wait information */
+	volatile pg_atomic_uint64 wait_event_info;	/* proc's wait information */
 
 	/* Support for group transaction status update. */
 	bool		clogGroupMember;	/* true, if member of clog group */
@@ -512,7 +512,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 dd514d52991..40eb121d4cd 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 51ee68397d5..36355a55b0c 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_BUFFERPIN			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_BUFFERPIN			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 f5815b4994a..fadd1b93740 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,14 @@ 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);
+	elog(DEBUG1, "setting my_wait_event_info = 0x%lX (%ld)", wait_event_info, wait_event_info);
 }
 
 /* ----------
@@ -85,7 +92,7 @@ static inline void
 pgstat_report_wait_end(void)
 {
 	/* see pgstat_report_wait_start() */
-	*(volatile uint32 *) my_wait_event_info = 0;
+	*(volatile uint64 *) 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 b7c1c58ea56..3cf4e2a8c45 100644
--- a/src/test/modules/injection_points/injection_points.c
+++ b/src/test/modules/injection_points/injection_points.c
@@ -284,7 +284,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;
 	InjectionPointCondition *condition = (InjectionPointCondition *) 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 2a20ffb1273..81c0a0d9a72 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -40,7 +40,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/worker_spi/worker_spi.c b/src/test/modules/worker_spi/worker_spi.c
index bea8339f464..fc9909ecb14 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 94e45dd4d57..2a24a042d04 100644
--- a/src/test/regress/expected/rules.out
+++ b/src/test/regress/expected/rules.out
@@ -1790,13 +1790,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,
@@ -1926,7 +1927,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,
@@ -2139,7 +2140,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,
@@ -2176,7 +2177,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

