On Wed, Sep 21, 2016 at 8:13 AM, Thomas Munro
<thomas.mu...@enterprisedb.com> wrote:
> +         <para>
> +          <literal>EventSet</>: The server process is waiting on a socket
> +          or a timer. This wait happens in a latch, an inter-process facility
> +          using boolean variables letting a process sleep until it is set.
> +          Latches support several type of operations, like postmaster death
> +          handling, timeout and socket activity lookup, and are a useful
> +          replacement for <function>sleep</> where signal handling matters.
> +         </para>
>
> This paragraph seems a bit confused.  I suggest something more like
> this:  "The server process is waiting for one or more sockets, a timer
> or an interprocess latch.  The wait happens in a WaitEventSet,
> <productname>PostgreSQL</>'s portable IO multiplexing abstraction."

OK, I have tweaked the paragraph as follows using your suggestion:
+        <listitem>
+         <para>
+          <literal>EventSet</>: The server process is waiting on one or more
+          sockets, a time or an inter-process latch.  The wait happens in a
+          <function>WaitEventSet</>, <productname>PostgreSQL</>'s portable
+          I/O multiplexing abstraction using boolean variables letting a
+          process sleep until it is set.  It supports several type of
+          operations, like postmaster death handling, timeout and socket
+          activity lookup, and are a useful replacement for <function>sleep</>
+          where signal handling matters.
+         </para>
+        </listitem>

> On Tue, Aug 23, 2016 at 7:01 PM, Michael Paquier
> <michael.paqu...@gmail.com> wrote:
>>> On Mon, Aug 22, 2016 at 12:09 PM, Alexander Korotkov
>>> <a.korot...@postgrespro.ru> wrote:
>>>> Would it be better to use an array here?
>>
>> Okay, I have switched to an array....
>
> I looked at various macro tricks[1] but they're all pretty unpleasant!
>  +1 for the simple array with carefully managed order.  About that
> order...
> [1] 
> http://stackoverflow.com/questions/147267/easy-way-to-use-variables-of-enum-types-as-string-in-c

Yes, I recall bumping on this one, or something really similar to that...

> +const char *const WaitEventNames[] = {
> [...]
> +};
>
> It looks like this array wants to be in alphabetical order, but it
> isn't quite.  Also, perhaps a compile time assertion about the size of
> the array matching EVENT_LAST_TYPE could be useful?

In GetWaitEventIdentifier()? I'd think that just returning ??? would
have been fine if there is a non-matching call.

> +typedef enum WaitEventIdentifier
> +{
> [...]
> +} WaitEventIdentifier;
>
> This is also nearly but not exactly in alphabetical order
> (EVENT_PROC_SIGNAL comes after EVENT_PROC_SLEEP for example).  But
> it's not currently possible to have the strings and the enumerators
> both in alphabetical order because they're not the same, even
> accounting for camel-case to upper-case transliteration.  I think at
> least one of them should be sorted.  Shouldn't they match fully and
> then *both* be sorted alphabetically?  For example
> "MessageQueueInternal" doesn't match EVENT_MQ_WAIT_INTERNAL.  Then
> there are some cases where I'd expect underscores for consistency with
> other enumerators and with the corresponding camel-case strings: you
> have EVENT_WAL_SENDER_MAIN, but EVENT_WALWRITER_MAIN.

Not wrong..

> The documentation is in a slightly different order again but also not
> exactly alphabetical: for example ProcSleep is listed before
> ProcSignal.

Right.

> Sorry if this all sounds terribly picky but I think we should try to
> be strictly systematic here.

No worries about that, it matters a lot for this patch. The user-faced
documentation is what should do the decision-making I think. So let's
order the names, and adapt the enum depending on that. I have done so
after double-checking both lists, and added a comment for anybody
updating that in the fiture.

>>>> EventIdentifier seems too general name for me, isn't it?  Could we name it
>>>> WaitEventIdentifier? Or WaitEventId for shortcut?
>>
>> ... And WaitEventIdentifier.
>
> +1 from me too for avoiding the overly general term 'event'.  It does
> seem a little odd to leave the enumerators names as EVENT_...  though;
> shouldn't these be WAIT_EVENT_... or WE_...?  Or perhaps you could
> consider WaitPointIdentifier and WP_SECURE_READ or
> WaitEventPointIdentifier and WEP_SECURE_READ, if you buy my earlier
> argument that what we are really naming here is point in the code
> where we wait, not the events we're waiting for.  Contrast with
> LWLocks where we report the lock that you're waiting for, not the
> place in the code where you're waiting for that lock.

Well, WE_ if I need make a choice for something else than EVENT_.

> On the other hand, if we could *accurately* report whether it's a
> "Latch", "Socket" or "Latch|Socket" that we're waiting for, it might
> be cool to do that instead.  One way to do that would be to use up
> several class IDs:  WAIT_EVENT_LATCH, WAIT_EVENT_LATCH_OR_SOCKET,
> WAIT_EVENT_SOCKET (or perhaps WAIT_EVENT_LATCH | WAIT_EVENT_SOCKET,
> reserving 2 or 3 upper bits from the 8 bit class ID for this).  Then
> we could figure out the right class ID by looking at set->latch and
> set->nevents (perhaps an extra boolean would be needed to record
> whether postmaster death is in there so we could deduce whether there
> are any sockets).  It would be interesting specifically for the case
> of FDWs where it would be nice to be able to see clearly that it's
> waiting for a remote server ("Socket").  It may also be interesting to
> know if there is a timeout.  Postmaster death doesn't seem newsworthy,
> we're nearly always also waiting for that exceptional event so it'd
> just be clutter to report it.

