1 | /* SPDX-License-Identifier: GPL-2.0 */ |
2 | #ifndef _LINUX_ONCE_LITE_H |
3 | #define _LINUX_ONCE_LITE_H |
4 | |
5 | #include <linux/types.h> |
6 | |
7 | /* Call a function once. Similar to DO_ONCE(), but does not use jump label |
8 | * patching via static keys. |
9 | */ |
10 | #define DO_ONCE_LITE(func, ...) \ |
11 | DO_ONCE_LITE_IF(true, func, ##__VA_ARGS__) |
12 | |
13 | #define __ONCE_LITE_IF(condition) \ |
14 | ({ \ |
15 | static bool __section(".data.once") __already_done; \ |
16 | bool __ret_cond = !!(condition); \ |
17 | bool __ret_once = false; \ |
18 | \ |
19 | if (unlikely(__ret_cond && !__already_done)) { \ |
20 | __already_done = true; \ |
21 | __ret_once = true; \ |
22 | } \ |
23 | unlikely(__ret_once); \ |
24 | }) |
25 | |
26 | #define DO_ONCE_LITE_IF(condition, func, ...) \ |
27 | ({ \ |
28 | bool __ret_do_once = !!(condition); \ |
29 | \ |
30 | if (__ONCE_LITE_IF(__ret_do_once)) \ |
31 | func(__VA_ARGS__); \ |
32 | \ |
33 | unlikely(__ret_do_once); \ |
34 | }) |
35 | |
36 | #endif /* _LINUX_ONCE_LITE_H */ |
37 | |