latch / signal perf stuff: generic
authorAndres Freund <[email protected]>
Sat, 31 Oct 2020 00:12:09 +0000 (17:12 -0700)
committerAndres Freund <[email protected]>
Mon, 11 Jan 2021 23:09:14 +0000 (15:09 -0800)
Author:
Reviewed-By:
Discussion: https://postgr.es/m/
Backpatch:

14 files changed:
src/backend/libpq/pqsignal.c
src/backend/postmaster/autovacuum.c
src/backend/postmaster/bgworker.c
src/backend/postmaster/bgwriter.c
src/backend/postmaster/checkpointer.c
src/backend/postmaster/startup.c
src/backend/postmaster/walwriter.c
src/backend/replication/walreceiver.c
src/backend/replication/walsender.c
src/backend/storage/ipc/latch.c
src/backend/storage/ipc/procsignal.c
src/backend/tcop/postgres.c
src/include/libpq/pqsignal.h
src/include/storage/latch.h

index b43af220303e7905b02a2689a34cae997294302f..8d97b008ab65caebc9b02198eaea55c256654e3e 100644 (file)
@@ -19,7 +19,8 @@
 
 
 /* Global variables */
-sigset_t   UnBlockSig,
+sigset_t   SleepSig,
+           UnBlockSig,
            BlockSig,
            StartupBlockSig;
 
@@ -40,6 +41,7 @@ sigset_t  UnBlockSig,
 void
 pqinitmask(void)
 {
+   sigemptyset(&SleepSig);
    sigemptyset(&UnBlockSig);
 
    /* First set all signals, then clear some. */
@@ -94,6 +96,8 @@ pqinitmask(void)
 #ifdef SIGALRM
    sigdelset(&StartupBlockSig, SIGALRM);
 #endif
+
+   sigaddset(&UnBlockSig, SIGURG);
 }
 
 /*
index 47e60ca5613f8668258aabdf35d3bb73d8ab463f..211859f77d0e1b8600850f7a38f66a2a301173c6 100644 (file)
@@ -464,7 +464,9 @@ AutoVacLauncherMain(int argc, char *argv[])
 
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
+   pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, avl_sigusr2_handler);
+   pqsignal(SIGURG, latch_sigurg_handler);
    pqsignal(SIGFPE, FloatExceptionHandler);
    pqsignal(SIGCHLD, SIG_DFL);
 
@@ -1543,6 +1545,7 @@ AutoVacWorkerMain(int argc, char *argv[])
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, SIG_IGN);
+   pqsignal(SIGURG, latch_sigurg_handler);
    pqsignal(SIGFPE, FloatExceptionHandler);
    pqsignal(SIGCHLD, SIG_DFL);
 
index dd3dad3de35fa9fd5cd4313a22657cc20236a59f..c0282e882cdf04933e29b3fd4d330620dc9f02e8 100644 (file)
@@ -330,6 +330,7 @@ BackgroundWorkerStateChange(bool allow_new_workers)
            pg_memory_barrier();
            slot->pid = 0;
            slot->in_use = false;
+           /* FIXME: shouldn't this use SetLatch() or something */
            if (notify_pid != 0)
                kill(notify_pid, SIGUSR1);
 
@@ -779,6 +780,7 @@ StartBackgroundWorker(void)
         */
        pqsignal(SIGINT, StatementCancelHandler);
        pqsignal(SIGUSR1, procsignal_sigusr1_handler);
+       pqsignal(SIGURG, latch_sigurg_handler);
        pqsignal(SIGFPE, FloatExceptionHandler);
 
        /* XXX Any other handlers needed here? */
@@ -787,6 +789,7 @@ StartBackgroundWorker(void)
    {
        pqsignal(SIGINT, SIG_IGN);
        pqsignal(SIGUSR1, bgworker_sigusr1_handler);
+       pqsignal(SIGURG, latch_sigurg_handler);
        pqsignal(SIGFPE, SIG_IGN);
    }
    pqsignal(SIGTERM, bgworker_die);
