Use WaitLatch() for condition variables.
authorThomas Munro <tmunro@postgresql.org>
Thu, 30 Jul 2020 05:23:32 +0000 (17:23 +1200)
committerThomas Munro <tmunro@postgresql.org>
Thu, 30 Jul 2020 05:42:45 +0000 (17:42 +1200)
Previously, condition_variable.c created a long lived WaitEventSet to
avoid extra system calls.  WaitLatch() now uses something similar
internally, so there is no point in wasting an extra kernel descriptor.

Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com>
Discussion: https://postgr.es/m/CA%2BhUKGJAC4Oqao%3DqforhNey20J8CiG2R%3DoBPqvfR0vOJrFysGw%40mail.gmail.com

src/backend/storage/lmgr/condition_variable.c

index 37b6a4eecdb68a4a97de33a2c225cc673abec550..2ec00397b491b1019d03ec5009e11e5f3272e79f 100644 (file)
@@ -30,9 +30,6 @@
 /* Initially, we are not prepared to sleep on any condition variable. */
 static ConditionVariable *cv_sleep_target = NULL;
 
-/* Reusable WaitEventSet. */
-static WaitEventSet *cv_wait_event_set = NULL;
-
 /*
  * Initialize a condition variable.
  */
@@ -62,23 +59,6 @@ ConditionVariablePrepareToSleep(ConditionVariable *cv)
 {
    int         pgprocno = MyProc->pgprocno;
 
-   /*
-    * If first time through in this process, create a WaitEventSet, which
-    * we'll reuse for all condition variable sleeps.
-    */
-   if (cv_wait_event_set == NULL)
-   {
-       WaitEventSet *new_event_set;
-
-       new_event_set = CreateWaitEventSet(TopMemoryContext, 2);
-       AddWaitEventToSet(new_event_set, WL_LATCH_SET, PGINVALID_SOCKET,
-                         MyLatch, NULL);
-       AddWaitEventToSet(new_event_set, WL_EXIT_ON_PM_DEATH, PGINVALID_SOCKET,
-                         NULL, NULL);
-       /* Don't set cv_wait_event_set until we have a correct WES. */
-       cv_wait_event_set = new_event_set;
-   }
-
    /*
     * If some other sleep is already prepared, cancel it; this is necessary
     * because we have just one static variable tracking the prepared sleep,
@@ -135,6 +115,7 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
    long        cur_timeout = -1;
    instr_time  start_time;
    instr_time  cur_time;
+   int         wait_events;
 
    /*
     * If the caller didn't prepare to sleep explicitly, then do so now and
@@ -166,19 +147,20 @@ ConditionVariableTimedSleep(ConditionVariable *cv, long timeout,
        INSTR_TIME_SET_CURRENT(start_time);
        Assert(timeout >= 0 && timeout <= INT_MAX);
        cur_timeout = timeout;
+       wait_events = WL_LATCH_SET | WL_TIMEOUT | WL_EXIT_ON_PM_DEATH;
    }
+   else
+       wait_events = WL_LATCH_SET | WL_EXIT_ON_PM_DEATH;
 
    while (true)
    {
-       WaitEvent   event;
        bool        done = false;
 
        /*
         * Wait for latch to be set.  (If we're awakened for some other
         * reason, the code below will cope anyway.)
         */
-       (void) WaitEventSetWait(cv_wait_event_set, cur_timeout, &event, 1,
-                               wait_event_info);
+       (void) WaitLatch(MyLatch, wait_events, cur_timeout, wait_event_info);
 
        /* Reset latch before examining the state of the wait list. */
        ResetLatch(MyLatch);