/* Helpers used from arbitrary contexts. * Hard irqs are blocked, be cautious.
*/ bool __do_once_start(bool *done, unsignedlong *flags); void __do_once_done(bool *done, struct static_key_true *once_key, unsignedlong *flags, struct module *mod);
/* Variant for process contexts only. */ bool __do_once_sleepable_start(bool *done); void __do_once_sleepable_done(bool *done, struct static_key_true *once_key, struct module *mod);
/* 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! * * Note 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; \ staticbool __section(".data..do_once") ___done = false; \ static DEFINE_STATIC_KEY_TRUE(___once_key); \ if (static_branch_unlikely(&___once_key)) { \ unsignedlong ___flags; \
___ret = __do_once_start(&___done, &___flags); \ if (unlikely(___ret)) { \
func(__VA_ARGS__); \
__do_once_done(&___done, &___once_key, \
&___flags, THIS_MODULE); \
} \
} \
___ret; \
})
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.