That's actually pretty close to what I mentioned upthread here:
https://www.postgresql.org/message-id/CAB7nPqQx4OEym9cf22CY%3D5eWqqiAMjij6EBCoNReezt9-NvGkw%40mail.gmail.com
In order to support that adding a column wait_event_details with
text[] makes the most sense I guess. Still I think that's another
discussion, this patch does already a lot.

So I have adjusted the patch in many ways, tweaked the order of the
items, and adjusted some of their names as suggested by Thomas.
Updated version attached.
-- 
Michael
diff --git a/contrib/postgres_fdw/connection.c 
b/contrib/postgres_fdw/connection.c
index 8ca1c1c..7cecef8 100644
--- a/contrib/postgres_fdw/connection.c
+++ b/contrib/postgres_fdw/connection.c
@@ -496,7 +496,7 @@ pgfdw_get_result(PGconn *conn, const char *query)
                        wc = WaitLatchOrSocket(MyLatch,
                                                                   WL_LATCH_SET 
| WL_SOCKET_READABLE,
                                                                   
PQsocket(conn),
-                                                                  -1L);
+                                                                  -1L, 
WE_EXTENSION);
                        ResetLatch(MyLatch);
 
                        CHECK_FOR_INTERRUPTS();
diff --git a/doc/src/sgml/monitoring.sgml b/doc/src/sgml/monitoring.sgml
index 0776428..5185d65 100644
--- a/doc/src/sgml/monitoring.sgml
+++ b/doc/src/sgml/monitoring.sgml
@@ -679,6 +679,18 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
           buffer in question.
          </para>
         </listitem>
+        <listitem>
+         <para>
+          <literal>EventSet</>: The server process is waiting on one or more
+          sockets, a time or an inter-process latch.  The wait happens in a
+          <function>WaitEventSet</>, <productname>PostgreSQL</>'s portable
+          I/O multiplexing abstraction using boolean variables letting a
+          process sleep until it is set.  It supports several type of
+          operations, like postmaster death handling, timeout and socket
+          activity lookup, and are a useful replacement for <function>sleep</>
+          where signal handling matters.
+         </para>
+        </listitem>
        </itemizedlist>
       </entry>
      </row>
@@ -1085,6 +1097,139 @@ postgres   27093  0.0  0.0  30096  2752 ?        Ss   
11:34   0:00 postgres: ser
          <entry><literal>BufferPin</></entry>
          <entry>Waiting to acquire a pin on a buffer.</entry>
         </row>
+        <row>
+         <entry morerows="32"><literal>EventSet</></entry>
+         <entry><literal>ArchiverMain</></entry>
+         <entry>Waiting in main loop of the archiver process.</entry>
+        </row>
+        <row>
+         <entry><literal>AutoVacuumMain</></entry>
+         <entry>Waiting in main loop of autovacuum launcher process.</entry>
+        </row>
+        <row>
+         <entry><literal>BaseBackupThrottle</></entry>
+         <entry>Waiting during base backup when throttling activity.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWorkerShutdown</></entry>
+         <entry>Waiting for background worker to shut down.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWorkerStartup</></entry>
+         <entry>Waiting for background worker to start up.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWriterHibernate</></entry>
+         <entry>Waiting in background writer process, hibernating.</entry>
+        </row>
+        <row>
+         <entry><literal>BgWriterMain</></entry>
+         <entry>Waiting in main loop of background writer process background 
worker.</entry>
+        </row>
+        <row>
+         <entry><literal>CheckpointerMain</></entry>
+         <entry>Waiting in main loop of checkpointer process.</entry>
+        </row>
+        <row>
+         <entry><literal>ExecuteGather</></entry>
+         <entry>Waiting for activity from child process when executing 
<literal>Gather</> node.</entry>
+        </row>
+        <row>
+         <entry><literal>Extension</></entry>
+         <entry>Waiting in the code path of an extension, should be used by 
custom plugins and modules</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueInternal</></entry>
+         <entry>Waiting for other process to be attached in shared message 
queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueuePutMessage</></entry>
+         <entry>Waiting to put new message in shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueReceive</></entry>
+         <entry>Waiting to receive bytes in shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>MessageQueueSend</></entry>
+         <entry>Waiting to send bytes in shared message queue.</entry>
+        </row>
+        <row>
+         <entry><literal>ParallelFinish</></entry>
+         <entry>Waiting for parallel workers to finish computing.</entry>
+        </row>
+        <row>
+         <entry><literal>PgSleep</></entry>
+         <entry>Waiting in process that called <function>pg_sleep</>.</entry>
+        </row>
+        <row>
+         <entry><literal>PgStatMain</></entry>
+         <entry>Waiting in main loop of the statistics collector 
process.</entry>
+        </row>
+        <row>
+         <entry><literal>ProcSignal</></entry>
+         <entry>Waiting for signal from another backend.</entry>
+        </row>
+        <row>
+         <entry><literal>ProcSleep</></entry>
+         <entry>Waiting for a specific lock.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryApplyDelay</></entry>
+         <entry>Waiting to apply WAL at recovery because it is delayed.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryWalAll</></entry>
+         <entry>Waiting for WAL from any kind of source (local, archive or 
stream) at recovery.</entry>
+        </row>
+        <row>
+         <entry><literal>RecoveryWalStream</></entry>
+         <entry>Waiting for WAL from a stream at recovery.</entry>
+        </row>
+        <row>
+         <entry><literal>SecureRead</></entry>
+         <entry>Waiting to read data from a secure connection.</entry>
+        </row>
+        <row>
+         <entry><literal>SecureWrite</></entry>
+         <entry>Waiting to write data to a secure connection.</entry>
+        </row>
+        <row>
+         <entry><literal>SSLOpenServer</></entry>
+         <entry>Waiting for SSL while attempting connection.</entry>
+        </row>
+        <row>
+         <entry><literal>SyncRep</></entry>
+         <entry>Waiting for WAL commit during synchronous replication.</entry>
+        </row>
+        <row>
+         <entry><literal>SysLoggerMain</></entry>
+         <entry>Waiting in main loop of syslogger process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalReceiverMain</></entry>
+         <entry>Waiting in main loop of WAL receiver process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalReceiverWaitStart</></entry>
+         <entry>Waiting for startup process to send initial data for streaming 
replication.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderMain</></entry>
+         <entry>Waiting in main loop of WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderWaitForWAL</></entry>
+         <entry>Waiting for WAL to be flushed in WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalSenderWriteData</></entry>
+         <entry>Waiting for any activity when processing replies from WAL 
receiver in WAL sender process.</entry>
+        </row>
+        <row>
+         <entry><literal>WalWriterMain</></entry>
+         <entry>Waiting in main loop of WAL writer process.</entry>
+        </row>
       </tbody>
      </tgroup>
     </table>
