doc: Expand section related to LWLocks and shared memory
authorMichael Paquier <[email protected]>
Wed, 1 Nov 2023 05:54:13 +0000 (14:54 +0900)
committerMichael Paquier <[email protected]>
Wed, 1 Nov 2023 05:54:13 +0000 (14:54 +0900)
The documentation includes a section describing how to define custom
LWLocks in extensions using the shmem hooks.  However, it has never
mentioned the second, more flexible method based on the following
routines:
- LWLockNewTrancheId() to allocate a tranche ID.
- LWLockRegisterTranche() to associate a name to a tranche ID.
- LWLockInitialize() to initialize a LWLock with a tranche ID.

autoprewarm.c is the only example of extension in the tree that
allocates a LWLock this way.

This commit adds some documentation about all that.  While on it, a
comment is added about the need of AddinShmemInitLock.  This is required
especially for EXEC_BACKEND builds (aka Windows, normally), as per a
remark from Alexander, because backends can execute shmem initialization
paths concurrently.

Author: Aleksander Alekseev, Michael Paquier
Discussion: https://postgr.es/m/CAJ7c6TPKhFgL+54cdTD9yGpG4+sNcyJ+N1GvQqAxgWENAOa3VA@mail.gmail.com

doc/src/sgml/xfunc.sgml

index 96ba95818c2d5e568e0f9906b0ea132a198cee68..89116ae74c2b9bf8194f2b82b1eddf43012e8c41 100644 (file)
@@ -3428,6 +3428,29 @@ void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks)
      <filename>contrib/pg_stat_statements/pg_stat_statements.c</filename> in the
      <productname>PostgreSQL</productname> source tree.
     </para>
+    <para>
+     There is another, more flexible method of obtaining LWLocks. First,
+     allocate a <literal>tranche_id</literal> from a shared counter by
+     calling:
+<programlisting>
+int LWLockNewTrancheId(void)
+</programlisting>
+     Next, each individual process using the <literal>tranche_id</literal>
+     should associate it with a <literal>tranche_name</literal> by calling:
+<programlisting>
+void LWLockRegisterTranche(int tranche_id, const char *tranche_name)
+</programlisting>
+     It is also required to call <function>LWLockInitialize</function> once
+     per LWLock, passing the <literal>tranche_id</literal> as argument:
+<programlisting>
+void LWLockInitialize(LWLock *lock, int tranche_id)
+</programlisting>
+     A complete usage example of <function>LWLockNewTrancheId</function>,
+     <function>LWLockInitialize</function> and
+     <function>LWLockRegisterTranche</function> can be found in
+     <filename>contrib/pg_prewarm/autoprewarm.c</filename> in the
+     <productname>PostgreSQL</productname> source tree.
+    </para>
     <para>
      To avoid possible race-conditions, each backend should use the LWLock
      <function>AddinShmemInitLock</function> when connecting to and initializing
@@ -3451,6 +3474,13 @@ if (!ptr)
 }
 </programlisting>
     </para>
+    <para>
+     It is convenient to use <literal>shmem_startup_hook</literal> which allows
+     placing all the code responsible for initializing shared memory in one
+     place. When using <literal>shmem_startup_hook</literal> the extension
+     still needs to acquire <function>AddinShmemInitLock</function> in order to
+     work properly on all the supported platforms.
+    </para>
    </sect2>
 
    <sect2 id="xfunc-addin-wait-events">