diff options
author | Richard Braun <rbraun@sceen.net> | 2014-09-20 02:26:06 +0200 |
---|---|---|
committer | Richard Braun <rbraun@sceen.net> | 2014-09-20 02:26:06 +0200 |
commit | 600f0097618e9085fabf6f7ecc0283a5bb9f044d (patch) | |
tree | 28cf0f93671a6d02631be2d279a24e6197e305db /kern/sref.h | |
parent | 65c9a187a9926181534939480a4034b06b10b71e (diff) |
kern/sref: new module
This module provides multiprocessor scalable reference counters, based
on Refcache, as described in the RadixVM paper.
Diffstat (limited to 'kern/sref.h')
-rw-r--r-- | kern/sref.h | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/kern/sref.h b/kern/sref.h new file mode 100644 index 00000000..c854b9d2 --- /dev/null +++ b/kern/sref.h @@ -0,0 +1,104 @@ +/* + * Copyright (c) 2014 Richard Braun. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + * + * + * Scalable reference counting. + * + * The purpose of this module is to reduce the amount of inter-processor + * communication usually involved with reference counting. Scalable + * reference counters should only be used when multiprocessor scalability + * is important because of the costs they imply (increased memory usage + * and latencies). + * + * When a counter drops to 0, the no-reference function associated with it + * is called in work context. As a result, special care must be taken if + * using sref counters in the work module itself. + */ + +#ifndef _KERN_SREF_H +#define _KERN_SREF_H + +#include <kern/spinlock.h> + +struct sref_counter; + +/* + * Type for no-reference functions. + */ +typedef void (*sref_noref_fn_t)(struct sref_counter *); + +#include <kern/sref_i.h> + +/* + * Early initialization of the sref module. + * + * This function depends on the availability of percpu variables. + */ +void sref_bootstrap(void); + +/* + * Initialize the sref module. + * + * This function mostly takes care of setting up periodic maintenance. + */ +void sref_setup(void); + +/* + * Manage registration of the current processor. + * + * Registering tells the sref module that the current processor reports + * periodic events. When a processor enters a state in which reporting + * periodic events becomes irrelevant, it unregisters itself so that the + * other registered processors don't need to wait for it to make progress. + * For example, this is done inside the idle loop since it is obviously + * impossible to obtain or release references while idling. + * + * Unregistration can fail if internal data still require processing, in + * which case a maintenance thread is awaken and ERROR_BUSY is returned. + * + * Preemption must be disabled when calling these functions. + */ +void sref_register(void); +int sref_unregister(void); + +/* + * Report a periodic event (normally the periodic timer interrupt) on the + * current processor. + * + * Interrupts and preemption must be disabled when calling this function. + */ +void sref_report_periodic_event(void); + +/* + * Initialize a scalable reference counter. + * + * The counter is set to 1. The no-reference function is called (from thread + * context) when it is certain that the true number of references is 0. + */ +static inline void +sref_counter_init(struct sref_counter *counter, sref_noref_fn_t noref_fn) +{ + counter->noref_fn = noref_fn; + spinlock_init(&counter->lock); + counter->flags = 0; + counter->value = 1; +} + +void sref_counter_inc(struct sref_counter *counter); + +void sref_counter_dec(struct sref_counter *counter); + +#endif /* _KERN_SREF_H */ |