| PSERIALIZE(9) | Kernel Developer's Manual | PSERIALIZE(9) |
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);
struct frotz {
...
struct frotz *f_next;
};
kmutex_t frobbotzim_lock;
struct frotz *frobbotzim;
pserialize_t frobbotzim_psz;
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; /* * Publish the contents of f->f_next before we publish the * pointer to f in frobbotzim. */ membar_producer(); frobbotzim = 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; f != NULL; f = f->f_next) {
/* Fetch f before we fetch anything f points to. */
membar_consumer();
if (f->f_... = key) {
*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; (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);
Hennessy, et al., Passive serialization in a multitasking environment, US Patent and Trademark Office, US Patent 4809168, February 28, 1989.
| November 21, 2014 | NetBSD 7.1 |