Blame view
include/linux/once.h
1.65 KB
46234253b
|
1 2 3 4 5 |
#ifndef _LINUX_ONCE_H #define _LINUX_ONCE_H #include <linux/types.h> #include <linux/jump_label.h> |
c90aeb948
|
6 7 8 |
bool __do_once_start(bool *done, unsigned long *flags); void __do_once_done(bool *done, struct static_key *once_key, unsigned long *flags); |
46234253b
|
9 |
|
c90aeb948
|
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
/* Call a function exactly once. The idea of DO_ONCE() is to perform * a function call such as initialization of random seeds, etc, only * once, where DO_ONCE() can live in the fast-path. After @func has * been called with the passed arguments, the static key will patch * out the condition into a nop. DO_ONCE() guarantees type safety of * arguments! * * Not that the following is not equivalent ... * * DO_ONCE(func, arg); * DO_ONCE(func, arg); * * ... to this version: * * void foo(void) * { * DO_ONCE(func, arg); * } * * foo(); * foo(); * * In case the one-time invocation could be triggered from multiple * places, then a common helper function must be defined, so that only * a single static key will be placed there! */ #define DO_ONCE(func, ...) \ ({ \ bool ___ret = false; \ static bool ___done = false; \ static struct static_key ___once_key = STATIC_KEY_INIT_TRUE; \ if (static_key_true(&___once_key)) { \ unsigned long ___flags; \ ___ret = __do_once_start(&___done, &___flags); \ if (unlikely(___ret)) { \ func(__VA_ARGS__); \ __do_once_done(&___done, &___once_key, \ &___flags); \ } \ } \ ___ret; \ |
46234253b
|
51 |
}) |
c90aeb948
|
52 53 |
#define get_random_once(buf, nbytes) \ DO_ONCE(get_random_bytes, (buf), (nbytes)) |
46234253b
|
54 |
#endif /* _LINUX_ONCE_H */ |