diff --git a/src/backend/access/transam/parallel.c 
b/src/backend/access/transam/parallel.c
index cde0ed3..60d5c9c 100644
--- a/src/backend/access/transam/parallel.c
+++ b/src/backend/access/transam/parallel.c
@@ -540,7 +540,8 @@ WaitForParallelWorkersToFinish(ParallelContext *pcxt)
                if (!anyone_alive)
                        break;
 
-               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, -1);
+               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, -1,
+                                 WE_PARALLEL_FINISH);
                ResetLatch(&MyProc->procLatch);
        }
 
diff --git a/src/backend/access/transam/xlog.c 
b/src/backend/access/transam/xlog.c
index 2189c22..678b6de 100644
--- a/src/backend/access/transam/xlog.c
+++ b/src/backend/access/transam/xlog.c
@@ -5827,7 +5827,8 @@ recoveryApplyDelay(XLogReaderState *record)
 
                WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                  WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                 secs * 1000L + microsecs / 1000);
+                                 secs * 1000L + microsecs / 1000,
+                                 WE_RECOVERY_APPLY_DELAY);
        }
        return true;
 }
@@ -11376,7 +11377,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool 
randAccess,
 
                                                
WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                                         WL_LATCH_SET | 
WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                                 wait_time);
+                                                        wait_time, 
WE_RECOVERY_WAL_STREAM);
                                                
ResetLatch(&XLogCtl->recoveryWakeupLatch);
                                                now = GetCurrentTimestamp();
                                        }
@@ -11539,7 +11540,7 @@ WaitForWALToBecomeAvailable(XLogRecPtr RecPtr, bool 
randAccess,
                                         */
                                        WaitLatch(&XLogCtl->recoveryWakeupLatch,
                                                          WL_LATCH_SET | 
WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                         5000L);
+                                                         5000L, 
WE_RECOVERY_WAL_ALL);
                                        
ResetLatch(&XLogCtl->recoveryWakeupLatch);
                                        break;
                                }
diff --git a/src/backend/executor/nodeGather.c 
b/src/backend/executor/nodeGather.c
index 438d1b2..b832d91 100644
--- a/src/backend/executor/nodeGather.c
+++ b/src/backend/executor/nodeGather.c
@@ -387,7 +387,7 @@ gather_readnext(GatherState *gatherstate)
                                return NULL;
 
                        /* Nothing to do except wait for developments. */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_EXECUTE_GATHER);
                        ResetLatch(MyLatch);
                        nvisited = 0;
                }
diff --git a/src/backend/libpq/be-secure-openssl.c 
b/src/backend/libpq/be-secure-openssl.c
index fedb02c..571d4d6 100644
--- a/src/backend/libpq/be-secure-openssl.c
+++ b/src/backend/libpq/be-secure-openssl.c
@@ -419,7 +419,8 @@ aloop:
                                else
                                        waitfor = WL_SOCKET_WRITEABLE;
 
-                               WaitLatchOrSocket(MyLatch, waitfor, port->sock, 
0);
+                               WaitLatchOrSocket(MyLatch, waitfor, port->sock, 
0,
+                                                                 
WE_SSL_OPEN_SERVER);
                                goto aloop;
                        case SSL_ERROR_SYSCALL:
                                if (r < 0)
diff --git a/src/backend/libpq/be-secure.c b/src/backend/libpq/be-secure.c
index cdd07d5..4e16073 100644
--- a/src/backend/libpq/be-secure.c
+++ b/src/backend/libpq/be-secure.c
@@ -146,7 +146,8 @@ retry:
 
                ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
 