index 715d5195bb671e9c6a1df6dc98ba805b6d4be43a..66864a42df98bd182d5e5d47376f5761fcc5d9a1 100644 (file)
@@ -109,6 +109,7 @@ BackgroundWriterMain(void)
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, SIG_IGN);
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /*
     * Reset some signals that are accepted by postmaster but not here
index 524fc4f1127dd88870763dd15a4b1131f72837c7..e208b5878dd367bf99358ec8e6b34346656c513c 100644 (file)
@@ -203,6 +203,7 @@ CheckpointerMain(void)
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, SignalHandlerForShutdownRequest);
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /*
     * Reset some signals that are accepted by postmaster but not here
index f781fdc6fcab50e5a1a7e48dc54de7d0abbfe259..1fce630b4744433be0e9f9837d7e5739e03bfcd4 100644 (file)
@@ -180,6 +180,7 @@ StartupProcessMain(void)
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, StartupProcTriggerHandler);
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /*
     * Reset some signals that are accepted by postmaster but not here
index 5f36796fcd677a48fb36a0ac21105f6054b81046..92ed7519a2c09a4681cba4282ef3b71df1a4a898 100644 (file)
@@ -107,6 +107,7 @@ WalWriterMain(void)
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, SIG_IGN); /* not used */
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /*
     * Reset some signals that are accepted by postmaster but not here
index 723f513d8bcb240b073ee7eb2339fc19045a8a6a..751c2d38cf7b915e9017fc1fa8d6aee015d3c9c0 100644 (file)
@@ -264,6 +264,7 @@ WalReceiverMain(void)
    pqsignal(SIGPIPE, SIG_IGN);
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, SIG_IGN);
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /* Reset some signals that are accepted by postmaster but not here */
    pqsignal(SIGCHLD, SIG_DFL);
index fe0d368a35b0129f71e798c05e4d6e0acc79630c..dfdea4f4c4e1fbc8cd9b33f3b220fa6c83df4447 100644 (file)
@@ -3054,6 +3054,7 @@ WalSndSignals(void)
    pqsignal(SIGUSR1, procsignal_sigusr1_handler);
    pqsignal(SIGUSR2, WalSndLastCycleHandler);  /* request a last cycle and
                                                 * shutdown */
+   pqsignal(SIGURG, latch_sigurg_handler);
 
    /* Reset some signals that are accepted by postmaster but not here */
    pqsignal(SIGCHLD, SIG_DFL);
index f2d005eea054a0031439b4d2341476e37fd4e5e1..1d9a375078b951782434ee85890cc6f182763dfc 100644 (file)
@@ -46,6 +46,7 @@
 #include <poll.h>
 #endif
 
+#include "libpq/pqsignal.h"
 #include "miscadmin.h"
 #include "pgstat.h"
 #include "port/atomics.h"
@@ -274,6 +275,7 @@ void
 InitLatch(Latch *latch)
 {
    latch->is_set = false;
+   latch->maybe_sleeping = false;
    latch->owner_pid = MyProcPid;
    latch->is_shared = false;
 
@@ -321,6 +323,7 @@ InitSharedLatch(Latch *latch)
 #endif
 
    latch->is_set = false;
+   latch->maybe_sleeping = false;
    latch->owner_pid = 0;
    latch->is_shared = true;
 }
@@ -523,6 +526,11 @@ SetLatch(Latch *latch)
 
    latch->is_set = true;
 
+    pg_memory_barrier();
+
+   if (!latch->maybe_sleeping)
+       return;
+
 #ifndef WIN32
 
    /*
@@ -556,7 +564,7 @@ SetLatch(Latch *latch)
            sendSelfPipeByte();
    }
    else
-       kill(owner_pid, SIGUSR1);
+       kill(owner_pid, SIGURG);
 #else
 
    /*
@@ -589,6 +597,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;
 
@@ -1289,6 +1298,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;
@@ -1299,6 +1316,9 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
            occurred_events++;
            returned_events++;
 
+           /* could have been set above */
+           set->latch->maybe_sleeping = false;
+
            break;
        }
 
