Skip to content

Commit fdc42a1

Browse files
committed
add CallOnce
1 parent 204583b commit fdc42a1

File tree

3 files changed

+91
-0
lines changed

3 files changed

+91
-0
lines changed

src/platform.h.in

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@
7777
#else
7878
#include <pthread.h>
7979
#endif
80+
#if __cplusplus >= 201103L
81+
#include <mutex>
82+
#endif
8083
#endif // NCNN_THREADS
8184

8285
#if __ANDROID_API__ >= 26
@@ -141,6 +144,22 @@ public:
141144
private:
142145
DWORD key;
143146
};
147+
148+
#if __cplusplus < 201103L
149+
typedef INIT_ONCE OnceFlag;
150+
#define OnceFlagInit INIT_ONCE_STATIC_INIT
151+
152+
static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void))
153+
{
154+
BOOL pending = FALSE;
155+
InitOnceBeginInitialize(&flag, 0, &pending, NULL);
156+
if (pending)
157+
init_routine();
158+
InitOnceComplete(&flag, 0, NULL);
159+
return 0;
160+
}
161+
#endif // < c++11
162+
144163
#else // defined _WIN32
145164
class NCNN_EXPORT Mutex
146165
{
@@ -186,7 +205,30 @@ public:
186205
private:
187206
pthread_key_t key;
188207
};
208+
209+
#if __cplusplus < 201103L
210+
typedef pthread_once_t OnceFlag;
211+
#define OnceFlagInit PTHREAD_ONCE_INIT
212+
213+
static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void))
214+
{
215+
return pthread_once(&flag, init_routine);
216+
}
217+
#endif // < c++11
218+
189219
#endif // defined _WIN32
220+
221+
#if __cplusplus >= 201103L
222+
using OnceFlag = std::once_flag;
223+
#define OnceFlagInit {}
224+
225+
static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void))
226+
{
227+
std::call_once(flag, init_routine);
228+
return 0;
229+
}
230+
#endif // >= c++11
231+
190232
#else // NCNN_THREADS
191233
class NCNN_EXPORT Mutex
192234
{
@@ -225,6 +267,21 @@ public:
225267
private:
226268
void* data;
227269
};
270+
271+
typedef bool OnceFlag;
272+
#define OnceFlagInit false
273+
274+
static inline int CallOnce(OnceFlag &flag, void (*init_routine)(void))
275+
{
276+
if (!flag)
277+
{
278+
init_routine();
279+
flag = true;
280+
}
281+
282+
return 0;
283+
}
284+
228285
#endif // NCNN_THREADS
229286

230287
class NCNN_EXPORT MutexLockGuard

tests/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ endif()
6060

6161
ncnn_add_test(c_api)
6262
ncnn_add_test(cpu)
63+
ncnn_add_test(platform)
6364

6465
if(NCNN_VULKAN)
6566
ncnn_add_test(command)

tests/test_platform.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#include <stdlib.h>
2+
3+
#include "platform.h"
4+
5+
static int g_once_count = 0;
6+
7+
static void init()
8+
{
9+
g_once_count++;
10+
}
11+
12+
int test_call_once()
13+
{
14+
static ncnn::OnceFlag flag = OnceFlagInit;
15+
ncnn::CallOnce(flag, &init);
16+
ncnn::CallOnce(flag, &init);
17+
ncnn::CallOnce(flag, &init);
18+
19+
if (g_once_count != 1)
20+
return EXIT_FAILURE;
21+
return EXIT_SUCCESS;
22+
}
23+
24+
int main()
25+
{
26+
int ret;
27+
28+
ret = test_call_once();
29+
if (ret)
30+
return ret;
31+
32+
return 0;
33+
}

0 commit comments

Comments
 (0)