1 /*
2 * Copyright 2022 Yonggang Luo
3 * SPDX-License-Identifier: MIT
4 *
5 * Testing u_call_once.h
6 */
7
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <gtest/gtest.h>
11
12 #include "c11/threads.h"
13 #include "util/u_atomic.h"
14 #include "util/u_call_once.h"
15
16 #define NUM_DEBUG_TEST_THREAD 8
17
update_x(int * x)18 static void update_x(int *x) {
19 p_atomic_inc(x);
20 }
21
22 static int xC;
update_x_global(void)23 static void update_x_global(void)
24 {
25 update_x(&xC);
26 }
27
test_call_once(void * _state)28 static int test_call_once(void *_state)
29 {
30 static int xA = 0;
31 {
32 static once_flag once = ONCE_FLAG_INIT;
33 for (int i = 0; i < 100; i += 1) {
34 util_call_once_data_slow(&once, (util_call_once_data_func)update_x, &xA);
35 }
36 }
37
38 static int xB = 0;
39 {
40 static util_once_flag once = UTIL_ONCE_FLAG_INIT;
41 for (int i = 0; i < 100; i += 1) {
42 util_call_once_data(&once, (util_call_once_data_func)update_x, &xB);
43 }
44 }
45 {
46 static util_once_flag once = UTIL_ONCE_FLAG_INIT;
47 for (int i = 0; i < 100; i += 1) {
48 util_call_once(&once, update_x_global);
49 }
50 }
51 EXPECT_EQ(xA, 1);
52 EXPECT_EQ(xB, 1);
53 EXPECT_EQ(xC, 1);
54 return 0;
55 }
56
TEST(UtilCallOnce,Multithread)57 TEST(UtilCallOnce, Multithread)
58 {
59 thrd_t threads[NUM_DEBUG_TEST_THREAD];
60 for (unsigned i = 0; i < NUM_DEBUG_TEST_THREAD; i++) {
61 thrd_create(&threads[i], test_call_once, NULL);
62 }
63 for (unsigned i = 0; i < NUM_DEBUG_TEST_THREAD; i++) {
64 int ret;
65 thrd_join(threads[i], &ret);
66 }
67 }
68