GCC Code Coverage Report


Directory: src/
File: src/apis/DLB_interface.c
Date: 2024-11-22 17:07:10
Exec Total Coverage
Lines: 170 201 84.6%
Functions: 44 45 97.8%
Branches: 33 62 53.2%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2024 Barcelona Supercomputing Center */
3 /* */
4 /* This file is part of the DLB library. */
5 /* */
6 /* DLB is free software: you can redistribute it and/or modify */
7 /* it under the terms of the GNU Lesser General Public License as published by */
8 /* the Free Software Foundation, either version 3 of the License, or */
9 /* (at your option) any later version. */
10 /* */
11 /* DLB is distributed in the hope that it will be useful, */
12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
14 /* GNU Lesser General Public License for more details. */
15 /* */
16 /* You should have received a copy of the GNU Lesser General Public License */
17 /* along with DLB. If not, see <https://www.gnu.org/licenses/>. */
18 /*********************************************************************************/
19
20 #include "apis/dlb.h"
21
22 #include "LB_core/node_barrier.h"
23 #include "LB_core/spd.h"
24 #include "LB_core/DLB_kernel.h"
25 #include "LB_comm/shmem_procinfo.h"
26 #include "support/env.h"
27 #include "support/error.h"
28 #include "support/debug.h"
29
30 #include <unistd.h>
31 #include <stdlib.h>
32 #include <string.h>
33 #include <stdio.h>
34
35
36 #pragma GCC visibility push(default)
37
38 /* Status */
39
40 27 int DLB_Init(int ncpus, const_dlb_cpu_set_t mask, const char *dlb_args) {
41 27 spd_enter_dlb(thread_spd);
42
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 3 times.
27 if (__sync_bool_compare_and_swap(&thread_spd->dlb_initialized, false, true) ) {
43 24 return Initialize(thread_spd, getpid(), ncpus, mask, dlb_args);
44 } else {
45 3 return DLB_ERR_INIT;
46 }
47 }
48
49 28 int DLB_Finalize(void) {
50 28 spd_enter_dlb(thread_spd);
51
2/2
✓ Branch 0 taken 24 times.
✓ Branch 1 taken 4 times.
28 if (__sync_bool_compare_and_swap(&thread_spd->dlb_initialized, true, false) ) {
52 24 return Finish(thread_spd);
53
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
4 } else if (__sync_bool_compare_and_swap(&thread_spd->dlb_preinitialized, true, false) ) {
54 /* This is to support the case when a single process does DLB_PreInit + DLB_Init
55 * The first DLB_Finalize must finalize everything except the CPUs not inherited
56 * during DLB_Init, if any. The second finalize must clean up the procinfo shmem.
57 */
58 3 shmem_procinfo__finalize(thread_spd->id,
59 3 thread_spd->options.debug_opts & DBG_RETURNSTOLEN,
60 3 thread_spd->options.shm_key);
61 3 return DLB_SUCCESS;
62 }
63 1 return DLB_NOUPDT;
64 }
65
66 3 int DLB_PreInit(const_dlb_cpu_set_t mask, char ***next_environ) {
67 3 spd_enter_dlb(thread_spd);
68
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!thread_spd->dlb_initialized
69
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 && __sync_bool_compare_and_swap(&thread_spd->dlb_preinitialized, false, true)) {
70
71 /* DLB_PreInit must modify the environment so that a process child
72 * knows what CPUs must inherit */
73 char flag[32];
74 3 snprintf(flag, 32, "--preinit-pid=%d", getpid());
75 3 dlb_setenv("DLB_ARGS", flag, next_environ, ENV_APPEND);
76
77 3 return PreInitialize(thread_spd, mask, NULL);
78 } else {
79 return DLB_ERR_INIT;
80 }
81 }
82
83 2 int DLB_Enable(void) {
84 2 spd_enter_dlb(thread_spd);
85
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
86 return DLB_ERR_NOINIT;
87 }
88 2 return set_lewi_enabled(thread_spd, true);
89 }
90
91 2 int DLB_Disable(void) {
92 2 spd_enter_dlb(thread_spd);
93
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
94 return DLB_ERR_NOINIT;
95 }
96 2 return set_lewi_enabled(thread_spd, false);
97 }
98
99 2 int DLB_SetMaxParallelism(int max) {
100 2 spd_enter_dlb(thread_spd);
101
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
102 return DLB_ERR_NOINIT;
103 }
104 2 return set_max_parallelism(thread_spd, max);
105 }
106
107 1 int DLB_UnsetMaxParallelism(void) {
108 1 spd_enter_dlb(thread_spd);
109
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (unlikely(!thread_spd->dlb_initialized)) {
110 return DLB_ERR_NOINIT;
111 }
112 1 return unset_max_parallelism(thread_spd);
113 }
114
115
116 /* Callbacks */
117
118 38 int DLB_CallbackSet(dlb_callbacks_t which, dlb_callback_t callback, void *arg) {
119 38 spd_enter_dlb(thread_spd);
120 38 return pm_callback_set(&thread_spd->pm, which, callback, arg);
121 }
122
123 1 int DLB_CallbackGet(dlb_callbacks_t which, dlb_callback_t *callback, void **arg) {
124 1 spd_enter_dlb(thread_spd);
125 1 return pm_callback_get(&thread_spd->pm, which, callback, arg);
126 }
127
128
129 /* Lend */
130
131 4 int DLB_Lend(void) {
132 4 spd_enter_dlb(thread_spd);
133
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (unlikely(!thread_spd->dlb_initialized)) {
134 return DLB_ERR_NOINIT;
135 }
136 4 return lend(thread_spd);
137 }
138
139 6 int DLB_LendCpu(int cpuid) {
140 6 spd_enter_dlb(thread_spd);
141
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
6 if (unlikely(!thread_spd->dlb_initialized)) {
142 return DLB_ERR_NOINIT;
143 }
144 6 return lend_cpu(thread_spd, cpuid);
145 }
146
147 2 int DLB_LendCpus(int ncpus) {
148 2 spd_enter_dlb(thread_spd);
149
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
150 return DLB_ERR_NOINIT;
151 }
152 2 return lend_cpus(thread_spd, ncpus);
153 }
154
155 4 int DLB_LendCpuMask(const_dlb_cpu_set_t mask) {
156 4 spd_enter_dlb(thread_spd);
157
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (unlikely(!thread_spd->dlb_initialized)) {
158 return DLB_ERR_NOINIT;
159 }
160 4 return lend_cpu_mask(thread_spd, mask);
161 }
162
163
164 /* Reclaim */
165
166 3 int DLB_Reclaim(void) {
167 3 spd_enter_dlb(thread_spd);
168
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (unlikely(!thread_spd->dlb_initialized)) {
169 return DLB_ERR_NOINIT;
170 }
171 3 return reclaim(thread_spd);
172 }
173
174 2 int DLB_ReclaimCpu(int cpuid) {
175 2 spd_enter_dlb(thread_spd);
176
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
177 return DLB_ERR_NOINIT;
178 }
179 2 return reclaim_cpu(thread_spd, cpuid);
180 }
181
182 2 int DLB_ReclaimCpus(int ncpus) {
183 2 spd_enter_dlb(thread_spd);
184
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
185 return DLB_ERR_NOINIT;
186 }
187 2 return reclaim_cpus(thread_spd, ncpus);
188 }
189
190 3 int DLB_ReclaimCpuMask(const_dlb_cpu_set_t mask) {
191 3 spd_enter_dlb(thread_spd);
192
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (unlikely(!thread_spd->dlb_initialized)) {
193 return DLB_ERR_NOINIT;
194 }
195 3 return reclaim_cpu_mask(thread_spd, mask);
196 }
197
198
199 /* Acquire */
200
201 3 int DLB_AcquireCpu(int cpuid) {
202 3 spd_enter_dlb(thread_spd);
203
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 if (unlikely(!thread_spd->dlb_initialized)) {
204 return DLB_ERR_NOINIT;
205 }
206 3 return acquire_cpu(thread_spd, cpuid);
207 }
208
209 13 int DLB_AcquireCpus(int ncpus) {
210 13 spd_enter_dlb(thread_spd);
211
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 13 times.
13 if (unlikely(!thread_spd->dlb_initialized)) {
212 return DLB_ERR_NOINIT;
213 }
214 13 return acquire_cpus(thread_spd, ncpus);
215 }
216
217 2 int DLB_AcquireCpuMask(const_dlb_cpu_set_t mask) {
218 2 spd_enter_dlb(thread_spd);
219
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
220 return DLB_ERR_NOINIT;
221 }
222 2 return acquire_cpu_mask(thread_spd, mask);
223 }
224
225 9 int DLB_AcquireCpusInMask(int ncpus, const_dlb_cpu_set_t mask) {
226 9 spd_enter_dlb(thread_spd);
227
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 if (unlikely(!thread_spd->dlb_initialized)) {
228 return DLB_ERR_NOINIT;
229 }
230 9 return acquire_cpus_in_mask(thread_spd, ncpus, mask);
231 }
232
233
234 /* Borrow */
235
236 2 int DLB_Borrow(void) {
237 2 spd_enter_dlb(thread_spd);
238
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
239 return DLB_ERR_NOINIT;
240 }
241 2 return borrow(thread_spd);
242 }
243
244 2 int DLB_BorrowCpu(int cpuid) {
245 2 spd_enter_dlb(thread_spd);
246
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
247 return DLB_ERR_NOINIT;
248 }
249 2 return borrow_cpu(thread_spd, cpuid);
250 }
251
252 2 int DLB_BorrowCpus(int ncpus) {
253 2 spd_enter_dlb(thread_spd);
254
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
255 return DLB_ERR_NOINIT;
256 }
257 2 return borrow_cpus(thread_spd, ncpus);
258 }
259
260 2 int DLB_BorrowCpuMask(const_dlb_cpu_set_t mask) {
261 2 spd_enter_dlb(thread_spd);
262
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
263 return DLB_ERR_NOINIT;
264 }
265 2 return borrow_cpu_mask(thread_spd, mask);
266 }
267
268 2 int DLB_BorrowCpusInMask(int ncpus, const_dlb_cpu_set_t mask) {
269 2 spd_enter_dlb(thread_spd);
270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
271 return DLB_ERR_NOINIT;
272 }
273 2 return borrow_cpus_in_mask(thread_spd, ncpus, mask);
274 }
275
276
277 /* Return */
278
279 2 int DLB_Return(void) {
280 2 spd_enter_dlb(thread_spd);
281
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
282 return DLB_ERR_NOINIT;
283 }
284 2 return return_all(thread_spd);
285 }
286
287 8 int DLB_ReturnCpu(int cpuid) {
288 8 spd_enter_dlb(thread_spd);
289
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 8 times.
8 if (unlikely(!thread_spd->dlb_initialized)) {
290 return DLB_ERR_NOINIT;
291 }
292 8 return return_cpu(thread_spd, cpuid);
293 }
294
295 2 int DLB_ReturnCpuMask(const_dlb_cpu_set_t mask) {
296 2 spd_enter_dlb(thread_spd);
297
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (unlikely(!thread_spd->dlb_initialized)) {
298 return DLB_ERR_NOINIT;
299 }
300 2 return return_cpu_mask(thread_spd, mask);
301 }
302
303
304 /* DROM Responsive */
305
306 4 int DLB_PollDROM(int *ncpus, dlb_cpu_set_t mask) {
307 4 spd_enter_dlb(thread_spd);
308
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (unlikely(!thread_spd->dlb_initialized)) {
309 return DLB_ERR_NOINIT;
310 }
311 4 return poll_drom(thread_spd, ncpus, mask);
312 }
313
314 int DLB_PollDROM_Update(void) {
315 spd_enter_dlb(thread_spd);
316 if (unlikely(!thread_spd->dlb_initialized)) {
317 return DLB_ERR_NOINIT;
318 }
319 return poll_drom_update(thread_spd);
320 }
321
322
323 /* Misc */
324
325 17 int DLB_CheckCpuAvailability(int cpuid) {
326 17 spd_enter_dlb(thread_spd);
327 17 return check_cpu_availability(thread_spd, cpuid);
328 }
329
330 3 int DLB_Barrier(void) {
331 3 spd_enter_dlb(thread_spd);
332 3 return node_barrier(thread_spd, NULL);
333 }
334
335 4 int DLB_BarrierAttach(void) {
336 4 spd_enter_dlb(thread_spd);
337 4 return node_barrier_attach(thread_spd, NULL);
338 }
339
340 7 int DLB_BarrierDetach(void) {
341 7 spd_enter_dlb(thread_spd);
342 7 return node_barrier_detach(thread_spd, NULL);
343 }
344
345 2 dlb_barrier_t* DLB_BarrierNamedRegister(const char *barrier_name,
346 dlb_barrier_flags_t flags) {
347 2 spd_enter_dlb(thread_spd);
348 2 return (dlb_barrier_t*)node_barrier_register(thread_spd, barrier_name, flags);
349 }
350
351 dlb_barrier_t* DLB_BarrierNamedGet(const char *barrier_name,
352 dlb_barrier_flags_t flags)
353 __attribute__((alias("DLB_BarrierNamedRegister")));
354
355 2 int DLB_BarrierNamed(dlb_barrier_t *barrier) {
356 2 spd_enter_dlb(thread_spd);
357 2 return node_barrier(thread_spd, (barrier_t*)barrier);
358 }
359
360 1 int DLB_BarrierNamedAttach(dlb_barrier_t *barrier) {
361 1 spd_enter_dlb(thread_spd);
362 1 return node_barrier_attach(thread_spd, (barrier_t*)barrier);
363 }
364
365 1 int DLB_BarrierNamedDetach(dlb_barrier_t *barrier) {
366 1 spd_enter_dlb(thread_spd);
367 1 return node_barrier_detach(thread_spd, (barrier_t*)barrier);
368 }
369
370 2 int DLB_SetVariable(const char *variable, const char *value) {
371 2 spd_enter_dlb(thread_spd);
372 2 return options_set_variable(&thread_spd->options, variable, value);
373 }
374
375 3 int DLB_GetVariable(const char *variable, char *value) {
376 3 spd_enter_dlb(thread_spd);
377 3 return options_get_variable(&thread_spd->options, variable, value);
378 }
379
380 1 int DLB_PrintVariables(int print_extended) {
381 1 spd_enter_dlb(thread_spd);
382 1 options_print_variables(&thread_spd->options, print_extended);
383 1 return DLB_SUCCESS;
384 }
385
386 6 int DLB_PrintShmem(int num_columns, dlb_printshmem_flags_t print_flags) {
387 6 spd_enter_dlb(thread_spd);
388 6 return print_shmem(thread_spd, num_columns, print_flags);
389 }
390
391 1 const char* DLB_Strerror(int errnum) {
392 1 return error_get_str(errnum);
393 }
394
395 1 int DLB_SetObserverRole(bool thread_is_observer) {
396 1 spd_enter_dlb(thread_spd);
397 1 return set_observer_role(thread_is_observer);
398 }
399
400 #pragma GCC visibility pop
401