-               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
+               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
+                                                WE_SECURE_READ);
 
                /*
                 * If the postmaster has died, it's not safe to continue 
running,
@@ -247,7 +248,8 @@ retry:
 
                ModifyWaitEvent(FeBeWaitSet, 0, waitfor, NULL);
 
-               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1);
+               WaitEventSetWait(FeBeWaitSet, -1 /* no timeout */ , &event, 1,
+                                                WE_SECURE_WRITE);
 
                /* See comments in secure_read. */
                if (event.events & WL_POSTMASTER_DEATH)
diff --git a/src/backend/libpq/pqmq.c b/src/backend/libpq/pqmq.c
index bfe66c6..625b987 100644
--- a/src/backend/libpq/pqmq.c
+++ b/src/backend/libpq/pqmq.c
@@ -171,7 +171,7 @@ mq_putmessage(char msgtype, const char *s, size_t len)
                if (result != SHM_MQ_WOULD_BLOCK)
                        break;
 
-               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0);
+               WaitLatch(&MyProc->procLatch, WL_LATCH_SET, 0, 
WE_MQ_PUT_MESSAGE);
                ResetLatch(&MyProc->procLatch);
                CHECK_FOR_INTERRUPTS();
        }
diff --git a/src/backend/postmaster/autovacuum.c 
b/src/backend/postmaster/autovacuum.c
index 1a92ca1..019075e 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -598,7 +598,8 @@ AutoVacLauncherMain(int argc, char *argv[])
                 */
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                          (nap.tv_sec * 1000L) + (nap.tv_usec 
/ 1000L));
+                                          (nap.tv_sec * 1000L) + (nap.tv_usec 
/ 1000L),
+                                          WE_AUTOVACUUM_MAIN);
 
                ResetLatch(MyLatch);
 
diff --git a/src/backend/postmaster/bgworker.c 
b/src/backend/postmaster/bgworker.c
index 699c934..7da01df 100644
--- a/src/backend/postmaster/bgworker.c
+++ b/src/backend/postmaster/bgworker.c
@@ -969,7 +969,8 @@ WaitForBackgroundWorkerStartup(BackgroundWorkerHandle 
*handle, pid_t *pidp)
                        break;
 
                rc = WaitLatch(MyLatch,
-                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 
0);
+                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 
0,
+                                          WE_BGWORKER_STARTUP);
 
                if (rc & WL_POSTMASTER_DEATH)
                {
@@ -1008,7 +1009,8 @@ WaitForBackgroundWorkerShutdown(BackgroundWorkerHandle 
*handle)
                        break;
 
                rc = WaitLatch(&MyProc->procLatch,
-                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 
0);
+                                          WL_LATCH_SET | WL_POSTMASTER_DEATH, 
0,
+                                          WE_BGWORKER_SHUTDOWN);
 
                if (rc & WL_POSTMASTER_DEATH)
                {
diff --git a/src/backend/postmaster/bgwriter.c 
b/src/backend/postmaster/bgwriter.c
index 1002034..a89d39d 100644
--- a/src/backend/postmaster/bgwriter.c
+++ b/src/backend/postmaster/bgwriter.c
@@ -345,7 +345,8 @@ BackgroundWriterMain(void)
                 */
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                          BgWriterDelay /* ms */ );
+                                          BgWriterDelay /* ms */,
+                                          WE_BGWRITER_MAIN);
 
                /*
                 * If no latch event and BgBufferSync says nothing's happening, 
extend
@@ -372,7 +373,8 @@ BackgroundWriterMain(void)
                        /* Sleep ... */
                        rc = WaitLatch(MyLatch,
                                                   WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                                  BgWriterDelay * 
HIBERNATE_FACTOR);
+                                                  BgWriterDelay * 
HIBERNATE_FACTOR,
+                                                  WE_BGWRITER_HIBERNATE);
                        /* Reset the notification request in case we timed out 
*/
                        StrategyNotifyBgWriter(-1);
                }
