From 0ca79c8677debc81a44ea6b21156c72383a7c6a3 Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Wed, 4 Sep 2024 21:38:49 +0800 Subject: [PATCH 1/2] add CallOnce --- src/platform.h.in | 57 +++++++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/test_platform.cpp | 33 ++++++++++++++++++++++++ 3 files changed, 91 insertions(+) create mode 100644 tests/test_platform.cpp diff --git a/src/platform.h.in b/src/platform.h.in index 50a9454b7da0..732b2f0871b0 100644 --- a/src/platform.h.in +++ b/src/platform.h.in @@ -77,6 +77,9 @@ #else #include #endif +#if (__cplusplus >= 201103L) && !NCNN_SIMPLESTL +#include +#endif #endif // NCNN_THREADS #if __ANDROID_API__ >= 26 @@ -141,6 +144,22 @@ public: private: DWORD key; }; + +#if (__cplusplus < 201103L) || NCNN_SIMPLESTL +typedef INIT_ONCE OnceFlag; +#define OnceFlagInit INIT_ONCE_STATIC_INIT + +static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void)) +{ + BOOL pending = FALSE; + InitOnceBeginInitialize(&flag, 0, &pending, NULL); + if (pending) + init_routine(); + InitOnceComplete(&flag, 0, NULL); + return 0; +} +#endif // < c++11 + #else // defined _WIN32 class NCNN_EXPORT Mutex { @@ -186,7 +205,30 @@ public: private: pthread_key_t key; }; + +#if (__cplusplus < 201103L) || NCNN_SIMPLESTL +typedef pthread_once_t OnceFlag; +#define OnceFlagInit PTHREAD_ONCE_INIT + +static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void)) +{ + return pthread_once(&flag, init_routine); +} +#endif // < c++11 + #endif // defined _WIN32 + +#if (__cplusplus >= 201103L) && !NCNN_SIMPLESTL +using OnceFlag = std::once_flag; +#define OnceFlagInit {} + +static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void)) +{ + std::call_once(flag, init_routine); + return 0; +} +#endif // >= c++11 + #else // NCNN_THREADS class NCNN_EXPORT Mutex { @@ -225,6 +267,21 @@ public: private: void* data; }; + +typedef bool OnceFlag; +#define OnceFlagInit false + +static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void)) +{ + if (!flag) + { + init_routine(); + flag = true; + } + + return 0; +} + #endif // NCNN_THREADS class NCNN_EXPORT MutexLockGuard diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index e2ddc32a00dc..44634959dd51 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -60,6 +60,7 @@ endif() ncnn_add_test(c_api) ncnn_add_test(cpu) +ncnn_add_test(platform) if(NCNN_VULKAN) ncnn_add_test(command) diff --git a/tests/test_platform.cpp b/tests/test_platform.cpp new file mode 100644 index 000000000000..21f59ba61853 --- /dev/null +++ b/tests/test_platform.cpp @@ -0,0 +1,33 @@ +#include + +#include "platform.h" + +static int g_once_count = 0; + +static void init() +{ + g_once_count++; +} + +int test_call_once() +{ + static ncnn::OnceFlag flag = OnceFlagInit; + ncnn::CallOnce(flag, &init); + ncnn::CallOnce(flag, &init); + ncnn::CallOnce(flag, &init); + + if (g_once_count != 1) + return EXIT_FAILURE; + return EXIT_SUCCESS; +} + +int main() +{ + int ret; + + ret = test_call_once(); + if (ret) + return ret; + + return 0; +} From decbf28b3ef5b06c148f72e05b8bcba52b7b555c Mon Sep 17 00:00:00 2001 From: Zhao Zhili Date: Wed, 4 Sep 2024 21:50:56 +0800 Subject: [PATCH 2/2] make try_initialize_global_cpu_info thread safe --- src/cpu.cpp | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/cpu.cpp b/src/cpu.cpp index f9e64a1cc75b..b6a3e37913ee 100644 --- a/src/cpu.cpp +++ b/src/cpu.cpp @@ -1932,15 +1932,10 @@ static void initialize_global_cpu_info() #endif // defined __ANDROID__ || defined __linux__ } -static int g_cpu_info_initialized = 0; - static inline void try_initialize_global_cpu_info() { - if (!g_cpu_info_initialized) - { - initialize_global_cpu_info(); - g_cpu_info_initialized = 1; - } + static ncnn::OnceFlag flag = OnceFlagInit; + ncnn::CallOnce(flag, &initialize_global_cpu_info); } namespace ncnn {