Line | Branch | Exec | Source |
---|---|---|---|
1 | #include "test_threading.h" | ||
2 | |||
3 | #include "gate/threading.h" | ||
4 | #include "gate/synchronization.h" | ||
5 | #include "gate/tests.h" | ||
6 | |||
7 | |||
8 | 1 | GATE_TEST_FUNCTION(test_mutex) | |
9 | { | ||
10 | 1 | gate_mutex_t mutex = GATE_INIT_EMPTY; | |
11 | |||
12 | 1 | GATE_TEST_UNIT_BEGIN(test_mutex); | |
13 | |||
14 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_mutex_create(&mutex)); |
15 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_acquire(&mutex)); |
16 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_release(&mutex)); |
17 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_destroy(&mutex)); |
18 | |||
19 | 1 | GATE_TEST_UNIT_END; | |
20 | } | ||
21 | |||
22 | 1 | GATE_TEST_FUNCTION(test_semaphore) | |
23 | { | ||
24 | 1 | gate_semaphore_t sema = GATE_INIT_EMPTY; | |
25 | |||
26 | 1 | GATE_TEST_UNIT_BEGIN(test_semaphore); | |
27 | |||
28 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_semaphore_create(&sema, 2)); |
29 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_acquire(&sema)); |
30 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_timed_acquire(&sema, 500)); |
31 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_release(&sema)); |
32 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_release(&sema)); |
33 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_destroy(&sema)); |
34 | |||
35 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_semaphore_create(&sema, 1)); |
36 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_acquire(&sema)); |
37 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_RESULT(GATE_RESULT_TIMEOUT, gate_semaphore_timed_acquire(&sema, 200)); |
38 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_release(&sema)); |
39 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_semaphore_destroy(&sema)); |
40 | |||
41 | 1 | GATE_TEST_UNIT_END; | |
42 | } | ||
43 | |||
44 | 1 | GATE_TEST_FUNCTION(test_syncevent) | |
45 | { | ||
46 | 1 | gate_syncevent_t evt = GATE_INIT_EMPTY; | |
47 | |||
48 | 1 | GATE_TEST_UNIT_BEGIN(test_syncevent); | |
49 | |||
50 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_syncevent_create(&evt, false)); |
51 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_syncevent_set(&evt)); |
52 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_syncevent_timed_wait(&evt, 0)); |
53 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_syncevent_reset(&evt)); |
54 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_RESULT(GATE_RESULT_TIMEOUT, gate_syncevent_timed_wait(&evt, 2000)); |
55 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_syncevent_destroy(&evt)); |
56 | |||
57 | 1 | GATE_TEST_UNIT_END; | |
58 | } | ||
59 | |||
60 | 1 | gate_bool_t test_synccondition() | |
61 | { | ||
62 | 1 | gate_mutex_t cond_mutex = GATE_INIT_EMPTY; | |
63 | 1 | gate_synccondition_t cond = GATE_INIT_EMPTY; | |
64 | |||
65 | 1 | GATE_TEST_UNIT_BEGIN(test_synccondition); | |
66 | |||
67 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_mutex_create(&cond_mutex)); |
68 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_synccondition_create(&cond)); |
69 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_acquire(&cond_mutex)); |
70 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_RESULT(GATE_RESULT_TIMEOUT, gate_synccondition_timed_wait(&cond, &cond_mutex, 0)); |
71 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_release(&cond_mutex)); |
72 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_synccondition_signal_one(&cond)); |
73 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_synccondition_destroy(&cond)); |
74 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_destroy(&cond_mutex)); |
75 | |||
76 | 1 | GATE_TEST_UNIT_END; | |
77 | } | ||
78 | |||
79 | |||
80 | |||
81 | 1 | gate_bool_t test_atomics() | |
82 | { | ||
83 | 1 | gate_atomic_flag_t flag_atom = GATE_ATOMIC_FLAG_INIT; | |
84 | gate_atomic_int_t int_atom; | ||
85 | gate_atomic_int64_t int64_atom; | ||
86 | gate_atomic_ptr_t ptr_atom; | ||
87 | 1 | int dummy1 = 42; | |
88 | 1 | int dummy2 = 24; | |
89 | 1 | gate_atomic_lock_t lock_atom = GATE_ATOMIC_LOCK_INIT; | |
90 | |||
91 | 1 | GATE_TEST_UNIT_BEGIN(test_atomic); | |
92 | |||
93 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_flag_set(&flag_atom), false); |
94 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_flag_set(&flag_atom), true); |
95 | 1 | gate_atomic_flag_clear(&flag_atom); | |
96 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_flag_set(&flag_atom), false); |
97 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_flag_set(&flag_atom), true); |
98 | |||
99 | 1 | gate_atomic_int_init(&int_atom, 1); | |
100 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_get(&int_atom), 1); |
101 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_inc(&int_atom), 2); |
102 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_dec(&int_atom), 1); |
103 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_set(&int_atom, 10), 1); |
104 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_add(&int_atom, 10), 20); |
105 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_xchg_if(&int_atom, 10, 100), 20); |
106 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_get(&int_atom), 20); |
107 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_xchg_if(&int_atom, 20, 100), 20); |
108 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int_get(&int_atom), 100); |
109 | |||
110 | 1 | gate_atomic_int64_init(&int64_atom, 1); | |
111 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_get(&int64_atom), 1); |
112 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_inc(&int64_atom), 2); |
113 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_dec(&int64_atom), 1); |
114 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_set(&int64_atom, 10), 1); |
115 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_add(&int64_atom, 10), 20); |
116 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_xchg_if(&int64_atom, 10, 100), 20); |
117 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_get(&int64_atom), 20); |
118 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_xchg_if(&int64_atom, 20, 100), 20); |
119 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_int64_get(&int64_atom), 100); |
120 | |||
121 | 1 | gate_atomic_ptr_init(&ptr_atom, NULL); | |
122 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_set(&ptr_atom, &dummy1), NULL); |
123 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_get(&ptr_atom), &dummy1); |
124 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_xchg_if(&ptr_atom, NULL, &dummy2), &dummy1); |
125 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_get(&ptr_atom), &dummy1); |
126 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_xchg_if(&ptr_atom, &dummy1, &dummy2), &dummy1); |
127 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_ptr_get(&ptr_atom), &dummy2); |
128 | |||
129 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(gate_atomic_lock_acquire_spin(&lock_atom, 1), true); |
130 | 1 | gate_atomic_lock_release(&lock_atom); | |
131 | |||
132 | 1 | GATE_TEST_UNIT_END; | |
133 | } | ||
134 | |||
135 | |||
136 | 1 | static gate_thread_native_return_type GATE_THREAD_API test_thread_entry(gate_thread_native_param_type param) | |
137 | { | ||
138 | 1 | gate_bool_t* ptr_checkpoint_reached = (gate_bool_t*)param; | |
139 | 1 | gate_thread_sleep(10); | |
140 | 1 | *ptr_checkpoint_reached = true; | |
141 | 1 | return (gate_thread_native_return_type)GATE_RESULT_OK; | |
142 | } | ||
143 | |||
144 | 1 | static gate_bool_t test_thread_start_join() | |
145 | { | ||
146 | 1 | gate_bool_t checkpoint_reached = false; | |
147 | 1 | gate_thread_t thread_handle = GATE_INIT_EMPTY; | |
148 | 1 | gate_thread_id_t thread_id = 0; | |
149 | 1 | gate_result_t result = GATE_RESULT_FAILED; | |
150 | |||
151 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_thread_start_native(&test_thread_entry, &checkpoint_reached, &thread_handle, &thread_id)); |
152 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_thread_join(&thread_handle, &result)); |
153 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(result, GATE_RESULT_OK); |
154 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(checkpoint_reached, true); |
155 | 1 | return true; | |
156 | } | ||
157 | |||
158 | typedef struct test_thread_param | ||
159 | { | ||
160 | gate_synccondition_t cond; | ||
161 | gate_mutex_t mutex; | ||
162 | gate_size_t input_data[16]; | ||
163 | gate_size_t input_index; | ||
164 | gate_size_t output_data[16]; | ||
165 | gate_size_t output_index; | ||
166 | gate_bool_t completed; | ||
167 | } test_thread_param_t; | ||
168 | |||
169 | 1 | static gate_thread_native_return_type GATE_THREAD_API test_thread_worker(gate_thread_native_param_type param) | |
170 | { | ||
171 | 1 | test_thread_param_t* ptr_shared = (test_thread_param_t*)param; | |
172 | gate_size_t sz, ndx; | ||
173 | 1 | sz = sizeof(ptr_shared->input_data) / sizeof(ptr_shared->input_data[0]); | |
174 | |||
175 | 1 | ndx = 0; | |
176 | 1 | gate_mutex_acquire(&ptr_shared->mutex); | |
177 |
2/2✓ Branch 0 taken 18 times.
✓ Branch 1 taken 1 times.
|
19 | while (ndx < sz) |
178 | { | ||
179 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 2 times.
|
18 | if (ndx < ptr_shared->input_index) |
180 | { | ||
181 | 16 | ptr_shared->output_data[ndx] = ptr_shared->input_data[ndx]; | |
182 | 16 | ++ptr_shared->output_index; | |
183 | 16 | ++ndx; | |
184 | } | ||
185 | else | ||
186 | { | ||
187 | 2 | gate_synccondition_wait(&ptr_shared->cond, &ptr_shared->mutex); | |
188 | } | ||
189 | } | ||
190 | 1 | gate_mutex_release(&ptr_shared->mutex); | |
191 | |||
192 | 1 | gate_thread_yield(); | |
193 | { | ||
194 | 1 | gate_mutex_acquire(&ptr_shared->mutex); | |
195 | 1 | ptr_shared->completed = true; | |
196 | 1 | gate_synccondition_signal_one(&ptr_shared->cond); | |
197 | 1 | gate_mutex_release(&ptr_shared->mutex); | |
198 | } | ||
199 | 1 | return (gate_thread_native_return_type)GATE_RESULT_OK; | |
200 | } | ||
201 | 1 | static gate_bool_t test_thread_worker_sync() | |
202 | { | ||
203 | 1 | test_thread_param_t shared = GATE_INIT_EMPTY; | |
204 | gate_size_t ndx, sz; | ||
205 | 1 | gate_thread_t thread_handle = GATE_INIT_EMPTY; | |
206 | 1 | gate_thread_id_t thread_id = 0; | |
207 | 1 | gate_result_t result = GATE_RESULT_FAILED; | |
208 | |||
209 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_mutex_create(&shared.mutex)); |
210 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_synccondition_create(&shared.cond)); |
211 | |||
212 | 1 | shared.input_index = 0; | |
213 | 1 | shared.output_index = 0; | |
214 | 1 | sz = sizeof(shared.input_data) / sizeof(shared.input_data[0]); | |
215 | |||
216 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_REQUIRE_OK(gate_thread_start_native(&test_thread_worker, &shared, &thread_handle, &thread_id)); |
217 | |||
218 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
|
17 | for (ndx = 0; ndx != sz; ++ndx) |
219 | { | ||
220 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | GATE_TEST_CHECK_OK(gate_mutex_acquire(&shared.mutex)); |
221 | 16 | shared.input_data[shared.input_index++] = ndx; | |
222 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | GATE_TEST_CHECK_OK(gate_synccondition_signal_one(&shared.cond)); |
223 |
1/2✓ Branch 3 taken 16 times.
✗ Branch 4 not taken.
|
16 | GATE_TEST_CHECK_OK(gate_mutex_release(&shared.mutex)); |
224 | 16 | gate_thread_yield(); | |
225 | } | ||
226 | |||
227 | { | ||
228 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_acquire(&shared.mutex)); |
229 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
|
2 | while (!shared.completed) |
230 | { | ||
231 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_synccondition_wait(&shared.cond, &shared.mutex)); |
232 | } | ||
233 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_release(&shared.mutex)); |
234 | } | ||
235 | |||
236 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_thread_join(&thread_handle, &result)); |
237 |
1/2✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
|
1 | GATE_TEST_CHECK_EQUAL(result, GATE_RESULT_OK); |
238 | |||
239 |
2/2✓ Branch 0 taken 16 times.
✓ Branch 1 taken 1 times.
|
17 | for (ndx = 0; ndx != sz; ++ndx) |
240 | { | ||
241 |
1/2✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
|
16 | GATE_TEST_CHECK_EQUAL(shared.input_data[ndx], shared.output_data[ndx]); |
242 | } | ||
243 | |||
244 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_synccondition_destroy(&shared.cond)); |
245 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK_OK(gate_mutex_destroy(&shared.mutex)); |
246 | |||
247 | 1 | return true; | |
248 | } | ||
249 | |||
250 | |||
251 | 1 | gate_bool_t test_threads() | |
252 | { | ||
253 | int thread_model; | ||
254 | |||
255 | 1 | GATE_TEST_UNIT_BEGIN(test_thread); | |
256 | |||
257 | 1 | thread_model = gate_thread_model(); | |
258 | |||
259 |
1/2✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
|
1 | if (thread_model == GATE_THREAD_MODEL_NATIVE) |
260 | { | ||
261 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK(test_thread_start_join()); |
262 |
1/2✓ Branch 3 taken 1 times.
✗ Branch 4 not taken.
|
1 | GATE_TEST_CHECK(test_thread_worker_sync()); |
263 | } | ||
264 | |||
265 | 1 | GATE_TEST_UNIT_END; | |
266 | } | ||
267 | |||
268 |