PSERIALIZE(9)
π pserialize(9): passive serialization, but make it cute π
okay so welcome to the pserialize(9) page from the Kernel Developer's Manual, bestie. This one is all about passive serialization, and it's lowkey iconic: lock-less reads, writer-side patience, the whole vibe. β¨
π NAME π
pserialize β passive serialization mechanism
πΈ SYNOPSIS πΈ
#include <sys/pserialize.h>
pserialize_t
pserialize_create(void);
void
pserialize_destroy(pserialize_t psz);
int
pserialize_read_enter(void);
void
pserialize_read_exit(int s);
void
pserialize_perform(pserialize_t psz);
π¦ DESCRIPTION π¦
Passive serialization is a reader / writer synchronisation mechanism designed for lock-less read operations. The read operations may happen from software interrupt at IPL_SOFTCLOCK.
β¨ FUNCTIONS β¨
pserialize_create()β Allocate a new synchronisation object. Fresh object, new vibes. πpserialize_destroy()β Destroy the synchronisation object. No synchronisation activity should happen at this point.pserialize_read_enter()β Enter the critical path of the reader side. Returns an IPL value, which must be passed topserialize_read_exit(9). Protected code path is not allowed to block. Not allowed, bestie.pserialize_read_exit()β Exit the critical path of the reader side. Takes the IPL value returned bypserialize_read_enter(9).pserialize_perform()β Perform the passive serialization on the writer side. Passing of this function ensures that no readers are in action. Writers are typically additionally serialized with a separate mechanism, e.g.mutex(9), to remove objects used by readers from a published list. Operation blocks and it may only be performed from thread context.
π EXAMPLES π
Okay, imagine we've got a global database of frotz records:
struct frotz {
...
struct frotz *f_next;
};
static struct {
kmutex_t lock;
pserialize_t psz;
struct frotz *first;
} frobbotzim __cacheline_aligned;
Create a frotz and publish it, as a writer:
struct frotz *f = pool_get(&frotz_pool, PR_WAITOK);
/* Initialize f. */
...
mutex_enter(&frobbotzim.lock);
f->f_next = frobbotzim.first;
/*
* Publish the contents of f->f_next before we publish the
* pointer to f in frobbotzim.first.
*/
membar_producer();
frobbotzim.first = f;
mutex_exit(&frobbotzim.lock);
Find a frotz, as a reader:
struct frotz *f;
int error = ENOENT;
int s;
s = pserialize_read_enter();
for (f = frobbotzim.first; f != NULL; f = f->f_next) {
/* Fetch f before we fetch anything f points to. */
membar_datadep_consumer();
if (f->f_... == key) {
/*
* Grab whatever part of the frotz we need.
* Note that we can't use the frotz after
* pserialize_read_exit, without a stronger
* kind of reference, say a reference count
* managed by atomic_ops(3).
*/
*resultp = f->f_...;
error = 0;
break;
}
}
pserialize_read_exit(s);
return error;
Remove a frotz, as a writer, and free it once there are no more readers:
struct frotz **fp, *f;
mutex_enter(&frobbotzim.lock);
for (fp = &frobbotzim.first; (f = *fp) != NULL; fp = &f->f_next) {
if (f->f_... == key) {
/*
* Unhook it from the list. Readers may still
* be traversing the list at this point, so
* the next pointer must remain valid and
* memory must remain allocated.
*/
*fp = f->f_next;
break;
}
}
mutex_exit(&frobbotzim.lock);
/*
* Wait for all existing readers to complete. New readers will
* not see f because the list no longer points to it.
*/
pserialize_perform(frobbotzim.psz);
/* Now nobody else can be touching f, so it is safe to free. */
if (f != NULL)
pool_put(&frotz_pool, f);
π₯ CODE REFERENCES π₯
The pserialize is implemented within the file sys/kern/subr_pserialize.c.
π SEE ALSO π
membar_ops(3)condvar(9)mutex(9)rwlock(9)
Hennessy, et al., Passive serialization in a multitasking environment, US Patent and Trademark Office, US Patent 4809168, February 28, 1989.
π HISTORY π
Passive serialization mechanism first appeared in NetBSD 6.0.
xoxo π β source/version: Debian; date: January 26, 2016 πΈ
π¦ where this page comes from
- nixpkgs unstable: netbsd-source 11.0
- Copyright (c) 2011 The NetBSD Foundation, Inc
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash-1017 on : a language model's rewrite of the original, under its terms