66#ifdef CMARK_THREADING
77
88#include <pthread.h>
9- #include <stdatomic.h>
109
11- static CMARK_INLINE bool check_latch (atomic_int * latch ) {
12- int expected = 0 ;
13- if (atomic_compare_exchange_strong (latch , & expected , 1 )) {
14- return true;
15- } else {
16- return false;
17- }
18- }
10+ #define CMARK_DEFINE_ONCE (NAME ) static pthread_once_t NAME##_once = PTHREAD_ONCE_INIT;
1911
20- static CMARK_INLINE void initialize_mutex_once (pthread_mutex_t * m , atomic_int * latch ) {
21- if (check_latch (latch )) {
22- pthread_mutex_init (m , NULL );
23- }
24- }
12+ #define CMARK_RUN_ONCE (NAME , FUNC ) pthread_once(&NAME##_once, FUNC)
2513
2614#define CMARK_DEFINE_LOCK (NAME ) \
2715static pthread_mutex_t NAME##_lock; \
28- static atomic_int NAME##_latch = 0;
16+ CMARK_DEFINE_ONCE(NAME); \
17+ static void initialize_##NAME() { pthread_mutex_init(&NAME##_lock, NULL); }
2918
3019#define CMARK_INITIALIZE_AND_LOCK (NAME ) \
31- initialize_mutex_once(& NAME##_lock, &NAME##_latch ); \
20+ CMARK_RUN_ONCE( NAME, initialize_##NAME ); \
3221pthread_mutex_lock(&NAME##_lock);
3322
3423#define CMARK_UNLOCK (NAME ) pthread_mutex_unlock(&NAME##_lock);
3524
36- #define CMARK_DEFINE_LATCH (NAME ) static atomic_int NAME = 0;
37-
38- #define CMARK_CHECK_LATCH (NAME ) check_latch(&NAME)
39-
4025#else // no threading support
4126
4227static CMARK_INLINE bool check_latch (int * latch ) {
@@ -52,9 +37,9 @@ static CMARK_INLINE bool check_latch(int *latch) {
5237#define CMARK_INITIALIZE_AND_LOCK (NAME )
5338#define CMARK_UNLOCK (NAME )
5439
55- #define CMARK_DEFINE_LATCH static int NAME = 0;
40+ #define CMARK_DEFINE_ONCE ( NAME ) static int NAME = 0;
5641
57- #define CMARK_CHECK_LATCH check_latch(&NAME)
42+ #define CMARK_RUN_ONCE ( NAME , FUNC ) if ( check_latch(&NAME)) FUNC();
5843
5944#endif // CMARK_THREADING
6045
0 commit comments