diff options
author | Thomas Munro | 2021-02-28 22:51:15 +0000 |
---|---|---|
committer | Thomas Munro | 2021-02-28 23:44:12 +0000 |
commit | c8f3bc2401e7df7b79bae39dd3511c91f825b6a4 (patch) | |
tree | 740f9fecf0c3efb6a2aa338d5c47598edb4150af | |
parent | d1b90995e8d41df7e59efe48e98f26cd66baba9b (diff) |
Optimize latches to send fewer signals.
Don't send signals to processes that aren't sleeping.
Author: Andres Freund <[email protected]>
Discussion: https://postgr.es/m/CA+hUKGJjxPDpzBE0a3hyUywBvaZuC89yx3jK9RFZgfv_KHU7gg@mail.gmail.com
-rw-r--r-- | src/backend/storage/ipc/latch.c | 24 | ||||
-rw-r--r-- | src/include/storage/latch.h | 1 |
2 files changed, 25 insertions, 0 deletions
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c index 79b9627831..eacf8d51ea 100644 --- a/src/backend/storage/ipc/latch.c +++ b/src/backend/storage/ipc/latch.c @@ -274,6 +274,7 @@ void InitLatch(Latch *latch) { latch->is_set = false; + latch->maybe_sleeping = false; latch->owner_pid = MyProcPid; latch->is_shared = false; @@ -321,6 +322,7 @@ InitSharedLatch(Latch *latch) #endif latch->is_set = false; + latch->maybe_sleeping = false; latch->owner_pid = 0; latch->is_shared = true; } @@ -523,6 +525,10 @@ SetLatch(Latch *latch) latch->is_set = true; + pg_memory_barrier(); + if (!latch->maybe_sleeping) + return; + #ifndef WIN32 /* @@ -589,6 +595,7 @@ ResetLatch(Latch *latch) { /* Only the owner should reset the latch */ Assert(latch->owner_pid == MyProcPid); + Assert(latch->maybe_sleeping == false); latch->is_set = false; @@ -1270,6 +1277,14 @@ WaitEventSetWait(WaitEventSet *set, long timeout, * ordering, so that we cannot miss seeing is_set if a notification * has already been queued. */ + if (set->latch && !set->latch->is_set) + { + /* about to sleep on a latch */ + set->latch->maybe_sleeping = true; + pg_memory_barrier(); + /* and recheck */ + } + if (set->latch && set->latch->is_set) { occurred_events->fd = PGINVALID_SOCKET; @@ -1280,6 +1295,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout, occurred_events++; returned_events++; + /* could have been set above */ + set->latch->maybe_sleeping = false; + break; } @@ -1291,6 +1309,12 @@ WaitEventSetWait(WaitEventSet *set, long timeout, rc = WaitEventSetWaitBlock(set, cur_timeout, occurred_events, nevents); + if (set->latch) + { + Assert(set->latch->maybe_sleeping); + set->latch->maybe_sleeping = false; + } + if (rc == -1) break; /* timeout occurred */ else diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h index 1468f30a8e..393591be03 100644 --- a/src/include/storage/latch.h +++ b/src/include/storage/latch.h @@ -110,6 +110,7 @@ typedef struct Latch { sig_atomic_t is_set; + sig_atomic_t maybe_sleeping; bool is_shared; int owner_pid; #ifdef WIN32 |