From 6744818fe556f07fe6c004320fa18a15fbee98fd Mon Sep 17 00:00:00 2001 From: Thomas Munro Date: Fri, 10 Mar 2023 16:19:42 +1300 Subject: [PATCH 3/4] Use microsecond-based naps in walreceiver. Since anything based on timestamp differences is really in microseconds under the covers, we might as well use the new higher resolution API for waiting. --- src/backend/replication/walreceiver.c | 16 ++++++++-------- src/backend/utils/adt/timestamp.c | 20 ++++++++++++++++++++ src/include/utils/timestamp.h | 2 ++ 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index f6446da2d6..18c66c0c63 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -445,7 +445,7 @@ WalReceiverMain(void) pgsocket wait_fd = PGINVALID_SOCKET; int rc; TimestampTz nextWakeup; - long nap; + int64 nap; /* * Exit walreceiver if we're not in recovery. This should not @@ -530,7 +530,7 @@ WalReceiverMain(void) /* Calculate the nap time, clamping as necessary. */ now = GetCurrentTimestamp(); - nap = TimestampDifferenceMilliseconds(now, nextWakeup); + nap = TimestampDifferenceMicroseconds(now, nextWakeup); /* * Ideally we would reuse a WaitEventSet object repeatedly @@ -544,12 +544,12 @@ WalReceiverMain(void) * avoiding some system calls. */ Assert(wait_fd != PGINVALID_SOCKET); - rc = WaitLatchOrSocket(MyLatch, - WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | - WL_TIMEOUT | WL_LATCH_SET, - wait_fd, - nap, - WAIT_EVENT_WAL_RECEIVER_MAIN); + rc = WaitLatchOrSocketUs(MyLatch, + WL_EXIT_ON_PM_DEATH | WL_SOCKET_READABLE | + WL_TIMEOUT | WL_LATCH_SET, + wait_fd, + nap, + WAIT_EVENT_WAL_RECEIVER_MAIN); if (rc & WL_LATCH_SET) { ResetLatch(MyLatch); diff --git a/src/backend/utils/adt/timestamp.c b/src/backend/utils/adt/timestamp.c index de93db89d4..52f6568397 100644 --- a/src/backend/utils/adt/timestamp.c +++ b/src/backend/utils/adt/timestamp.c @@ -1719,6 +1719,26 @@ TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time) return (long) ((diff + 999) / 1000); } +/* + * TimestampDifferenceMicroseconds -- convert the difference between two + * timestamps into microseconds + * + * Compute a wait time for WaitLatchUs(). + */ +int64 +TimestampDifferenceMicroseconds(TimestampTz start_time, TimestampTz stop_time) +{ + TimestampTz diff; + + /* Deal with zero or negative elapsed time quickly. */ + if (start_time >= stop_time) + return 0; + /* To not fail with timestamp infinities, we must detect overflow. */ + if (pg_sub_s64_overflow(stop_time, start_time, &diff)) + return PG_INT64_MAX; + return diff; +} + /* * TimestampDifferenceExceeds -- report whether the difference between two * timestamps is >= a threshold (expressed in milliseconds) diff --git a/src/include/utils/timestamp.h b/src/include/utils/timestamp.h index edd59dc432..1caa15221d 100644 --- a/src/include/utils/timestamp.h +++ b/src/include/utils/timestamp.h @@ -100,6 +100,8 @@ extern void TimestampDifference(TimestampTz start_time, TimestampTz stop_time, long *secs, int *microsecs); extern long TimestampDifferenceMilliseconds(TimestampTz start_time, TimestampTz stop_time); +extern int64 TimestampDifferenceMicroseconds(TimestampTz start_time, + TimestampTz stop_time); extern bool TimestampDifferenceExceeds(TimestampTz start_time, TimestampTz stop_time, int msec); -- 2.39.2