@@ -1310,6 +1330,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
@@ -1355,8 +1381,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
    struct epoll_event *cur_epoll_event;
 
    /* Sleep */
-   rc = epoll_wait(set->epoll_fd, set->epoll_ret_events,
-                   nevents, cur_timeout);
+   rc = epoll_pwait(set->epoll_fd, set->epoll_ret_events,
+                    nevents, cur_timeout, &SleepSig);
 
    /* Check return code */
    if (rc < 0)
@@ -1399,6 +1425,8 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
        if (cur_event->events == WL_LATCH_SET &&
            cur_epoll_event->events & (EPOLLIN | EPOLLERR | EPOLLHUP))
        {
+           Assert(set->latch);
+
            /* There's data in the self-pipe, clear it. */
            drainSelfPipe();
 
@@ -1946,6 +1974,14 @@ latch_sigusr1_handler(void)
    if (waiting)
        sendSelfPipeByte();
 }
+
+void
+latch_sigurg_handler(SIGNAL_ARGS)
+{
+   if (waiting)
+       sendSelfPipeByte();
+}
+
 #endif                         /* !WIN32 */
 
 /* Send one byte to the self-pipe, to wake up WaitLatch */
index 583efaecff88e30e79321898811f6f37046a3864..876abf1b5167104a5fd79910878c5e0a31641729 100644 (file)
@@ -587,7 +587,7 @@ procsignal_sigusr1_handler(SIGNAL_ARGS)
 
    SetLatch(MyLatch);
 
-   latch_sigusr1_handler();
+   //latch_sigusr1_handler();
 
    errno = save_errno;
 }
index 28055680aad73486f612226cb3eb6122b45e2aca..fdb9eab73a1407008d1fa69668ecdb9679ba3269 100644 (file)
@@ -3924,6 +3924,7 @@ PostgresMain(int argc, char *argv[],
        pqsignal(SIGPIPE, SIG_IGN);
        pqsignal(SIGUSR1, procsignal_sigusr1_handler);
        pqsignal(SIGUSR2, SIG_IGN);
+       pqsignal(SIGURG, latch_sigurg_handler);
        pqsignal(SIGFPE, FloatExceptionHandler);
 
        /*
index 1161b138748a9609e56e69de7c35316a5946f249..ee41e9732c78f7df52f7f44854ea35afd7ca2fcb 100644 (file)
@@ -30,7 +30,8 @@ extern int    pqsigsetmask(int mask);
 #define sigdelset(set, signum) (*(set) &= ~(sigmask(signum)))
 #endif                         /* WIN32 */
 
-extern sigset_t UnBlockSig,
+extern sigset_t SleepSig,
+           UnBlockSig,
            BlockSig,
            StartupBlockSig;
 
index 1468f30a8e00e50ed9bfa8983d6a40ffc8ca6fec..f13e399c08cb9f469ddaf191ffda7c788c75eaba 100644 (file)
 typedef struct Latch
 {
    sig_atomic_t is_set;
+   sig_atomic_t maybe_sleeping;
    bool        is_shared;
    int         owner_pid;
 #ifdef WIN32
@@ -184,8 +185,10 @@ extern void InitializeLatchWaitSet(void);
  */
 #ifndef WIN32
 extern void latch_sigusr1_handler(void);
+extern void latch_sigurg_handler(SIGNAL_ARGS);
 #else
 #define latch_sigusr1_handler()  ((void) 0)
+static inline void latch_sigurg_handler(SIGNAL_ARGS) {}
 #endif
 
 #endif                         /* LATCH_H */