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