diff --git a/src/backend/postmaster/checkpointer.c 
b/src/backend/postmaster/checkpointer.c
index d702a48..e18ef9f 100644
--- a/src/backend/postmaster/checkpointer.c
+++ b/src/backend/postmaster/checkpointer.c
@@ -556,7 +556,8 @@ CheckpointerMain(void)
 
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                          cur_timeout * 1000L /* convert to ms 
*/ );
+                                          cur_timeout * 1000L /* convert to ms 
*/,
+                                          WE_CHECKPOINTER_MAIN);
 
                /*
                 * Emergency bailout if postmaster has died.  This is to avoid 
the
diff --git a/src/backend/postmaster/pgarch.c b/src/backend/postmaster/pgarch.c
index 1aa6466..018878c 100644
--- a/src/backend/postmaster/pgarch.c
+++ b/src/backend/postmaster/pgarch.c
@@ -390,7 +390,7 @@ pgarch_MainLoop(void)
 
                                rc = WaitLatch(MyLatch,
                                                         WL_LATCH_SET | 
WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                          timeout * 1000L);
+                                                        timeout * 1000L, 
WE_ARCHIVER_MAIN);
                                if (rc & WL_TIMEOUT)
                                        wakened = true;
                        }
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 8a2ce91..110eb50 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -3152,6 +3152,9 @@ pgstat_get_wait_event_type(uint32 wait_event_info)
                case WAIT_BUFFER_PIN:
                        event_type = "BufferPin";
                        break;
+               case WAIT_EVENT_SET:
+                       event_type = "EventSet";
+                       break;
                default:
                        event_type = "???";
                        break;
@@ -3193,6 +3196,9 @@ pgstat_get_wait_event(uint32 wait_event_info)
                case WAIT_BUFFER_PIN:
                        event_name = "BufferPin";
                        break;
+               case WAIT_EVENT_SET:
+                       event_name = GetWaitEventIdentifier(eventId);
+                       break;
                default:
                        event_name = "unknown wait event";
                        break;
@@ -3682,7 +3688,7 @@ PgstatCollectorMain(int argc, char *argv[])
                wr = WaitLatchOrSocket(MyLatch,
                                         WL_LATCH_SET | WL_POSTMASTER_DEATH | 
WL_SOCKET_READABLE,
                                                           pgStatSock,
-                                                          -1L);
+                                                          -1L, WE_PGSTAT_MAIN);
 #else
 
                /*
@@ -3698,7 +3704,8 @@ PgstatCollectorMain(int argc, char *argv[])
                wr = WaitLatchOrSocket(MyLatch,
                WL_LATCH_SET | WL_POSTMASTER_DEATH | WL_SOCKET_READABLE | 
WL_TIMEOUT,
                                                           pgStatSock,
-                                                          2 * 1000L /* msec */ 
);
+                                                          2 * 1000L /* msec */,
+                                                          EVENT_PGSTAT_MAIN);
 #endif
 
                /*
diff --git a/src/backend/postmaster/syslogger.c 
b/src/backend/postmaster/syslogger.c
index e7e488a..5bdfa479 100644
--- a/src/backend/postmaster/syslogger.c
+++ b/src/backend/postmaster/syslogger.c
@@ -424,7 +424,8 @@ SysLoggerMain(int argc, char *argv[])
                rc = WaitLatchOrSocket(MyLatch,
                                                           WL_LATCH_SET | 
WL_SOCKET_READABLE | cur_flags,
                                                           syslogPipe[0],
-                                                          cur_timeout);
+                                                          cur_timeout,
+                                                          WE_SYSLOGGER_MAIN);
 
                if (rc & WL_SOCKET_READABLE)
                {
@@ -475,7 +476,8 @@ SysLoggerMain(int argc, char *argv[])
 
                (void) WaitLatch(MyLatch,
                                                 WL_LATCH_SET | cur_flags,
-                                                cur_timeout);
+                                                cur_timeout,
+                                                EVENT_SYSLOGGER_MAIN);
 
                EnterCriticalSection(&sysloggerSection);
 #endif   /* WIN32 */
diff --git a/src/backend/postmaster/walwriter.c 
b/src/backend/postmaster/walwriter.c
index 11ec56a..5b6fa15 100644
--- a/src/backend/postmaster/walwriter.c
+++ b/src/backend/postmaster/walwriter.c
@@ -290,7 +290,8 @@ WalWriterMain(void)
 
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                          cur_timeout);
+                                          cur_timeout,
+                                          WE_WAL_WRITER_MAIN);
 
                /*
                 * Emergency bailout if postmaster has died.  This is to avoid 
the
diff --git a/src/backend/replication/basebackup.c 
b/src/backend/replication/basebackup.c
index da9b7a6..82e8d03 100644
--- a/src/backend/replication/basebackup.c
+++ b/src/backend/replication/basebackup.c
@@ -1286,7 +1286,8 @@ throttle(size_t increment)
                 */
                wait_result = WaitLatch(MyLatch,
                                                         WL_LATCH_SET | 
WL_TIMEOUT | WL_POSTMASTER_DEATH,
-                                                               (long) (sleep / 
1000));
+                                                               (long) (sleep / 
1000),
+                                                               
WE_BASE_BACKUP_THROTTLE);
 
                if (wait_result & WL_LATCH_SET)
                        CHECK_FOR_INTERRUPTS();
diff --git a/src/backend/replication/syncrep.c 
b/src/backend/replication/syncrep.c
index b442d06..f1acb4a 100644
--- a/src/backend/replication/syncrep.c
+++ b/src/backend/replication/syncrep.c
@@ -258,7 +258,8 @@ SyncRepWaitForLSN(XLogRecPtr lsn, bool commit)
                 * Wait on latch.  Any condition that should wake us up will 
set the
                 * latch, so no need for timeout.
                 */
