summaryrefslogtreecommitdiff
path: root/static/netbsd/man9/pslist.9 3.html
diff options
context:
space:
mode:
Diffstat (limited to 'static/netbsd/man9/pslist.9 3.html')
-rw-r--r--static/netbsd/man9/pslist.9 3.html386
1 files changed, 0 insertions, 386 deletions
diff --git a/static/netbsd/man9/pslist.9 3.html b/static/netbsd/man9/pslist.9 3.html
deleted file mode 100644
index 9aa95f84..00000000
--- a/static/netbsd/man9/pslist.9 3.html
+++ /dev/null
@@ -1,386 +0,0 @@
-<table class="head">
- <tr>
- <td class="head-ltitle">PSLIST(9)</td>
- <td class="head-vol">Kernel Developer's Manual</td>
- <td class="head-rtitle">PSLIST(9)</td>
- </tr>
-</table>
-<div class="manual-text">
-<section class="Sh">
-<h1 class="Sh" id="NAME"><a class="permalink" href="#NAME">NAME</a></h1>
-<p class="Pp"><code class="Nm">pslist</code> &#x2014;
- <span class="Nd">pserialize-safe linked lists</span></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SYNOPSIS"><a class="permalink" href="#SYNOPSIS">SYNOPSIS</a></h1>
-<p class="Pp"><code class="In">#include
- &lt;<a class="In">sys/pslist.h</a>&gt;</code></p>
-<p class="Pp"><var class="Vt">struct pslist_head head <span class="No">=</span>
- <code class="Dv">PSLIST_INITIALIZER</code></var>;
- <br/>
- <var class="Vt">struct pslist_entry entry <span class="No">=</span>
- <code class="Dv">PSLIST_ENTRY_INITIALIZER</code></var>;</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_INIT</code>(<var class="Fa" style="white-space: nowrap;">struct
- pslist_head *head</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_DESTROY</code>(<var class="Fa" style="white-space: nowrap;">struct
- pslist_head *head</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_ENTRY_INIT</code>(<var class="Fa" style="white-space: nowrap;">TYPE
- *element</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_ENTRY_DESTROY</code>(<var class="Fa" style="white-space: nowrap;">TYPE
- *element</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_INSERT_HEAD</code>(<var class="Fa" style="white-space: nowrap;">struct
- pslist_head *head</var>, <var class="Fa" style="white-space: nowrap;">TYPE
- *new</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_INSERT_BEFORE</code>(<var class="Fa" style="white-space: nowrap;">TYPE
- *element</var>, <var class="Fa" style="white-space: nowrap;">TYPE
- *new</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_INSERT_AFTER</code>(<var class="Fa" style="white-space: nowrap;">TYPE
- *element</var>, <var class="Fa" style="white-space: nowrap;">TYPE
- *new</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">void</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_REMOVE</code>(<var class="Fa" style="white-space: nowrap;">TYPE
- *element</var>, <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY
- NAME</var>);</p>
-<p class="Pp"><var class="Ft">TYPE *</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_FIRST</code>(<var class="Fa" style="white-space: nowrap;">const
- struct pslist *head</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-<p class="Pp"><var class="Ft">TYPE *</var>
- <br/>
- <code class="Fn">PSLIST_WRITER_NEXT</code>(<var class="Fa" style="white-space: nowrap;">const
- TYPE *element</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-<p class="Pp"><code class="Fn">PSLIST_WRITER_FOREACH</code>(<var class="Fa" style="white-space: nowrap;">const
- TYPE *element</var>, <var class="Fa" style="white-space: nowrap;">const
- struct pslist_head *head</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-<p class="Pp"><var class="Ft">TYPE *</var>
- <br/>
- <code class="Fn">PSLIST_READER_FIRST</code>(<var class="Fa" style="white-space: nowrap;">const
- struct pslist *head</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-<p class="Pp"><var class="Ft">TYPE *</var>
- <br/>
- <code class="Fn">PSLIST_READER_NEXT</code>(<var class="Fa" style="white-space: nowrap;">const
- TYPE *element</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-<p class="Pp"><code class="Fn">PSLIST_READER_FOREACH</code>(<var class="Fa" style="white-space: nowrap;">const
- TYPE *element</var>, <var class="Fa" style="white-space: nowrap;">const
- struct pslist_head *head</var>,
- <var class="Fa" style="white-space: nowrap;">TYPE</var>,
- <var class="Fa" style="white-space: nowrap;">PSLIST_ENTRY NAME</var>);</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="DESCRIPTION"><a class="permalink" href="#DESCRIPTION">DESCRIPTION</a></h1>
-<p class="Pp">The <code class="Nm">pslist</code> data structure is a linked list
- like <code class="Nm">list</code> in <a class="Xr">queue(3)</a>. It is
- augmented with memory barriers so that any number of readers can safely run
- in parallel with at most one writer, without needing any interprocessor
- synchronization such as locks or atomics on the reader side.</p>
-<p class="Pp" id="PSLIST_INIT">The head of a linked list is represented by a
- <var class="Vt">struct pslist_head</var> object allocated by the caller,
- e.g. by embedding it in another struct, which should be otherwise treated as
- opaque. A linked list head must be initialized with
- <code class="Dv">PSLIST_INITIALIZER</code> or
- <a class="permalink" href="#PSLIST_INIT"><code class="Fn">PSLIST_INIT</code></a>()
- before it may be used. When initialized, a list head represents an empty
- list. A list should be empty and destroyed with
- <a class="permalink" href="#PSLIST_DESTROY"><code class="Fn" id="PSLIST_DESTROY">PSLIST_DESTROY</code></a>()
- before the <var class="Vt">struct pslist_head</var> object's memory is
- reused.</p>
-<p class="Pp" id="element">Each entry in a linked list is represented by a
- <var class="Vt">struct pslist_entry</var> object, also opaque, and embedded
- as a member in a caller-allocated structure called an
- <a class="permalink" href="#element"><i class="Em">element</i></a>. A
- <var class="Vt">struct pslist_entry</var> object must be initialized with
- <code class="Dv">PSLIST_ENTRY_INITIALIZER</code> or
- <a class="permalink" href="#PSLIST_ENTRY_INIT"><code class="Fn" id="PSLIST_ENTRY_INIT">PSLIST_ENTRY_INIT</code></a>()
- before it may be used.</p>
-<p class="Pp" id="PSLIST_ENTRY_DESTROY">When initialized, a list entry is
- unassociated. Inserting an entry associates it with a particular list.
- Removing it partially disassociates it from that list and prevents new
- readers from finding it in the list, but allows extant parallel readers to
- continue reading the next entry. The caller must then wait, e.g. with
- <a class="Xr">pserialize_perform(9)</a>, for all extant parallel readers to
- finish, before destroying the list entry with
- <a class="permalink" href="#PSLIST_ENTRY_DESTROY"><code class="Fn">PSLIST_ENTRY_DESTROY</code></a>()
- and then freeing or reusing its memory.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="EXCLUSIVE_OPERATIONS"><a class="permalink" href="#EXCLUSIVE_OPERATIONS">EXCLUSIVE
- OPERATIONS</a></h1>
-<p class="Pp">The following operations may be performed on list heads and
- entries when the caller has exclusive access to them &#x2014; no parallel
- writers or readers may have access to the same objects.</p>
-<dl class="Bl-tag">
- <dt id="PSLIST_INITIALIZER"><a class="permalink" href="#PSLIST_INITIALIZER"><code class="Dv">PSLIST_INITIALIZER</code></a></dt>
- <dd>Constant initializer for a <var class="Vt">struct pslist_head</var>
- object.</dd>
- <dt><code class="Fn">PSLIST_INIT</code>(<var class="Fa">head</var>)</dt>
- <dd>Initialize the list headed by <var class="Fa">head</var> to be empty.</dd>
- <dt><code class="Fn">PSLIST_DESTROY</code>(<var class="Fa">head</var>)</dt>
- <dd>Destroy the list headed by <var class="Fa">head</var>, which must be
- empty.
- <p class="Pp">This has an effect only with the
- <code class="Dv">DIAGNOSTIC</code> option, so it is not strictly
- necessary, but it can help to detect bugs early; see
- <a class="Xr">KASSERT(9)</a>.</p>
- </dd>
- <dt id="PSLIST_ENTRY_INITIALIZER"><a class="permalink" href="#PSLIST_ENTRY_INITIALIZER"><code class="Dv">PSLIST_ENTRY_INITIALIZER</code></a></dt>
- <dd>Constant initializer for an unassociated <var class="Vt">struct
- pslist_entry</var> object.</dd>
- <dt id="PSLIST_ENTRY_INIT~2"><a class="permalink" href="#PSLIST_ENTRY_INIT~2"><code class="Fn">PSLIST_ENTRY_INIT</code></a>(<var class="Fa">element</var>,
- <var class="Fa">NAME</var>)</dt>
- <dd>Initialize the <var class="Vt">struct pslist_entry</var> object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>.</dd>
- <dt><code class="Fn">PSLIST_ENTRY_DESTROY</code>(<var class="Fa">element</var>,
- <var class="Fa">NAME</var>)</dt>
- <dd>Destroy the <var class="Vt">struct pslist_entry</var> object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>.
- Either <var class="Fa">element</var> must never have been inserted into a
- list, or it must have been inserted and removed, and the caller must have
- waited for all parallel readers to finish reading it first.</dd>
-</dl>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="WRITER_OPERATIONS"><a class="permalink" href="#WRITER_OPERATIONS">WRITER
- OPERATIONS</a></h1>
-<p class="Pp">The following operations may be performed on list heads and
- entries when the caller has exclusive
- <a class="permalink" href="#write"><i class="Em" id="write">write</i></a>
- access to them &#x2014; parallel readers for the same objects are allowed,
- but no parallel writers.</p>
-<dl class="Bl-tag">
- <dt id="PSLIST_WRITER_INSERT_HEAD"><a class="permalink" href="#PSLIST_WRITER_INSERT_HEAD"><code class="Fn">PSLIST_WRITER_INSERT_HEAD</code></a>(<var class="Fa">head</var>,
- <var class="Fa">element</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Insert the element <var class="Fa">element</var> at the beginning of the
- list headed by <var class="Fa">head</var>, before any existing elements in
- the list.
- <p class="Pp">The object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var> object which has
- been initialized but not inserted.</p>
- </dd>
- <dt id="PSLIST_WRITER_INSERT_BEFORE"><a class="permalink" href="#PSLIST_WRITER_INSERT_BEFORE"><code class="Fn">PSLIST_WRITER_INSERT_BEFORE</code></a>(<var class="Fa">element</var>,
- <var class="Fa">new</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Insert the element <var class="Fa">new</var> into a list before the
- element <var class="Fa">element</var>.
- <p class="Pp">The object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var> object which has
- been inserted into a list. The object
- <var class="Fa">new</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var></p>
- </dd>
- <dt id="PSLIST_WRITER_INSERT_AFTER"><a class="permalink" href="#PSLIST_WRITER_INSERT_AFTER"><code class="Fn">PSLIST_WRITER_INSERT_AFTER</code></a>(<var class="Fa">element</var>,
- <var class="Fa">new</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Insert the element <var class="Fa">new</var> into a list after the element
- <var class="Fa">element</var>.
- <p class="Pp">The object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var> object which has
- been inserted into a list. The object
- <var class="Fa">new</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var></p>
- </dd>
- <dt id="PSLIST_WRITER_REMOVE"><a class="permalink" href="#PSLIST_WRITER_REMOVE"><code class="Fn">PSLIST_WRITER_REMOVE</code></a>(<var class="Fa">element</var>,
- <var class="Fa">NAME</var>)</dt>
- <dd>Remove the element <var class="Fa">element</var> from the list into which
- it has been inserted.
- <p class="Pp">The object
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- must be a <var class="Vt">struct pslist_entry</var> object which has
- been inserted into a list.</p>
- </dd>
- <dt id="PSLIST_WRITER_FIRST"><a class="permalink" href="#PSLIST_WRITER_FIRST"><code class="Fn">PSLIST_WRITER_FIRST</code></a>(<var class="Fa">head</var>,
- <var class="Fa">type</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Return a pointer to the first element <var class="Fa">o</var> of type
- <var class="Fa">type</var> with a <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">o</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>,
- or <code class="Dv">NULL</code> if the list is empty.</dd>
- <dt id="PSLIST_WRITER_NEXT"><a class="permalink" href="#PSLIST_WRITER_NEXT"><code class="Fn">PSLIST_WRITER_NEXT</code></a>(<var class="Fa">element</var>,
- <var class="Fa">type</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Return a pointer to the next element <var class="Fa">o</var> of type
- <var class="Fa">type</var> with a <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">o</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- after <var class="Fa">element</var> in a list, or
- <code class="Dv">NULL</code> if there are no elements after
- <var class="Fa">element</var>.</dd>
- <dt id="PSLIST_WRITER_FOREACH"><a class="permalink" href="#PSLIST_WRITER_FOREACH"><code class="Fn">PSLIST_WRITER_FOREACH</code></a>(<var class="Fa">element</var>,
- <var class="Fa">head</var>, <var class="Fa">type</var>,
- <var class="Fa">NAME</var>)</dt>
- <dd>Loop header for iterating over each element <var class="Fa">element</var>
- of type <var class="Fa">type</var> with <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- starting at the list head <var class="Fa">head</var>.
- <p class="Pp">The caller must not modify the list while iterating over
- it.</p>
- </dd>
-</dl>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="READER_OPERATIONS"><a class="permalink" href="#READER_OPERATIONS">READER
- OPERATIONS</a></h1>
-<p class="Pp">The following operations may be performed on list heads and
- entries when the caller is in a passively serialized read section &#x2014;
- see <a class="Xr">pserialize(9)</a>.</p>
-<dl class="Bl-tag">
- <dt id="PSLIST_READER_FIRST"><a class="permalink" href="#PSLIST_READER_FIRST"><code class="Fn">PSLIST_READER_FIRST</code></a>(<var class="Fa">head</var>,
- <var class="Fa">type</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Return a pointer to the first element <var class="Fa">o</var> of type
- <var class="Fa">type</var> with a <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">o</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>,
- or <code class="Dv">NULL</code> if the list is empty.</dd>
- <dt id="PSLIST_READER_NEXT"><a class="permalink" href="#PSLIST_READER_NEXT"><code class="Fn">PSLIST_READER_NEXT</code></a>(<var class="Fa">element</var>,
- <var class="Fa">type</var>, <var class="Fa">NAME</var>)</dt>
- <dd>Return a pointer to the next element <var class="Fa">o</var> of type
- <var class="Fa">type</var> with a <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">o</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- after <var class="Fa">element</var> in a list, or
- <code class="Dv">NULL</code> if there are no elements after
- <var class="Fa">element</var>.</dd>
- <dt id="PSLIST_READER_FOREACH"><a class="permalink" href="#PSLIST_READER_FOREACH"><code class="Fn">PSLIST_READER_FOREACH</code></a>(<var class="Fa">element</var>,
- <var class="Fa">head</var>, <var class="Fa">type</var>,
- <var class="Fa">NAME</var>)</dt>
- <dd>Loop header for iterating over each element <var class="Fa">element</var>
- of type <var class="Fa">type</var> with <var class="Vt">struct
- pslist_entry</var> member
- <var class="Fa">element</var><code class="Li">-&gt;</code><var class="Fa">NAME</var>
- starting at the list head <var class="Fa">head</var>.</dd>
-</dl>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="EXAMPLES"><a class="permalink" href="#EXAMPLES">EXAMPLES</a></h1>
-<p class="Pp">Example frotz structure and global state:</p>
-<div class="Bd Pp Li">
-<pre> struct frotz {
- uint64_t f_key;
- uint64_t f_datum;
- struct pslist_entry f_entry;
- };
-
- static struct {
- kmutex_t lock;
- pserialize_t psz;
- struct pslist_head list;
- struct pool pool;
- } frobnitzem __cacheline_aligned;</pre>
-</div>
-<p class="Pp">Initialize the global state:</p>
-<div class="Bd Pp Li">
-<pre> mutex_init(&amp;frobnitzem.lock, MUTEX_DEFAULT, IPL_NONE);
- frobnitzem.psz = pserialize_create();
- PSLIST_INIT(&amp;frobnitzem.list);
- pool_init(&amp;frobnitzem.pool, sizeof(struct frotz), ...);</pre>
-</div>
-<p class="Pp">Create and publish a frotz:</p>
-<div class="Bd Pp Li">
-<pre> uint64_t key = ...;
- uint64_t datum = ...;
-
- struct frotz *f = pool_get(&amp;frobnitzem.pool, PR_WAITOK);
-
- /* Initialize f. */
- f-&gt;f_key = key;
- f-&gt;f_datum = datum;
- PSLIST_ENTRY_INIT(f, f_entry);
-
- /* Publish it. */
- mutex_enter(&amp;frobnitzem.lock);
- PSLIST_WRITER_INSERT_HEAD(&amp;frobnitzem.list, f, f_entry);
- mutex_exit(&amp;frobnitzem.lock);</pre>
-</div>
-<p class="Pp">Look up a frotz and return its associated datum:</p>
-<div class="Bd Pp Li">
-<pre> uint64_t key = ...;
- struct frotz *f;
- int error = ENOENT;
- int s;
-
- s = pserialize_read_enter();
- PSLIST_READER_FOREACH(f, &amp;frobnitzem.list, struct frotz, f_entry) {
- if (f-&gt;f_key == key) {
- *datump = f-&gt;f_datum;
- error = 0;
- break;
- }
- }
- pserialize_read_exit(s);
- return error;</pre>
-</div>
-<p class="Pp">Remove a frotz and wait for readers to finish using it before
- reusing the memory allocated for it:</p>
-<div class="Bd Pp Li">
-<pre> struct frotz *f = ...;
-
- mutex_enter(&amp;frobnitzem.lock);
- PSLIST_WRITER_REMOVE(f, f_entry);
- mutex_exit(&amp;frobnitzem.lock);
-
- pserialize_perform(&amp;frobnitzem.psz);
-
- PSLIST_ENTRY_DESTROY(f, f_entry);
- pool_put(&amp;frobnitzem.pool, f);</pre>
-</div>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="CODE_REFERENCES"><a class="permalink" href="#CODE_REFERENCES">CODE
- REFERENCES</a></h1>
-<p class="Pp">The <code class="Nm">pslist</code> data structure is implemented
- by static inlines and macros in
- <span class="Pa">sys/sys/pslist.h</span>.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="SEE_ALSO"><a class="permalink" href="#SEE_ALSO">SEE
- ALSO</a></h1>
-<p class="Pp"><a class="Xr">queue(3)</a>, <a class="Xr">pserialize(9)</a>,
- <a class="Xr">psref(9)</a></p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="HISTORY"><a class="permalink" href="#HISTORY">HISTORY</a></h1>
-<p class="Pp">The <code class="Nm">pslist</code> data structure first appeared
- in <span class="Ux">NetBSD 8.0</span>.</p>
-</section>
-<section class="Sh">
-<h1 class="Sh" id="AUTHORS"><a class="permalink" href="#AUTHORS">AUTHORS</a></h1>
-<p class="Pp"><span class="An">Taylor R Campbell</span>
- &lt;<a class="Mt" href="mailto:riastradh@NetBSD.org">riastradh@NetBSD.org</a>&gt;</p>
-</section>
-</div>
-<table class="foot">
- <tr>
- <td class="foot-date">July 7, 2016</td>
- <td class="foot-os">NetBSD 10.1</td>
- </tr>
-</table>