Skip to content

Commit

Permalink
doc: Expand section related to LWLocks and shared memory
Browse files Browse the repository at this point in the history
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
  • Loading branch information
michaelpq committed Nov 1, 2023
1 parent 6ec62b7 commit fe705ef
Showing 1 changed file with 30 additions and 0 deletions.
30 changes: 30 additions & 0 deletions doc/src/sgml/xfunc.sgml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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">
Expand Down

0 comments on commit fe705ef

Please sign in to comment.