-               WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1);
+               WaitLatch(MyLatch, WL_LATCH_SET | WL_POSTMASTER_DEATH, -1,
+                                 WE_SYNC_REP);
        }
 
        /*
diff --git a/src/backend/replication/walreceiver.c 
b/src/backend/replication/walreceiver.c
index 413ee3a..046a760 100644
--- a/src/backend/replication/walreceiver.c
+++ b/src/backend/replication/walreceiver.c
@@ -486,7 +486,8 @@ WalReceiverMain(void)
                                                                   
WL_POSTMASTER_DEATH | WL_SOCKET_READABLE |
                                                                           
WL_TIMEOUT | WL_LATCH_SET,
                                                                           
wait_fd,
-                                                                          
NAPTIME_PER_CYCLE);
+                                                                          
NAPTIME_PER_CYCLE,
+                                                                          
WE_WAL_RECEIVER_MAIN);
                                if (rc & WL_LATCH_SET)
                                {
                                        ResetLatch(&walrcv->latch);
@@ -685,7 +686,8 @@ WalRcvWaitForStartPosition(XLogRecPtr *startpoint, 
TimeLineID *startpointTLI)
                }
                SpinLockRelease(&walrcv->mutex);
 
-               WaitLatch(&walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 
0);
+               WaitLatch(&walrcv->latch, WL_LATCH_SET | WL_POSTMASTER_DEATH, 0,
+                                 WE_WAL_RECEIVER_WAIT_START);
        }
 
        if (update_process_title)
diff --git a/src/backend/replication/walsender.c 
b/src/backend/replication/walsender.c
index c7743da..3cac83b 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -1146,7 +1146,8 @@ WalSndWriteData(LogicalDecodingContext *ctx, XLogRecPtr 
lsn, TransactionId xid,
 
                /* Sleep until something happens or we time out */
                WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                 MyProcPort->sock, sleeptime);
+                                                 MyProcPort->sock, sleeptime,
+                                                 WE_WAL_SENDER_WRITE_DATA);
        }
 
        /* reactivate latch so WalSndLoop knows to continue */
@@ -1272,7 +1273,8 @@ WalSndWaitForWal(XLogRecPtr loc)
 
                /* Sleep until something happens or we time out */
                WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                 MyProcPort->sock, sleeptime);
+                                                 MyProcPort->sock, sleeptime,
+                                                 WE_WAL_SENDER_WAIT_WAL);
        }
 
        /* reactivate latch so WalSndLoop knows to continue */
@@ -1924,7 +1926,8 @@ WalSndLoop(WalSndSendDataCallback send_data)
 
                        /* Sleep until something happens or we time out */
                        WaitLatchOrSocket(MyLatch, wakeEvents,
-                                                         MyProcPort->sock, 
sleeptime);
+                                                         MyProcPort->sock, 
sleeptime,
+                                                         WE_WAL_SENDER_MAIN);
                }
        }
        return;
diff --git a/src/backend/storage/ipc/latch.c b/src/backend/storage/ipc/latch.c
index 9def8a1..3394238 100644
--- a/src/backend/storage/ipc/latch.c
+++ b/src/backend/storage/ipc/latch.c
@@ -55,6 +55,7 @@
 #endif
 
 #include "miscadmin.h"
+#include "pgstat.h"
 #include "portability/instr_time.h"
 #include "postmaster/postmaster.h"
 #include "storage/barrier.h"
@@ -122,6 +123,46 @@ struct WaitEventSet
 #endif
 };
 
+/*
+ * This must match enum WaitEventIdentifier! The alphabetical order here
+ * is kept in priority and in-sync with the documentation.
+ */
+const char *const WaitEventNames[] = {
+       "ArchiverMain",
+       "AutoVacuumMain",
+       "BaseBackupThrottle",
+       "BgWorkerShutdown",
+       "BgWorkerStartup",
+       "BgWriterHibernate",
+       "BgWriterMain",
+       "CheckpointerMain",
+       "ExecuteGather",
+       "Extension",
+       "MessageQueueInternal",
+       "MessageQueuePutMessage",
+       "MessageQueueReceive",
+       "MessageQueueSend",
+       "ParallelFinish",
+       "PgSleep",
+       "PgStatMain",
+       "ProcSignal",
+       "ProcSleep",
+       "RecoveryApplyDelay",
+       "RecoveryWalAll",
+       "RecoveryWalStream",
+       "SecureRead",
+       "SecureWrite",
+       "SSLOpenServer",
+       "SyncRep",
+       "SysLoggerMain",
+       "WalReceiverMain",
+       "WalReceiverWaitStart",
+       "WalSenderMain",
+       "WalSenderWaitForWAL",
+       "WalSenderWriteData",
+       "WalWriterMain"
+};
+
 #ifndef WIN32
 /* Are we currently in WaitLatch? The signal handler would like to know. */
 static volatile sig_atomic_t waiting = false;
@@ -297,9 +338,11 @@ DisownLatch(volatile Latch *latch)
  * we return all of them in one call, but we will return at least one.
  */
 int
-WaitLatch(volatile Latch *latch, int wakeEvents, long timeout)
+WaitLatch(volatile Latch *latch, int wakeEvents, long timeout,
+                 WaitEventIdentifier eventId)
 {
-       return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout);
+       return WaitLatchOrSocket(latch, wakeEvents, PGINVALID_SOCKET, timeout,
+                                                        eventId);
 }
 
 /*
@@ -316,7 +359,7 @@ WaitLatch(volatile Latch *latch, int wakeEvents, long 
timeout)
  */
 int
 WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, pgsocket sock,
