public inbox for [email protected]help / color / mirror / Atom feed
[PATCH v6 05/10] doc: s/evade/avoid/ 2+ messages / 2 participants [nested] [flat]
* [PATCH v6 05/10] doc: s/evade/avoid/ @ 2020-04-06 22:16 Justin Pryzby <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Justin Pryzby @ 2020-04-06 22:16 UTC (permalink / raw) --- src/backend/access/gin/README | 2 +- src/backend/utils/adt/jsonpath_exec.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/backend/access/gin/README b/src/backend/access/gin/README index 125a82219b..41d4e1e8a0 100644 --- a/src/backend/access/gin/README +++ b/src/backend/access/gin/README @@ -413,7 +413,7 @@ leftmost leaf of the tree. Deletion algorithm keeps exclusive locks on left siblings of pages comprising currently investigated path. Thus, if current page is to be removed, all required pages to remove both downlink and rightlink are already locked. That -evades potential right to left page locking order, which could deadlock with +avoids potential right to left page locking order, which could deadlock with concurrent stepping right. A search concurrent to page deletion might already have read a pointer to the diff --git a/src/backend/utils/adt/jsonpath_exec.c b/src/backend/utils/adt/jsonpath_exec.c index f146767bfc..2d2eb7d7a3 100644 --- a/src/backend/utils/adt/jsonpath_exec.c +++ b/src/backend/utils/adt/jsonpath_exec.c @@ -35,7 +35,7 @@ * executeItemOptUnwrapTarget() function have 'unwrap' argument, which indicates * whether unwrapping of array is needed. When unwrap == true, each of array * members is passed to executeItemOptUnwrapTarget() again but with unwrap == false - * in order to evade subsequent array unwrapping. + * in order to avoid subsequent array unwrapping. * * All boolean expressions (predicates) are evaluated by executeBoolItem() * function, which returns tri-state JsonPathBool. When error is occurred -- 2.17.0 --C+ts3FVlLX8+P6JN Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v6-0006-doc-Add-logical-replication-support-to-replicate-.patch" ^ permalink raw reply [nested|flat] 2+ messages in thread
* reorganize "Shared Memory and LWLocks" section of docs @ 2024-01-12 04:14 Nathan Bossart <[email protected]> 0 siblings, 0 replies; 2+ messages in thread From: Nathan Bossart @ 2024-01-12 04:14 UTC (permalink / raw) To: pgsql-hackers I recently began trying to write documentation for the dynamic shared memory registry feature [0], and I noticed that the "Shared Memory and LWLocks" section of the documentation might need some improvement. At least, I felt that it would be hard to add any new content to this section without making it very difficult to follow. Concretely, I am proposing breaking it into two sections: one for shared memory and one for LWLocks. Furthermore, the LWLocks section will be split into two: one for requesting locks at server startup and one for requesting locks after server startup. I intend to also split the shared memory section into at-startup and after-startup sections if/when the dynamic shared memory registry feature is committed. Besides this restructuring, I felt that certain parts of this documentation could benefit from rephrasing and/or additional detail. Thoughts? [0] https://postgr.es/m/20231205034647.GA2705267%40nathanxps13 -- Nathan Bossart Amazon Web Services: https://aws.amazon.com Attachments: [text/x-diff] v1-0001-reorganize-shared-memory-and-lwlocks-documentatio.patch (9.3K, ../../20240112041430.GA3557928@nathanxps13/2-v1-0001-reorganize-shared-memory-and-lwlocks-documentatio.patch) download | inline diff: From dc5c1b37ced883021f4a92a17aa50b9d80d73fc6 Mon Sep 17 00:00:00 2001 From: Nathan Bossart <[email protected]> Date: Thu, 11 Jan 2024 21:55:25 -0600 Subject: [PATCH v1 1/1] reorganize shared memory and lwlocks documentation --- doc/src/sgml/xfunc.sgml | 180 +++++++++++++++++++++++++--------------- 1 file changed, 112 insertions(+), 68 deletions(-) diff --git a/doc/src/sgml/xfunc.sgml b/doc/src/sgml/xfunc.sgml index 89116ae74c..a758384a9a 100644 --- a/doc/src/sgml/xfunc.sgml +++ b/doc/src/sgml/xfunc.sgml @@ -3397,90 +3397,134 @@ CREATE FUNCTION make_array(anyelement) RETURNS anyarray </sect2> <sect2 id="xfunc-shared-addin"> - <title>Shared Memory and LWLocks</title> + <title>Shared Memory</title> - <para> - Add-ins can reserve LWLocks and an allocation of shared memory on server - startup. The add-in's shared library must be preloaded by specifying - it in - <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>. - The shared library should register a <literal>shmem_request_hook</literal> - in its <function>_PG_init</function> function. This - <literal>shmem_request_hook</literal> can reserve LWLocks or shared memory. - Shared memory is reserved by calling: + <sect3 id="xfunc-shared-addin-at-startup"> + <title>Requesting Shared Memory at Startup</title> + + <para> + Add-ins can reserve shared memory on server startup. To do so, the + add-in's shared library must be preloaded by specifying it in + <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>. + The shared library should also register a + <literal>shmem_request_hook</literal> in its + <function>_PG_init</function> function. This + <literal>shmem_request_hook</literal> can reserve shared memory by + calling: <programlisting> void RequestAddinShmemSpace(int size) </programlisting> - from your <literal>shmem_request_hook</literal>. - </para> - <para> - LWLocks are reserved by calling: + Each backend sould obtain a pointer to the reserved shared memory by + calling: +<programlisting> +void *ShmemInitStruct(const char *name, Size size, bool *foundPtr) +</programlisting> + If this function sets <literal>foundPtr</literal> to + <literal>false</literal>, the caller should proceed to initialize the + contents of the reserved shared memory. If <literal>foundPtr</literal> + is set to <literal>true</literal>, the shared memory was already + initialized by another backend, and the caller need not initialize + further. + </para> + + <para> + To avoid race conditions, each backend should use the LWLock + <function>AddinShmemInitLock</function> when initializing its allocation + of shared memory, as shown here: +<programlisting> +static mystruct *ptr = NULL; +bool found; + +LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); +ptr = ShmemInitStruct("my struct name", size, &found); +if (!found) +{ + ... initialize contents of shared memory ... + ptr->locks = GetNamedLWLockTranche("my tranche name"); +} +LWLockRelease(AddinShmemInitLock); +</programlisting> + <literal>shmem_startup_hook</literal> provides a convenient place for the + initialization code, but it is not strictly required that all such code + be placed in this hook. Any registered + <literal>shmem_startup_hook</literal> will be executed shortly after each + backend attaches to shared memory. Note that add-ins should still + acquire <function>AddinShmemInitLock</function> within this hook, as + shown in the example above. + </para> + + <para> + An example of a <literal>shmem_request_hook</literal> and + <literal>shmem_startup_hook</literal> can be found in + <filename>contrib/pg_stat_statements/pg_stat_statements.c</filename> in + the <productname>PostgreSQL</productname> source tree. + </para> + </sect3> + </sect2> + + <sect2 id="xfunc-addin-lwlocks"> + <title>LWLocks</title> + + <sect3 id="xfunc-addin-lwlocks-at-startup"> + <title>Requesting LWLocks at Startup</title> + + <para> + Add-ins can reserve LWLocks on server startup. Like with shared memory, + the add-in's shared library must be preloaded by specifying it in + <xref linkend="guc-shared-preload-libraries"/><indexterm><primary>shared_preload_libraries</primary></indexterm>, + and the shared library should register a + <literal>shmem_request_hook</literal> in its + <function>_PG_init</function> function. This + <literal>shmem_request_hook</literal> can reserve LWLocks by calling: <programlisting> void RequestNamedLWLockTranche(const char *tranche_name, int num_lwlocks) </programlisting> - from your <literal>shmem_request_hook</literal>. This will ensure that an array of - <literal>num_lwlocks</literal> LWLocks is available under the name - <literal>tranche_name</literal>. Use <function>GetNamedLWLockTranche</function> - to get a pointer to this array. - </para> - <para> - An example of a <literal>shmem_request_hook</literal> can be found in - <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: + This ensures that an array of <literal>num_lwlocks</literal> LWLocks is + available under the name <literal>tranche_name</literal>. A pointer to + this array can be obtained by calling: <programlisting> -int LWLockNewTrancheId(void) +LWLockPadded *GetNamedLWLockTranche(const char *tranche_name) </programlisting> - Next, each individual process using the <literal>tranche_id</literal> - should associate it with a <literal>tranche_name</literal> by calling: + </para> + </sect3> + + <sect3 id="xfunc-addin-lwlocks-after-startup"> + <title>Requesting LWLocks After Startup</title> + + <para> + There is another, more flexible method of obtaining LWLocks that can be + done after server startup and outside a + <literal>shmem_request_hook</literal>. To do so, first allocate a + <literal>tranche_id</literal> by calling: <programlisting> -void LWLockRegisterTranche(int tranche_id, const char *tranche_name) +int LWLockNewTrancheId(void) </programlisting> - It is also required to call <function>LWLockInitialize</function> once - per LWLock, passing the <literal>tranche_id</literal> as argument: + Next, initialize each LWLock, passing the new + <literal>tranche_id</literal> as an 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 - its allocation of shared memory, as shown here: + Finally, each backend using the <literal>tranche_id</literal> should + associate it with a <literal>tranche_name</literal> by calling: <programlisting> -static mystruct *ptr = NULL; - -if (!ptr) -{ - bool found; - - LWLockAcquire(AddinShmemInitLock, LW_EXCLUSIVE); - ptr = ShmemInitStruct("my struct name", size, &found); - if (!found) - { - initialize contents of shmem area; - acquire any requested LWLocks using: - ptr->locks = GetNamedLWLockTranche("my tranche name"); - } - LWLockRelease(AddinShmemInitLock); -} +void LWLockRegisterTranche(int tranche_id, const char *tranche_name) </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> + Similar to shared memory, each backend should ensure that only one + process allocates a new <literal>tranche_id</literal> + (<function>LWLockNewTrancheId</function>) and initializes each new LWLock + (<function>LWLockInitialize</function>). One way to do this is to only + call these functions in your shared memory initialization code with the + <function>AddinShmemInitLock</function> held exclusively. + </para> + + <para> + 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> + </sect3> </sect2> <sect2 id="xfunc-addin-wait-events"> -- 2.25.1 ^ permalink raw reply [nested|flat] 2+ messages in thread
end of thread, other threads:[~2024-01-12 04:14 UTC | newest] Thread overview: 2+ messages (download: mbox mbox.gz follow: Atom feed) -- links below jump to the message on this page -- 2020-04-06 22:16 [PATCH v6 05/10] doc: s/evade/avoid/ Justin Pryzby <[email protected]> 2024-01-12 04:14 reorganize "Shared Memory and LWLocks" section of docs Nathan Bossart <[email protected]>
This inbox is served by agora; see mirroring instructions for how to clone and mirror all data and code used for this inbox