Messages in this thread Patch in this message | | | Date | Mon, 10 Mar 2008 23:57:05 +0900 | From | Akinobu Mita <> | Subject | [PATCH 1/5] lib: introduce call_once() |
| |
call_once() is an utility function which has similar functionality of pthread_once().
Signed-off-by: Akinobu Mita <akinobu.mita@gmail.com> --- include/linux/once.h | 42 ++++++++++++++++++++++++++++++++++++++++++ lib/Makefile | 2 +- lib/once.c | 18 ++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-)
Index: 2.6-rc/include/linux/once.h =================================================================== --- /dev/null +++ 2.6-rc/include/linux/once.h @@ -0,0 +1,42 @@ +#ifndef __LINUX_ONCE_H +#define __LINUX_ONCE_H + +#include <linux/kernel.h> +#include <linux/mutex.h> + +struct once_control { + struct mutex lock; + int done; +}; + +#define __ONCE_INITIALIZER(name) { \ + .lock = __MUTEX_INITIALIZER(name.lock), \ + .done = 0, \ + } + +#define DEFINE_ONCE(name) struct once_control name = __ONCE_INITIALIZER(name) + +extern int call_once_slow(struct once_control *once_control, + int (*init_rouine)(void)); + +/* + * call_once - call the initialization function only once + * + * @once_control: guarantee that the init_routine will be called only once + * @init_routine: initialization function + * + * The first call to call_once(), with a given once_control, shall call the + * init_routine with no arguments and return the value init_routine returned. + * If the init_routine returns zero which indicates the initialization + * succeeded, subsequent calls of call_once() with the same once_control shall + * not call the init_routine and return zero. + */ + +static inline int call_once(struct once_control *once_control, + int (*init_rouine)(void)) +{ + return likely(once_control->done) ? 0 + : call_once_slow(once_control, init_rouine); +} + +#endif /* __LINUX_ONCE_H */ Index: 2.6-rc/lib/once.c =================================================================== --- /dev/null +++ 2.6-rc/lib/once.c @@ -0,0 +1,18 @@ +#include <linux/module.h> +#include <linux/once.h> + +int call_once_slow(struct once_control *once_control, int (*init_rouine)(void)) +{ + int err = 0; + + mutex_lock(&once_control->lock); + if (!once_control->done) { + err = init_rouine(); + if (!err) + once_control->done = 1; + } + mutex_unlock(&once_control->lock); + + return err; +} +EXPORT_SYMBOL_GPL(call_once_slow); Index: 2.6-rc/lib/Makefile =================================================================== --- 2.6-rc.orig/lib/Makefile +++ 2.6-rc/lib/Makefile @@ -14,7 +14,7 @@ lib-$(CONFIG_SMP) += cpumask.o lib-y += kobject.o kref.o klist.o obj-y += div64.o sort.o parser.o halfmd4.o debug_locks.o random32.o \ - bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o + bust_spinlocks.o hexdump.o kasprintf.o bitmap.o scatterlist.o once.o ifeq ($(CONFIG_DEBUG_KOBJECT),y) CFLAGS_kobject.o += -DDEBUG
| |