once.h 1.7 KB

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