-                                 long timeout)
+                                 long timeout, WaitEventIdentifier eventId)
 {
        int                     ret = 0;
        int                     rc;
@@ -344,7 +387,7 @@ WaitLatchOrSocket(volatile Latch *latch, int wakeEvents, 
pgsocket sock,
                AddWaitEventToSet(set, ev, sock, NULL, NULL);
        }
 
-       rc = WaitEventSetWait(set, timeout, &event, 1);
+       rc = WaitEventSetWait(set, timeout, &event, 1, eventId);
 
        if (rc == 0)
                ret |= WL_TIMEOUT;
@@ -863,7 +906,8 @@ WaitEventAdjustWin32(WaitEventSet *set, WaitEvent *event)
  */
 int
 WaitEventSetWait(WaitEventSet *set, long timeout,
-                                WaitEvent *occurred_events, int nevents)
+                                WaitEvent *occurred_events, int nevents,
+                                WaitEventIdentifier eventId)
 {
        int                     returned_events = 0;
        instr_time      start_time;
@@ -872,6 +916,8 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
 
        Assert(nevents > 0);
 
+       pgstat_report_wait_start(WAIT_EVENT_SET, (uint16) eventId);
+
        /*
         * Initialize timeout if requested.  We must record the current time so
         * that we can determine the remaining timeout if interrupted.
@@ -960,6 +1006,8 @@ WaitEventSetWait(WaitEventSet *set, long timeout,
        waiting = false;
 #endif
 
+       pgstat_report_wait_end();
+
        return returned_events;
 }
 
@@ -1491,6 +1539,20 @@ WaitEventSetWaitBlock(WaitEventSet *set, int cur_timeout,
 }
 #endif
 
+
+/*
+ * Return an identifier for a Latch depending on an event for statistics
+ * collector.
+ */
+const char *
+GetWaitEventIdentifier(uint16 eventId)
+{
+       if (eventId > WE_LAST_TYPE)
+               return "???";
+       return WaitEventNames[eventId];
+}
+
+
 /*
  * SetLatch uses SIGUSR1 to wake up the process waiting on the latch.
  *
diff --git a/src/backend/storage/ipc/shm_mq.c b/src/backend/storage/ipc/shm_mq.c
index 5b32782..c47cf2b 100644
--- a/src/backend/storage/ipc/shm_mq.c
+++ b/src/backend/storage/ipc/shm_mq.c
@@ -894,7 +894,7 @@ shm_mq_send_bytes(shm_mq_handle *mqh, Size nbytes, const 
void *data,
                         * at top of loop, because setting an already-set latch 
is much
                         * cheaper than setting one that has been reset.
                         */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_MQ_SEND);
 
                        /* Reset the latch so we don't spin. */
                        ResetLatch(MyLatch);
@@ -991,7 +991,7 @@ shm_mq_receive_bytes(shm_mq *mq, Size bytes_needed, bool 
nowait,
                 * loop, because setting an already-set latch is much cheaper 
than
                 * setting one that has been reset.
                 */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_MQ_RECEIVE);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
@@ -1090,7 +1090,7 @@ shm_mq_wait_internal(volatile shm_mq *mq, PGPROC 
*volatile * ptr,
                }
 
                /* Wait to be signalled. */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_MQ_INTERNAL);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
diff --git a/src/backend/storage/lmgr/proc.c b/src/backend/storage/lmgr/proc.c
index 33e7023..23deeb6 100644
--- a/src/backend/storage/lmgr/proc.c
+++ b/src/backend/storage/lmgr/proc.c
@@ -1212,7 +1212,7 @@ ProcSleep(LOCALLOCK *locallock, LockMethod 
lockMethodTable)
                }
                else
                {
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_PROC_SLEEP);
                        ResetLatch(MyLatch);
                        /* check for deadlocks first, as that's probably 
log-worthy */
                        if (got_deadlock_timeout)
@@ -1724,7 +1724,7 @@ CheckDeadLockAlert(void)
 void
 ProcWaitForSignal(void)
 {
-       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+       WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_PROC_SIGNAL);
        ResetLatch(MyLatch);
        CHECK_FOR_INTERRUPTS();
 }
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 5e705e9..a814a06 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -560,7 +560,7 @@ pg_sleep(PG_FUNCTION_ARGS)
 
                (void) WaitLatch(MyLatch,
                                                 WL_LATCH_SET | WL_TIMEOUT,
-                                                delay_ms);
+                                                delay_ms, WE_PG_SLEEP);
                ResetLatch(MyLatch);
        }
 
diff --git a/src/include/pgstat.h b/src/include/pgstat.h
index dc3320d..bca16e4 100644
--- a/src/include/pgstat.h
+++ b/src/include/pgstat.h
@@ -721,7 +721,8 @@ typedef enum WaitClass
        WAIT_LWLOCK_NAMED,
        WAIT_LWLOCK_TRANCHE,
        WAIT_LOCK,
-       WAIT_BUFFER_PIN
+       WAIT_BUFFER_PIN,
+       WAIT_EVENT_SET
 }      WaitClass;
 
 
diff --git a/src/include/storage/latch.h b/src/include/storage/latch.h
index 5179ecc..45859bb 100644
--- a/src/include/storage/latch.h
+++ b/src/include/storage/latch.h
@@ -135,6 +135,51 @@ typedef struct WaitEvent
        void       *user_data;          /* pointer provided in 
AddWaitEventToSet */
 } WaitEvent;
 
