Commit c8f3bc24 authored by Thomas Munro's avatar Thomas Munro

Optimize latches to send fewer signals.

Don't send signals to processes that aren't sleeping.

Author: Andres Freund <andres@anarazel.de>
Discussion: https://postgr.es/m/CA+hUKGJjxPDpzBE0a3hyUywBvaZuC89yx3jK9RFZgfv_KHU7gg@mail.gmail.com
parent d1b90995
...@@ -274,6 +274,7 @@ void ...@@ -274,6 +274,7 @@ void
InitLatch(Latch *latch) InitLatch(Latch *latch)
{ {
latch->is_set = false; latch->is_set = false;
latch->maybe_sleeping = false;
latch->owner_pid = MyProcPid; latch->owner_pid = MyProcPid;
latch->is_shared = false; latch->is_shared = false;
...@@ -321,6 +322,7 @@ InitSharedLatch(Latch *latch) ...@@ -321,6 +322,7 @@ InitSharedLatch(Latch *latch)
#endif #endif
latch->is_set = false; latch->is_set = false;
latch->maybe_sleeping = false;
latch->owner_pid = 0; latch->owner_pid = 0;
latch->is_shared = true; latch->is_shared = true;
} }
...@@ -523,6 +525,10 @@ SetLatch(Latch *latch) ...@@ -523,6 +525,10 @@ SetLatch(Latch *latch)
latch->is_set = true; latch->is_set = true;
pg_memory_barrier();
if (!latch->maybe_sleeping)
return;
#ifndef WIN32 #ifndef WIN32
/* /*
...@@ -589,6 +595,7 @@ ResetLatch(Latch *latch) ...@@ -589,6 +595,7 @@ ResetLatch(Latch *latch)
{ {
/* Only the owner should reset the latch */ /* Only the owner should reset the latch */
Assert(latch->owner_pid == MyProcPid); Assert(latch->owner_pid == MyProcPid);
Assert(latch->maybe_sleeping == false);
latch->is_set = false; latch->is_set = false;
...@@ -1270,6 +1277,14 @@ WaitEventSetWait(WaitEventSet *set, long timeout, ...@@ -1270,6 +1277,14 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
* ordering, so that we cannot miss seeing is_set if a notification * ordering, so that we cannot miss seeing is_set if a notification
* has already been queued. * 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) if (set->latch && set->latch->is_set)
{ {
occurred_events->fd = PGINVALID_SOCKET; occurred_events->fd = PGINVALID_SOCKET;
...@@ -1280,6 +1295,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout, ...@@ -1280,6 +1295,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
occurred_events++; occurred_events++;
returned_events++; returned_events++;
/* could have been set above */
set->latch->maybe_sleeping = false;
break; break;
} }
...@@ -1291,6 +1309,12 @@ WaitEventSetWait(WaitEventSet *set, long timeout, ...@@ -1291,6 +1309,12 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
rc = WaitEventSetWaitBlock(set, cur_timeout, rc = WaitEventSetWaitBlock(set, cur_timeout,
occurred_events, nevents); occurred_events, nevents);
if (set->latch)
{
Assert(set->latch->maybe_sleeping);
set->latch->maybe_sleeping = false;
}
if (rc == -1) if (rc == -1)
break; /* timeout occurred */ break; /* timeout occurred */
else else
......
...@@ -110,6 +110,7 @@ ...@@ -110,6 +110,7 @@
typedef struct Latch typedef struct Latch
{ {
sig_atomic_t is_set; sig_atomic_t is_set;
sig_atomic_t maybe_sleeping;
bool is_shared; bool is_shared;
int owner_pid; int owner_pid;
#ifdef WIN32 #ifdef WIN32
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment