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