GCC Code Coverage Report


Directory: src/
File: src/LB_core/DLB_kernel.c
Date: 2026-02-23 15:13:19
Exec Total Coverage
Lines: 308 397 77.6%
Functions: 33 35 94.3%
Branches: 185 292 63.4%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2022 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 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23
24 #include "LB_core/DLB_kernel.h"
25
26 #include "LB_core/node_barrier.h"
27 #include "LB_core/spd.h"
28 #include "LB_numThreads/numThreads.h"
29 #include "LB_numThreads/omptool.h"
30 #include "LB_comm/shmem_async.h"
31 #include "LB_comm/shmem_barrier.h"
32 #include "LB_comm/shmem_cpuinfo.h"
33 #include "LB_comm/shmem_procinfo.h"
34 #include "LB_comm/shmem_talp.h"
35 #include "apis/dlb_errors.h"
36 #include "apis/dlb_talp.h"
37 #include "plugins/plugin_manager.h"
38 #include "support/debug.h"
39 #include "support/mytime.h"
40 #include "support/tracing.h"
41 #include "support/options.h"
42 #include "support/mask_utils.h"
43 #include "talp/talp.h"
44 #include "talp/talp_mpi.h"
45 #ifdef MPI_LIB
46 #include "mpi/mpi_core.h"
47 #endif
48
49 #include <limits.h>
50 #include <sched.h>
51 #include <string.h>
52
53
54 /* By default all threads are participants.
55 * A thread may change this value to avoid participating in LeWI and TALP metrics. */
56 __thread bool thread_is_observer = false;
57
58
59 /* Status */
60
61 85 int Initialize(subprocess_descriptor_t *spd, pid_t id, int ncpus,
62 const cpu_set_t *mask, const char *lb_args) {
63
64 85 int error = DLB_SUCCESS;
65
66 // Set it to false in case one thread is an observer but then Initializes DLB
67 85 thread_is_observer = false;
68
69 // Initialize common modules (spd->id and instrumentation module ASAP)
70 85 *spd = (const subprocess_descriptor_t) {
71 .id = id,
72 85 .pid = getpid(),
73 85 .dlb_initialized = spd->dlb_initialized,
74 85 .dlb_preinitialized = spd->dlb_preinitialized,
75 };
76 85 options_init(&spd->options, lb_args);
77 85 debug_init(&spd->options);
78 init_tracing(&spd->options);
79 instrument_event(RUNTIME_EVENT, EVENT_INIT, EVENT_BEGIN);
80 85 mu_init();
81 85 timer_init();
82
83 // Infer LeWI mode
84 85 spd->lb_policy =
85
4/4
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 57 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 32 times.
142 !spd->options.lewi ? POLICY_NONE :
86
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 spd->options.lewi_affinity == LEWI_AFFINITY_NONE ? POLICY_LEWI :
87
1/2
✓ Branch 0 taken 57 times.
✗ Branch 1 not taken.
57 spd->options.lewi_affinity != LEWI_AFFINITY_AUTO ? POLICY_LEWI_MASK :
88
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 55 times.
57 spd->options.ompt ? POLICY_LEWI_MASK :
89
2/2
✓ Branch 0 taken 53 times.
✓ Branch 1 taken 2 times.
55 spd->options.preinit_pid ? POLICY_LEWI_MASK :
90 mask ? POLICY_LEWI_MASK :
91 POLICY_LEWI;
92
93
2/2
✓ Branch 0 taken 32 times.
✓ Branch 1 taken 53 times.
85 if (spd->lb_policy == POLICY_LEWI
94
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 27 times.
32 && spd->options.mode == MODE_ASYNC) {
95 5 spd->lb_policy = POLICY_LEWI_ASYNC;
96 }
97
98 // Check if real process mask is needed and possible incompatibilities
99 // (Basically, always except if classic LeWI)
100 85 bool mask_is_needed = (
101 85 spd->lb_policy == POLICY_LEWI_MASK
102
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 11 times.
60 || spd->options.drom
103
4/4
✓ Branch 0 taken 60 times.
✓ Branch 1 taken 25 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 48 times.
145 || spd->options.preinit_pid);
104
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 48 times.
85 if (mask_is_needed &&
105
2/4
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 37 times.
37 (spd->lb_policy == POLICY_LEWI || spd->lb_policy == POLICY_LEWI_ASYNC)) {
106 warning("Classic LeWI support with no cpuset binding is not compatible"
107 " with newer DLB modules. DLB_Init cannot continue.");
108 return DLB_ERR_NOCOMP;
109 }
110
111 // Initialize the rest of the subprocess descriptor
112 85 pm_init(&spd->pm);
113 85 set_lb_funcs(&spd->lb_funcs, spd->lb_policy);
114
2/2
✓ Branch 0 taken 45 times.
✓ Branch 1 taken 40 times.
85 if (mask) {
115 // Preferred case, mask is provided by the user
116 45 memcpy(&spd->process_mask, mask, sizeof(cpu_set_t));
117 } else {
118 // Best effort querying the system
119 // (it may be late if DLB_Init is called after other RT sets this thread's affinity)
120 40 sched_getaffinity(0, sizeof(cpu_set_t), &spd->process_mask);
121 }
122
123 // ncpus is only used for classic LeWI
124
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 27 times.
85 if (spd->lb_policy == POLICY_LEWI
125
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 53 times.
58 || spd->lb_policy == POLICY_LEWI_ASYNC) {
126
2/2
✓ Branch 0 taken 28 times.
✓ Branch 1 taken 4 times.
32 spd->lewi_ncpus = ncpus > 0 ? ncpus : pm_get_num_threads();
127 }
128
129 // Initialize shared memories
130
2/2
✓ Branch 0 taken 37 times.
✓ Branch 1 taken 48 times.
85 if (mask_is_needed) {
131 // Initialize procinfo
132
1/2
✓ Branch 0 taken 37 times.
✗ Branch 1 not taken.
37 if (spd->options.lewi_color == 0) {
133 cpu_set_t new_process_mask;
134 37 error = shmem_procinfo__init(spd->id, spd->options.preinit_pid,
135 37 &spd->process_mask, &new_process_mask, spd->options.shm_key,
136 spd->options.shm_size_multiplier);
137
138 // If the process has been pre-initialized (error=DLB_NOTED),
139 // the mask provided by shmem_procinfo__init must overwrite the process mask
140
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 29 times.
37 if (error == DLB_NOTED) {
141 8 set_process_mask(&spd->pm, &new_process_mask);
142 8 memcpy(&spd->process_mask, &new_process_mask, sizeof(cpu_set_t));
143 8 error = DLB_SUCCESS;
144 }
145 } else {
146 // If using --lewi-color, we also need to initialize procinfo with cpu sharing
147 error = shmem_procinfo__init_with_cpu_sharing(spd->id, spd->options.preinit_pid,
148 &spd->process_mask, spd->options.shm_key, spd->options.shm_size_multiplier);
149 }
150
151
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 35 times.
37 if (error != DLB_SUCCESS) return error;
152
153 // Initialize cpuinfo
154 35 error = shmem_cpuinfo__init(spd->id, spd->options.preinit_pid,
155 35 &spd->process_mask, spd->options.shm_key, spd->options.lewi_color);
156
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 35 times.
35 if (error != DLB_SUCCESS) return error;
157
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 42 times.
48 } else if (spd->options.talp) {
158 // If mask is not needed but TALP is enabled, we still need to
159 // initialize shmem_procinfo but allowing CPU sharing
160 6 error = shmem_procinfo__init_with_cpu_sharing(spd->id, spd->options.preinit_pid,
161 6 &spd->process_mask, spd->options.shm_key, spd->options.shm_size_multiplier);
162 }
163
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 3 times.
83 if (spd->options.barrier) {
164 80 shmem_barrier__init(spd->options.shm_key, spd->options.shm_size_multiplier);
165 80 node_barrier_init(spd);
166 }
167
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 72 times.
83 if (spd->options.mode == MODE_ASYNC) {
168 11 error = shmem_async_init(spd->id, &spd->pm, &spd->process_mask,
169 11 spd->options.shm_key, spd->options.shm_size_multiplier);
170
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 if (error != DLB_SUCCESS) return error;
171 }
172
173 // Initialise LeWI
174 83 error = spd->lb_funcs.init(spd);
175
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 if (error != DLB_SUCCESS) return error;
176
177 // Initialize TALP
178
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 76 times.
83 if (spd->options.talp) {
179 7 talp_init(spd);
180 } else {
181 76 spd->talp_info = NULL;
182 }
183
184 // Initialize plugins
185 83 load_plugins(spd->options.plugins);
186
187 // Print initialization summary
188 83 info0("%s %s", PACKAGE, VERSION);
189
2/2
✓ Branch 0 taken 57 times.
✓ Branch 1 taken 26 times.
83 if (spd->lb_policy != POLICY_NONE) {
190 57 info0("Balancing policy: %s", policy_tostr(spd->lb_policy));
191 57 options_print_lewi_flags(&spd->options);
192 }
193 instrument_print_flags();
194
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_API, "Enabled verbose mode for DLB API");
195
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_MPI_API, "Enabled verbose mode for MPI API");
196
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_MPI_INT, "Enabled verbose mode for MPI Interception");
197
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_SHMEM, "Enabled verbose mode for Shared Memory");
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_DROM, "Enabled verbose mode for DROM");
199
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_STATS, "Enabled verbose mode for STATS");
200
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_MICROLB, "Enabled verbose mode for microLB policies");
201
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_ASYNC, "Enabled verbose mode for Asynchronous thread");
202
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 verbose0(VB_OMPT, "Enabled verbose mode for OMPT experimental features");
203
204
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 83 times.
83 if (spd->options.verbose & VB_AFFINITY) {
205 print_buffer_t buffer;
206 mu_get_system_description(&buffer);
207 verbose0(VB_AFFINITY, "System affinity\n%s", buffer.addr);
208 printbuffer_destroy(&buffer);
209 }
210
211 // Print number of cpus or mask
212
2/2
✓ Branch 0 taken 35 times.
✓ Branch 1 taken 48 times.
83 if (mask_is_needed) {
213 35 info("Process CPU affinity mask: %s", mu_to_str(&spd->process_mask));
214 }
215
216 83 spd->lewi_enabled = true;
217 instrument_event(RUNTIME_EVENT, EVENT_INIT, EVENT_END);
218 instrument_event(DLB_MODE_EVENT, EVENT_ENABLED, EVENT_BEGIN);
219
220 83 return error;
221 }
222
223 83 int Finish(subprocess_descriptor_t *spd) {
224
225 /* Protect finalization if spd does not match with current process */
226
1/2
✗ Branch 1 not taken.
✓ Branch 2 taken 83 times.
83 if (spd->pid != getpid()) {
227 return DLB_NOUPDT;
228 }
229
230 83 int error = DLB_SUCCESS;
231 instrument_event(RUNTIME_EVENT, EVENT_FINALIZE, EVENT_BEGIN);
232
233 #if MPI_LIB
234 /* If DLB_Finalize is called preemptively, we need to finalize also the MPI
235 * module */
236 finalize_mpi_core();
237 #endif
238
239 83 spd->lewi_enabled = false;
240
241 83 pm_finalize(&spd->pm);
242
243 // Finalize plugins
244 83 unload_plugins(spd->options.plugins);
245
246
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 76 times.
83 if (spd->options.talp) {
247 7 talp_finalize(spd);
248 }
249
1/2
✓ Branch 0 taken 83 times.
✗ Branch 1 not taken.
83 if (spd->lb_funcs.finalize) {
250 83 spd->lb_funcs.finalize(spd);
251 83 spd->lb_funcs.finalize = NULL;
252 }
253
2/2
✓ Branch 0 taken 80 times.
✓ Branch 1 taken 3 times.
83 if (spd->options.barrier) {
254 80 node_barrier_finalize(spd);
255 80 shmem_barrier__finalize(spd->options.shm_key, spd->options.shm_size_multiplier);
256 }
257
2/2
✓ Branch 0 taken 58 times.
✓ Branch 1 taken 25 times.
83 if (spd->lb_policy == POLICY_LEWI_MASK
258
2/2
✓ Branch 0 taken 49 times.
✓ Branch 1 taken 9 times.
58 || spd->options.drom
259
2/2
✓ Branch 0 taken 43 times.
✓ Branch 1 taken 6 times.
49 || spd->options.talp
260
2/2
✓ Branch 0 taken 41 times.
✓ Branch 1 taken 2 times.
43 || spd->options.ompt
261
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 40 times.
41 || spd->options.preinit_pid) {
262 43 shmem_cpuinfo__finalize(spd->id, spd->options.shm_key, spd->options.lewi_color);
263 43 shmem_procinfo__finalize(spd->id, spd->options.debug_opts & DBG_RETURNSTOLEN,
264 43 spd->options.shm_key, spd->options.shm_size_multiplier);
265 }
266
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 72 times.
83 if (spd->options.mode == MODE_ASYNC) {
267 11 shmem_async_finalize(spd->id);
268 }
269 83 timer_finalize();
270 instrument_event(RUNTIME_EVENT, EVENT_FINALIZE, EVENT_END);
271 instrument_finalize();
272 83 options_finalize(&spd->options);
273 83 return error;
274 }
275
276 5 int PreInitialize(subprocess_descriptor_t *spd, const cpu_set_t *mask,
277 const char *lb_args) {
278 // Initialize options
279 5 options_init(&spd->options, lb_args);
280
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (spd->options.preinit_pid == 0) return DLB_ERR_INIT;
281
282 5 debug_init(&spd->options);
283
284 // Initialize subprocess descriptor
285 5 spd->lb_policy = POLICY_NONE;
286 5 pm_init(&spd->pm);
287 5 set_lb_funcs(&spd->lb_funcs, spd->lb_policy);
288 5 spd->id = spd->options.preinit_pid;
289 5 memcpy(&spd->process_mask, mask, sizeof(cpu_set_t));
290
291 // Initialize modules
292 5 int error = DLB_SUCCESS;
293
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 error = error ? error : shmem_cpuinfo_ext__init(spd->options.shm_key, spd->options.lewi_color);
294
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 error = error ? error : shmem_procinfo_ext__init(spd->options.shm_key,
295 spd->options.shm_size_multiplier);
296
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 error = error ? error : shmem_procinfo_ext__preinit(spd->id, mask, DLB_DROM_FLAGS_NONE);
297
1/2
✓ Branch 0 taken 5 times.
✗ Branch 1 not taken.
5 error = error ? error : shmem_cpuinfo_ext__preinit(spd->id, mask, DLB_DROM_FLAGS_NONE);
298 // Close shmems even if there was an error
299 5 int cpuinfo_finalize_err = shmem_cpuinfo_ext__finalize();
300
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 error = error ? error : cpuinfo_finalize_err;
301 5 int procinfo_finalize_err = shmem_procinfo_ext__finalize();
302
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 error = error ? error : procinfo_finalize_err;
303 5 return error;
304 }
305
306 18 int set_lewi_enabled(subprocess_descriptor_t *spd, bool enabled) {
307 18 int error = DLB_SUCCESS;
308
2/2
✓ Branch 0 taken 14 times.
✓ Branch 1 taken 4 times.
18 if (__sync_bool_compare_and_swap(&spd->lewi_enabled, !enabled, enabled)) {
309
2/2
✓ Branch 0 taken 7 times.
✓ Branch 1 taken 7 times.
14 if (enabled) {
310 7 spd->lb_funcs.enable(spd);
311 instrument_event(DLB_MODE_EVENT, EVENT_ENABLED, EVENT_BEGIN);
312 } else {
313 7 spd->lb_funcs.disable(spd);
314 instrument_event(DLB_MODE_EVENT, EVENT_DISABLED, EVENT_BEGIN);
315 }
316 } else {
317 4 error = DLB_NOUPDT;
318 }
319 18 return error;
320 }
321
322 5 int set_max_parallelism(subprocess_descriptor_t *spd, int max) {
323 int error;
324
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (!spd->options.lewi) {
325 3 error = DLB_ERR_NOLEWI;
326
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 } else if (!spd->lewi_enabled) {
327 error = DLB_ERR_DISBLD;
328 } else {
329 instrument_event(RUNTIME_EVENT, EVENT_MAX_PARALLELISM, EVENT_BEGIN);
330 instrument_event(MAX_PAR_EVENT, 0, EVENT_END);
331 instrument_event(MAX_PAR_EVENT, max, EVENT_BEGIN);
332 2 error = spd->lb_funcs.set_max_parallelism(spd, max);
333 instrument_event(RUNTIME_EVENT, EVENT_MAX_PARALLELISM, EVENT_END);
334 }
335 5 return error;
336 }
337
338 3 int unset_max_parallelism(subprocess_descriptor_t *spd) {
339 int error;
340
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (!spd->options.lewi) {
341 1 error = DLB_ERR_NOLEWI;
342
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 } else if (!spd->lewi_enabled) {
343 error = DLB_ERR_DISBLD;
344 } else {
345 instrument_event(RUNTIME_EVENT, EVENT_MAX_PARALLELISM, EVENT_BEGIN);
346 instrument_event(MAX_PAR_EVENT, 0, EVENT_END);
347 2 error = spd->lb_funcs.unset_max_parallelism(spd);
348 instrument_event(RUNTIME_EVENT, EVENT_MAX_PARALLELISM, EVENT_END);
349 }
350 3 return error;
351 }
352
353
354 /* Sync-call specific (MPI, DLB_Barrier, etc.) */
355
356 18 void into_sync_call(sync_call_flags_t flags) {
357 /* Observer threads do not trigger LeWI nor TALP on sync calls */
358
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 if (unlikely(thread_is_observer)) return;
359
360 16 const subprocess_descriptor_t *spd = thread_spd;
361
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (unlikely(spd == NULL)) return;
362
363
3/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 if (spd->options.lewi && spd->lewi_enabled && flags.do_lewi) {
364 16 spd->lb_funcs.into_blocking_call(spd);
365 16 omptool__into_blocking_call();
366 }
367
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(spd->options.talp) {
368 talp_into_sync_call(spd, flags.is_blocking && flags.is_collective);
369 }
370 }
371
372 18 void out_of_sync_call(sync_call_flags_t flags) {
373 /* Observer threads do not trigger LeWI nor TALP on MPI calls */
374
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 16 times.
18 if (unlikely(thread_is_observer)) return;
375
376 16 const subprocess_descriptor_t *spd = thread_spd;
377
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if (unlikely(spd == NULL)) return;
378
379
3/6
✓ Branch 0 taken 16 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 16 times.
✗ Branch 5 not taken.
16 if (spd->options.lewi && spd->lewi_enabled && flags.do_lewi) {
380 16 spd->lb_funcs.out_of_blocking_call(spd);
381 16 omptool__outof_blocking_call();
382 }
383
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 if(spd->options.talp) {
384 talp_out_of_sync_call(spd, flags.is_blocking && flags.is_collective);
385 }
386 }
387
388
389 /* Lend */
390
391 8 int lend(const subprocess_descriptor_t *spd) {
392 int error;
393
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 if (!spd->options.lewi) {
394 6 error = DLB_ERR_NOLEWI;
395
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 } else if (!spd->lewi_enabled) {
396 2 error = DLB_ERR_DISBLD;
397 } else {
398 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_BEGIN);
399 instrument_event(GIVE_CPUS_EVENT, CPU_SETSIZE, EVENT_BEGIN);
400 omptool__lend_from_api();
401 error = spd->lb_funcs.lend(spd);
402 instrument_event(GIVE_CPUS_EVENT, 0, EVENT_END);
403 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_END);
404 }
405 8 return error;
406 }
407
408 40 int lend_cpu(const subprocess_descriptor_t *spd, int cpuid) {
409 int error;
410
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 37 times.
40 if (!spd->options.lewi) {
411 3 error = DLB_ERR_NOLEWI;
412
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 37 times.
37 } else if (!spd->lewi_enabled) {
413 error = DLB_ERR_DISBLD;
414 } else {
415 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_BEGIN);
416 instrument_event(GIVE_CPUS_EVENT, 1, EVENT_BEGIN);
417 37 error = spd->lb_funcs.lend_cpu(spd, cpuid);
418 instrument_event(GIVE_CPUS_EVENT, 0, EVENT_END);
419 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_END);
420 }
421 40 return error;
422 }
423
424 6 int lend_cpus(const subprocess_descriptor_t *spd, int ncpus) {
425 int error;
426
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!spd->options.lewi) {
427 3 error = DLB_ERR_NOLEWI;
428
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 } else if (!spd->lewi_enabled) {
429 error = DLB_ERR_DISBLD;
430 } else {
431 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_BEGIN);
432 instrument_event(GIVE_CPUS_EVENT, ncpus, EVENT_BEGIN);
433 3 error = spd->lb_funcs.lend_cpus(spd, ncpus);
434 instrument_event(GIVE_CPUS_EVENT, 0, EVENT_END);
435 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_END);
436 }
437 6 return error;
438 }
439
440 18 int lend_cpu_mask(const subprocess_descriptor_t *spd, const cpu_set_t *mask) {
441 int error;
442
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 15 times.
18 if (!spd->options.lewi) {
443 3 error = DLB_ERR_NOLEWI;
444
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 } else if (!spd->lewi_enabled) {
445 error = DLB_ERR_DISBLD;
446 } else {
447 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_BEGIN);
448 instrument_event(GIVE_CPUS_EVENT, CPU_COUNT(mask), EVENT_BEGIN);
449 15 error = spd->lb_funcs.lend_cpu_mask(spd, mask);
450 instrument_event(GIVE_CPUS_EVENT, 0, EVENT_END);
451 instrument_event(RUNTIME_EVENT, EVENT_LEND, EVENT_END);
452 }
453 18 return error;
454 }
455
456
457 /* Reclaim */
458
459 6 int reclaim(const subprocess_descriptor_t *spd) {
460 int error;
461
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (!spd->options.lewi) {
462 3 error = DLB_ERR_NOLEWI;
463
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 } else if (!spd->lewi_enabled) {
464 error = DLB_ERR_DISBLD;
465 } else {
466 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_BEGIN);
467 instrument_event(WANT_CPUS_EVENT, CPU_SETSIZE, EVENT_BEGIN);
468 3 error = spd->lb_funcs.reclaim(spd);
469 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
470 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_END);
471 }
472 6 return error;
473 }
474
475 5 int reclaim_cpu(const subprocess_descriptor_t *spd, int cpuid) {
476 int error;
477
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2 times.
5 if (!spd->options.lewi) {
478 3 error = DLB_ERR_NOLEWI;
479
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 } else if (!spd->lewi_enabled) {
480 error = DLB_ERR_DISBLD;
481 } else {
482 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_BEGIN);
483 instrument_event(WANT_CPUS_EVENT, 1, EVENT_BEGIN);
484 2 error = spd->lb_funcs.reclaim_cpu(spd, cpuid);
485 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
486 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_END);
487 }
488 5 return error;
489 }
490
491 3 int reclaim_cpus(const subprocess_descriptor_t *spd, int ncpus) {
492 int error;
493
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
494 3 error = DLB_ERR_NOLEWI;
495 } else if (!spd->lewi_enabled) {
496 error = DLB_ERR_DISBLD;
497 } else {
498 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_BEGIN);
499 instrument_event(WANT_CPUS_EVENT, ncpus, EVENT_BEGIN);
500 error = spd->lb_funcs.reclaim_cpus(spd, ncpus);
501 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
502 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_END);
503 }
504 3 return error;
505 }
506
507 8 int reclaim_cpu_mask(const subprocess_descriptor_t *spd, const cpu_set_t *mask) {
508 int error;
509
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 5 times.
8 if (!spd->options.lewi) {
510 3 error = DLB_ERR_NOLEWI;
511
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 } else if (!spd->lewi_enabled) {
512 error = DLB_ERR_DISBLD;
513 } else {
514 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_BEGIN);
515 instrument_event(WANT_CPUS_EVENT, CPU_COUNT(mask), EVENT_BEGIN);
516 5 error = spd->lb_funcs.reclaim_cpu_mask(spd, mask);
517 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
518 instrument_event(RUNTIME_EVENT, EVENT_RECLAIM, EVENT_END);
519 }
520 8 return error;
521 }
522
523
524 /* Acquire */
525
526 13 int acquire_cpu(const subprocess_descriptor_t *spd, int cpuid) {
527 int error;
528
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 10 times.
13 if (!spd->options.lewi) {
529 3 error = DLB_ERR_NOLEWI;
530
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 10 times.
10 } else if (!spd->lewi_enabled) {
531 error = DLB_ERR_DISBLD;
532 } else {
533 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_BEGIN);
534 instrument_event(WANT_CPUS_EVENT, 1, EVENT_BEGIN);
535 10 error = spd->lb_funcs.acquire_cpu(spd, cpuid);
536 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
537 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_END);
538 }
539 13 return error;
540 }
541
542 61 int acquire_cpus(const subprocess_descriptor_t *spd, int ncpus) {
543 int error;
544
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 58 times.
61 if (!spd->options.lewi) {
545 3 error = DLB_ERR_NOLEWI;
546
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58 times.
58 } else if (!spd->lewi_enabled) {
547 error = DLB_ERR_DISBLD;
548 } else {
549 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_BEGIN);
550 instrument_event(WANT_CPUS_EVENT, ncpus, EVENT_BEGIN);
551 58 error = spd->lb_funcs.acquire_cpus(spd, ncpus);
552 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
553 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_END);
554 }
555 61 return error;
556 }
557
558 12 int acquire_cpu_mask(const subprocess_descriptor_t *spd, const cpu_set_t *mask) {
559 int error;
560
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 if (!spd->options.lewi) {
561 3 error = DLB_ERR_NOLEWI;
562
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 9 times.
9 } else if (!spd->lewi_enabled) {
563 error = DLB_ERR_DISBLD;
564 } else {
565 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_BEGIN);
566 instrument_event(WANT_CPUS_EVENT, CPU_COUNT(mask), EVENT_BEGIN);
567 9 error = spd->lb_funcs.acquire_cpu_mask(spd, mask);
568 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
569 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_END);
570 }
571 12 return error;
572 }
573
574 14 int acquire_cpus_in_mask(const subprocess_descriptor_t *spd, int ncpus, const cpu_set_t *mask) {
575 int error;
576
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (!spd->options.lewi) {
577 3 error = DLB_ERR_NOLEWI;
578
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 11 times.
11 } else if (!spd->lewi_enabled) {
579 error = DLB_ERR_DISBLD;
580 } else {
581 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_BEGIN);
582 instrument_event(WANT_CPUS_EVENT, ncpus, EVENT_BEGIN);
583 11 error = spd->lb_funcs.acquire_cpus_in_mask(spd, ncpus, mask);
584 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
585 instrument_event(RUNTIME_EVENT, EVENT_ACQUIRE, EVENT_END);
586 }
587 14 return error;
588 }
589
590
591 /* Borrow */
592
593 7 int borrow(const subprocess_descriptor_t *spd) {
594 int error;
595
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (!spd->options.lewi) {
596 3 error = DLB_ERR_NOLEWI;
597
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (!spd->lewi_enabled) {
598 error = DLB_ERR_DISBLD;
599 } else {
600 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_BEGIN);
601 instrument_event(WANT_CPUS_EVENT, CPU_SETSIZE, EVENT_BEGIN);
602 4 error = spd->lb_funcs.borrow(spd);
603 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
604 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_END);
605 }
606 7 return error;
607 }
608
609 3 int borrow_cpu(const subprocess_descriptor_t *spd, int cpuid) {
610 int error;
611
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
612 3 error = DLB_ERR_NOLEWI;
613 } else if (!spd->lewi_enabled) {
614 error = DLB_ERR_DISBLD;
615 } else {
616 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_BEGIN);
617 instrument_event(WANT_CPUS_EVENT, 1, EVENT_BEGIN);
618 error = spd->lb_funcs.borrow_cpu(spd, cpuid);
619 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
620 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_END);
621 }
622 3 return error;
623 }
624
625 3 int borrow_cpus(const subprocess_descriptor_t *spd, int ncpus) {
626 int error;
627
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
628 3 error = DLB_ERR_NOLEWI;
629 } else if (!spd->lewi_enabled) {
630 error = DLB_ERR_DISBLD;
631 } else {
632 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_BEGIN);
633 instrument_event(WANT_CPUS_EVENT, ncpus, EVENT_BEGIN);
634 error = spd->lb_funcs.borrow_cpus(spd, ncpus);
635 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
636 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_END);
637 }
638 3 return error;
639 }
640
641 3 int borrow_cpu_mask(const subprocess_descriptor_t *spd, const cpu_set_t *mask) {
642 int error;
643
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
644 3 error = DLB_ERR_NOLEWI;
645 } else if (!spd->lewi_enabled) {
646 error = DLB_ERR_DISBLD;
647 } else {
648 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_BEGIN);
649 instrument_event(WANT_CPUS_EVENT, CPU_COUNT(mask), EVENT_BEGIN);
650 error = spd->lb_funcs.borrow_cpu_mask(spd, mask);
651 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
652 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_END);
653 }
654 3 return error;
655 }
656
657 7 int borrow_cpus_in_mask(const subprocess_descriptor_t *spd, int ncpus, const cpu_set_t *mask) {
658 int error;
659
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 4 times.
7 if (!spd->options.lewi) {
660 3 error = DLB_ERR_NOLEWI;
661
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 } else if (!spd->lewi_enabled) {
662 error = DLB_ERR_DISBLD;
663 } else {
664 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_BEGIN);
665 instrument_event(WANT_CPUS_EVENT, ncpus, EVENT_BEGIN);
666 4 error = spd->lb_funcs.borrow_cpus_in_mask(spd, ncpus, mask);
667 instrument_event(WANT_CPUS_EVENT, 0, EVENT_END);
668 instrument_event(RUNTIME_EVENT, EVENT_BORROW, EVENT_END);
669 }
670 7 return error;
671 }
672
673 /* Return */
674
675 3 int return_all(const subprocess_descriptor_t *spd) {
676 int error;
677
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
678 3 error = DLB_ERR_NOLEWI;
679 } else if (!spd->lewi_enabled) {
680 error = DLB_ERR_DISBLD;
681 } else {
682 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_BEGIN);
683 error = spd->lb_funcs.return_all(spd);
684 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_END);
685 }
686 3 return error;
687 }
688
689 19 int return_cpu(const subprocess_descriptor_t *spd, int cpuid) {
690 int error;
691
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 16 times.
19 if (!spd->options.lewi) {
692 3 error = DLB_ERR_NOLEWI;
693
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
16 } else if (!spd->lewi_enabled) {
694 error = DLB_ERR_DISBLD;
695 } else {
696 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_BEGIN);
697 16 error = spd->lb_funcs.return_cpu(spd, cpuid);
698 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_END);
699 }
700 19 return error;
701 }
702
703 3 int return_cpu_mask(const subprocess_descriptor_t *spd, const cpu_set_t *mask) {
704 int error;
705
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (!spd->options.lewi) {
706 3 error = DLB_ERR_NOLEWI;
707 } else if (!spd->lewi_enabled) {
708 error = DLB_ERR_DISBLD;
709 } else {
710 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_BEGIN);
711 error = spd->lb_funcs.return_cpu_mask(spd, mask);
712 instrument_event(RUNTIME_EVENT, EVENT_RETURN, EVENT_END);
713 }
714 3 return error;
715 }
716
717
718 /* Drom Responsive */
719
720 5 int poll_drom(const subprocess_descriptor_t *spd, int *new_cpus, cpu_set_t *new_mask) {
721 int error;
722
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 3 times.
5 if (!spd->options.drom) {
723 2 error = DLB_ERR_NOCOMP;
724 } else {
725 instrument_event(RUNTIME_EVENT, EVENT_POLLDROM, EVENT_BEGIN);
726 // Use a local mask if new_mask was not provided
727 cpu_set_t local_mask;
728
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 cpu_set_t *mask = new_mask ? new_mask : &local_mask;
729
730 3 error = shmem_procinfo__polldrom(spd->id, new_cpus, mask);
731
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 if (error == DLB_SUCCESS) {
732
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (spd->options.lewi) {
733 /* If LeWI, resolve reclaimed CPUs */
734 spd->lb_funcs.update_ownership(spd, mask);
735 } else {
736 /* Otherwise, udate owner and guest data */
737 1 shmem_cpuinfo__update_ownership(spd->id, mask, NULL);
738 }
739 }
740 instrument_event(RUNTIME_EVENT, EVENT_POLLDROM, EVENT_END);
741 }
742 5 return error;
743 }
744
745 int poll_drom_update(const subprocess_descriptor_t *spd) {
746 cpu_set_t new_mask;
747 int error = poll_drom(spd, NULL, &new_mask);
748 if (error == DLB_SUCCESS) {
749 set_process_mask(&spd->pm, &new_mask);
750 }
751 return error;
752 }
753
754 14 int drom_setprocessmask(int pid, const_dlb_cpu_set_t mask, dlb_drom_flags_t flags) {
755 cpu_set_t free_cpu_mask;
756 14 int error = shmem_procinfo__setprocessmask(pid, mask, flags, &free_cpu_mask);
757
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
14 if (error == DLB_SUCCESS
758
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 && thread_spd->dlb_initialized
759
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
3 && (pid == 0 || pid == thread_spd->id)
760
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 && !(flags & DLB_NO_SYNC)) {
761 /* Mask has been successfully set by own process, do like a poll_drom_update */
762
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (thread_spd->options.lewi) {
763 /* If LeWI, resolve reclaimed CPUs */
764 thread_spd->lb_funcs.update_ownership(thread_spd, mask);
765 } else {
766 /* Otherwise, udate owner and guest data */
767 2 shmem_cpuinfo__update_ownership(thread_spd->id, mask, NULL);
768 }
769 2 set_process_mask(&thread_spd->pm, mask);
770 }
771
3/4
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 8 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 6 times.
14 if (error == DLB_SUCCESS && (flags & DLB_FREE_CPUS_SLURM)) {
772 // Slurm freeing
773 char *mask_str = mu_parse_to_slurm_format(&free_cpu_mask);
774 if (mask_str == NULL) {
775 warning("error parsing mask %s to Slurm format", mu_to_str(&free_cpu_mask));
776 return DLB_ERR_UNKNOWN;
777 }
778 if (!secure_getenv("SLURM_JOBID")) {
779 warning("SLURM_JOBID is mandatory");
780 return DLB_ERR_UNKNOWN;
781 }
782 char hostname[HOST_NAME_MAX];
783 gethostname(hostname, HOST_NAME_MAX);
784 char *args[5];
785 asprintf(&args[0], "scontrol");
786 asprintf(&args[1], "update");
787 asprintf(&args[2], "jobid=%s", secure_getenv("SLURM_JOBID"));
788 asprintf(&args[3], "dealloc=%s:%s", hostname, mask_str);
789 args[4] = NULL;
790
791 int res_pid = fork();
792 if (res_pid < 0) {
793 warning("fork error while invoking scontrol");
794 return DLB_ERR_UNKNOWN;
795 } else if (res_pid == 0) {
796 verbose(VB_DROM, "%s %s %s %s", args[0], args[1], args[2], args[3]);
797 execvp("scontrol", args);
798 }
799
800 for (int i = 0; i < 5; ++i) {
801 free(args[i]);
802 }
803 free(mask_str);
804 }
805
806 14 return error;
807 }
808
809
810 /* Misc */
811
812 24 int check_cpu_availability(const subprocess_descriptor_t *spd, int cpuid) {
813 24 int error = DLB_SUCCESS;
814
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 23 times.
24 if (!spd->options.lewi) {
815 1 error = DLB_ERR_NOLEWI;
816
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 23 times.
23 } else if (!spd->lewi_enabled) {
817 error = DLB_ERR_DISBLD;
818 } else {
819 23 error = spd->lb_funcs.check_cpu_availability(spd, cpuid);
820 }
821 24 return error;
822 }
823
824 4 int print_shmem(subprocess_descriptor_t *spd, int num_columns,
825 dlb_printshmem_flags_t print_flags) {
826
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!spd->dlb_initialized) {
827 options_init(&spd->options, NULL);
828 debug_init(&spd->options);
829 }
830
831 4 shmem_cpuinfo__print_info(spd->options.shm_key, spd->options.lewi_color,
832 num_columns, print_flags);
833 4 shmem_procinfo__print_info(spd->options.shm_key, spd->options.shm_size_multiplier);
834 4 shmem_barrier__print_info(spd->options.shm_key, spd->options.shm_size_multiplier);
835 4 shmem_talp__print_info(spd->options.shm_key, spd->options.shm_size_multiplier);
836
837
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (!spd->dlb_initialized) {
838 options_finalize(&spd->options);
839 }
840
841 4 return DLB_SUCCESS;
842 }
843
844 11 int set_observer_role(bool is_observer) {
845 11 thread_is_observer = is_observer;
846 11 return DLB_SUCCESS;
847 }
848
849 int get_gpu_affinity(char *buffer, size_t buffer_size, bool full_uuid) {
850 int error = DLB_SUCCESS;
851 if (load_plugin("cupti") == DLB_SUCCESS) {
852 plugin_get_gpu_affinity(buffer, buffer_size, full_uuid);
853 unload_plugin("cupti");
854 } else if (load_plugin("rocprofilerv2") == DLB_SUCCESS) {
855 plugin_get_gpu_affinity(buffer, buffer_size, full_uuid);
856 unload_plugin("rocprofilerv2");
857 } else {
858 error = DLB_ERR_UNKNOWN;
859 }
860
861 return error;
862 }
863