| PSERIALIZE(9) | Kernel Developer's Manual | PSERIALIZE(9) | 
pserialize —
#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);
IPL_SOFTCLOCK.
pserialize_create()pserialize_destroy()pserialize_read_enter()pserialize_read_exit()pserialize_perform()
	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;
		}
	}
	/*
	 * 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.  */
	mutex_exit(&frobbotzim.lock);
	if (f != NULL)
		pool_put(&frotz_pool, f);
pserialize is implemented within the file
  sys/kern/subr_pserialize.c.
Hennessy, et al., Passive serialization in a multitasking environment, US Patent and Trademark Office, US Patent 4809168, February 28, 1989.
| January 26, 2016 | NetBSD 9.4 |