+/*
+ * List of latch identifiers used when reporting activity to statistics
+ * collector. Up to 256 different WaitEventIdentifier can be handled.
+ */
+typedef enum WaitEventIdentifier
+{
+       WE_ARCHIVER_MAIN,
+       WE_AUTOVACUUM_MAIN,
+       WE_BASE_BACKUP_THROTTLE,
+       WE_BGWORKER_SHUTDOWN,
+       WE_BGWORKER_STARTUP,
+       WE_BGWRITER_HIBERNATE,
+       WE_BGWRITER_MAIN,
+       WE_CHECKPOINTER_MAIN,
+       WE_EXECUTE_GATHER,
+       WE_EXTENSION,
+       WE_MQ_INTERNAL,
+       WE_MQ_PUT_MESSAGE,
+       WE_MQ_RECEIVE,
+       WE_MQ_SEND,
+       WE_PARALLEL_FINISH,
+       WE_PG_SLEEP,
+       WE_PGSTAT_MAIN,
+       WE_PROC_SIGNAL,
+       WE_PROC_SLEEP,
+       WE_RECOVERY_APPLY_DELAY,
+       WE_RECOVERY_WAL_ALL,
+       WE_RECOVERY_WAL_STREAM,
+       WE_SECURE_READ,
+       WE_SECURE_WRITE,
+       WE_SSL_OPEN_SERVER,
+       WE_SYNC_REP,
+       WE_SYSLOGGER_MAIN,
+       WE_WAL_RECEIVER_MAIN,
+       WE_WAL_RECEIVER_WAIT_START,
+       WE_WAL_SENDER_MAIN,
+       WE_WAL_SENDER_WAIT_WAL,
+       WE_WAL_SENDER_WRITE_DATA,
+       WE_WAL_WRITER_MAIN
+} WaitEventIdentifier;
+
+#define WE_LAST_TYPE WE_WAL_WRITER_MAIN
+
+extern const char *const WaitEventName[];
+
 /* forward declaration to avoid exposing latch.c implementation details */
 typedef struct WaitEventSet WaitEventSet;
 
@@ -155,10 +200,14 @@ extern int AddWaitEventToSet(WaitEventSet *set, uint32 
events, pgsocket fd,
                                  Latch *latch, void *user_data);
 extern void ModifyWaitEvent(WaitEventSet *set, int pos, uint32 events, Latch 
*latch);
 
-extern int     WaitEventSetWait(WaitEventSet *set, long timeout, WaitEvent 
*occurred_events, int nevents);
-extern int     WaitLatch(volatile Latch *latch, int wakeEvents, long timeout);
+extern int     WaitEventSetWait(WaitEventSet *set, long timeout,
+                                 WaitEvent *occurred_events, int nevents,
+                                 WaitEventIdentifier eventId);
+extern int     WaitLatch(volatile Latch *latch, int wakeEvents, long timeout,
+                                 WaitEventIdentifier eventId);
 extern int WaitLatchOrSocket(volatile Latch *latch, int wakeEvents,
-                                 pgsocket sock, long timeout);
+                                 pgsocket sock, long timeout, 
WaitEventIdentifier eventId);
+extern const char *GetWaitEventIdentifier(uint16 eventId);
 
 /*
  * Unix implementation uses SIGUSR1 for inter-process signaling.
diff --git a/src/test/modules/test_shm_mq/setup.c 
b/src/test/modules/test_shm_mq/setup.c
index 143df4e..adebfc8 100644
--- a/src/test/modules/test_shm_mq/setup.c
+++ b/src/test/modules/test_shm_mq/setup.c
@@ -279,7 +279,7 @@ wait_for_workers_to_become_ready(worker_state *wstate,
                }
 
                /* Wait to be signalled. */
-               WaitLatch(MyLatch, WL_LATCH_SET, 0);
+               WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_EXTENSION);
 
                /* Reset the latch so we don't spin. */
                ResetLatch(MyLatch);
diff --git a/src/test/modules/test_shm_mq/test.c 
b/src/test/modules/test_shm_mq/test.c
index dd34bc7..22145db 100644
--- a/src/test/modules/test_shm_mq/test.c
+++ b/src/test/modules/test_shm_mq/test.c
@@ -230,7 +230,7 @@ test_shm_mq_pipelined(PG_FUNCTION_ARGS)
                         * have read or written data and therefore there may 
now be work
                         * for us to do.
                         */
-                       WaitLatch(MyLatch, WL_LATCH_SET, 0);
+                       WaitLatch(MyLatch, WL_LATCH_SET, 0, WE_EXTENSION);
                        ResetLatch(MyLatch);
                        CHECK_FOR_INTERRUPTS();
                }
diff --git a/src/test/modules/worker_spi/worker_spi.c 
b/src/test/modules/worker_spi/worker_spi.c
index 314e371..aa7f7f9 100644
--- a/src/test/modules/worker_spi/worker_spi.c
+++ b/src/test/modules/worker_spi/worker_spi.c
@@ -227,7 +227,8 @@ worker_spi_main(Datum main_arg)
                 */
                rc = WaitLatch(MyLatch,
                                           WL_LATCH_SET | WL_TIMEOUT | 
WL_POSTMASTER_DEATH,
-                                          worker_spi_naptime * 1000L);
+                                          worker_spi_naptime * 1000L,
+                                          WE_EXTENSION);
                ResetLatch(MyLatch);
 
                /* emergency bailout if postmaster has died */
-- 
Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org)
To make changes to your subscription:
http://www.postgresql.org/mailpref/pgsql-hackers

Reply via email to