mirror of
https://github.com/postgres/postgres.git
synced 2025-05-08 07:21:33 +03:00
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
This commit is contained in:
parent
d1b90995e8
commit
c8f3bc2401
@ -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)
|
|||||||
#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)
|
|||||||
|
|
||||||
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)
|
|||||||
{
|
{
|
||||||
/* 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,
|
|||||||
* 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,
|
|||||||
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,
|
|||||||
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 @@
|
|||||||
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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user