GCC Code Coverage Report


Directory: src/
File: src/LB_comm/shmem_talp.c
Date: 2025-11-21 10:34:40
Exec Total Coverage
Lines: 204 231 88.3%
Functions: 22 23 95.7%
Branches: 93 126 73.8%

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 "LB_comm/shmem_talp.h"
21
22 #include "LB_comm/shmem.h"
23 #include "apis/dlb_errors.h"
24 #include "apis/dlb_talp.h"
25 #include "support/atomic.h"
26 #include "support/debug.h"
27 #include "support/types.h"
28 #include "support/mask_utils.h"
29
30 #include <stdlib.h>
31 #include <string.h>
32 #include <pthread.h>
33 #include <inttypes.h>
34
35
36 enum { NOBODY = 0 };
37
38
39 typedef struct DLB_ALIGN_CACHE talp_region_t {
40 char name[DLB_MONITOR_NAME_MAX];
41 atomic_int_least64_t mpi_time;
42 atomic_int_least64_t useful_time;
43 pid_t pid;
44 float avg_cpus;
45 } talp_region_t;
46
47 typedef struct {
48 bool initialized;
49 int max_regions; // capacity
50 int num_regions; // size
51 talp_region_t talp_region[];
52 } shdata_t;
53
54 enum { SHMEM_TALP_VERSION = 4 };
55
56 static shmem_handler_t *shm_handler = NULL;
57 static shdata_t *shdata = NULL;
58 static int max_regions = 0;
59 static const char *shmem_name = "talp";
60 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
61 static int subprocesses_attached = 0;
62
63
64 /*********************************************************************************/
65 /* Init / Finalize */
66 /*********************************************************************************/
67
68 /* This function may be called from shmem_init to cleanup pid */
69 static void cleanup_shmem(void *shdata_ptr, int pid) {
70
71 bool shmem_empty = true;
72 shdata_t *shared_data = shdata_ptr;
73 int num_regions = shared_data->num_regions;
74 for (int region_id = 0; region_id < num_regions; ++region_id) {
75 talp_region_t *talp_region = &shared_data->talp_region[region_id];
76 if (talp_region->pid == pid) {
77 *talp_region = (const talp_region_t){};
78 } else if (talp_region->pid > 0) {
79 shmem_empty = false;
80 }
81 }
82
83 /* If there are no registered regions, make sure shmem is reset */
84 if (shmem_empty) {
85 memset(shared_data, 0, shmem_talp__size());
86 }
87 }
88
89 26 static bool is_shmem_empty(void) {
90 26 int num_regions = shdata->num_regions;
91
2/2
✓ Branch 0 taken 5615 times.
✓ Branch 1 taken 25 times.
5640 for (int region_id = 0; region_id < num_regions; ++region_id) {
92
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5614 times.
5615 if (shdata->talp_region[region_id].pid != NOBODY) {
93 1 return false;
94 }
95 }
96 25 return true;
97 }
98
99 29 static void open_shmem(const char *shmem_key, int shmem_size_multiplier) {
100 29 pthread_mutex_lock(&mutex);
101 {
102
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 3 times.
29 if (shm_handler == NULL) {
103 26 max_regions = mu_get_system_size() * shmem_size_multiplier;
104 52 shm_handler = shmem_init((void**)&shdata,
105 26 &(const shmem_props_t) {
106 26 .size = shmem_talp__size(),
107 .name = shmem_name,
108 .key = shmem_key,
109 .version = SHMEM_TALP_VERSION,
110 .cleanup_fn = cleanup_shmem,
111 });
112 26 subprocesses_attached = 1;
113 } else {
114 3 ++subprocesses_attached;
115 }
116 }
117 29 pthread_mutex_unlock(&mutex);
118 29 }
119
120 29 static void close_shmem(void) {
121 29 pthread_mutex_lock(&mutex);
122 {
123
2/2
✓ Branch 0 taken 26 times.
✓ Branch 1 taken 3 times.
29 if (--subprocesses_attached == 0) {
124 26 shmem_finalize(shm_handler, is_shmem_empty);
125 26 shm_handler = NULL;
126 26 shdata = NULL;
127 }
128 }
129 29 pthread_mutex_unlock(&mutex);
130 29 }
131
132 14 int shmem_talp__init(const char *shmem_key, int shmem_size_multiplier) {
133 14 int error = DLB_SUCCESS;
134
135 // Shared memory creation
136 14 open_shmem(shmem_key, shmem_size_multiplier);
137
138 14 shmem_lock(shm_handler);
139 {
140 // Initialize some values if this is the 1st process attached to the shmem
141
2/2
✓ Branch 0 taken 12 times.
✓ Branch 1 taken 2 times.
14 if (!shdata->initialized) {
142 12 shdata->initialized = true;
143 12 shdata->num_regions = 0;
144 12 shdata->max_regions = max_regions;
145 } else {
146
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
2 if (shdata->max_regions != max_regions) {
147 error = DLB_ERR_INIT;
148 }
149 }
150 }
151 14 shmem_unlock(shm_handler);
152
153
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (error == DLB_ERR_INIT) {
154 warning("Cannot attach to TALP shmem because existing size differ."
155 " Existing shmem size: %d, expected: %d."
156 " Check for DLB_ARGS consistency among processes or clean up shared memory.",
157 shdata->max_regions, max_regions);
158 }
159
160
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14 times.
14 if (error < DLB_SUCCESS) {
161 // The shared memory contents are untouched, but the counter needs to
162 // be decremented, and the shared memory deleted if needed
163 close_shmem();
164 }
165
166 14 return error;
167 }
168
169 15 int shmem_talp_ext__init(const char *shmem_key, int shmem_size_multiplier) {
170 // Shared memory creation
171 15 open_shmem(shmem_key, shmem_size_multiplier);
172
173 // External processes don't need to initialize anything
174
175 15 return DLB_SUCCESS;
176 }
177
178 15 int shmem_talp__finalize(pid_t pid) {
179 15 int error = DLB_SUCCESS;
180
181
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14 times.
15 if (shm_handler == NULL) {
182 1 return DLB_ERR_NOSHMEM;
183 }
184
185 // Remove all regions associated with pid
186 14 shmem_lock(shm_handler);
187 {
188 14 int num_regions = shdata->num_regions;
189
2/2
✓ Branch 0 taken 6414 times.
✓ Branch 1 taken 14 times.
6428 for (int region_id = 0; region_id < num_regions; ++region_id) {
190 6414 talp_region_t *talp_region = &shdata->talp_region[region_id];
191
2/2
✓ Branch 0 taken 5611 times.
✓ Branch 1 taken 803 times.
6414 if (talp_region->pid == pid) {
192 5611 *talp_region = (const talp_region_t){};
193 }
194 }
195 }
196 14 shmem_unlock(shm_handler);
197
198 // Close shared memory
199 14 close_shmem();
200
201 14 return error;
202 }
203
204 15 int shmem_talp_ext__finalize(void) {
205 // Protect double finalization
206
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 15 times.
15 if (shm_handler == NULL) {
207 return DLB_ERR_NOSHMEM;
208 }
209
210 // Shared memory destruction
211 15 close_shmem();
212
213 15 return DLB_SUCCESS;
214 }
215
216
217 /*********************************************************************************/
218 /* Register regions */
219 /*********************************************************************************/
220
221 /* Register monitoring region with name "name", or look up if already registered.
222 * Return associated node-unique id by parameter. */
223 5616 int shmem_talp__register(pid_t pid, float avg_cpus, const char *name, int *node_shared_id) {
224
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5615 times.
5616 if (shm_handler == NULL) return DLB_ERR_NOSHMEM;
225
226 int error;
227 5615 shmem_lock(shm_handler);
228 {
229 /* Regions cannot be removed from shmem_talp.
230 * Search is linear, and append if not found. */
231 int region_id;
232 5615 int num_regions = shdata->num_regions;
233
2/2
✓ Branch 0 taken 4802804 times.
✓ Branch 1 taken 5615 times.
4808419 for (region_id = 0; region_id < num_regions; ++region_id) {
234 4802804 talp_region_t *talp_region = &shdata->talp_region[region_id];
235
2/2
✓ Branch 0 taken 4802002 times.
✓ Branch 1 taken 802 times.
4802804 if (talp_region->pid == pid
236
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4802002 times.
4802002 && strncmp(talp_region->name, name, DLB_MONITOR_NAME_MAX-1) == 0) {
237 /* Region was already registered */
238 break;
239 }
240 }
241
242
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5615 times.
5615 if (region_id < num_regions) {
243 /* found */
244 *node_shared_id = region_id;
245 error = DLB_NOUPDT;
246 } else {
247
2/2
✓ Branch 0 taken 5611 times.
✓ Branch 1 taken 4 times.
5615 if (num_regions < max_regions) {
248 /* Register new region (region_id points to empty spot) */
249 5611 ++shdata->num_regions;
250 5611 talp_region_t *empty_spot = &shdata->talp_region[region_id];
251 5611 *empty_spot = (const talp_region_t) {.pid = pid, .avg_cpus = avg_cpus};
252 5611 snprintf(empty_spot->name, DLB_MONITOR_NAME_MAX, "%s", name);
253 5611 *node_shared_id = region_id;
254 5611 error = DLB_SUCCESS;
255 } else {
256 /* No mem left */
257 4 error = DLB_ERR_NOMEM;
258 }
259 }
260 }
261 5615 shmem_unlock(shm_handler);
262
263 5615 return error;
264 }
265
266 /*********************************************************************************/
267 /* Getters */
268 /*********************************************************************************/
269
270 /* Obtain a list of PIDs that have registered a region */
271 2 int shmem_talp__get_pidlist(pid_t *pidlist, int *nelems, int max_len) {
272
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (shm_handler == NULL) return DLB_ERR_NOSHMEM;
273
274 1 *nelems = 0;
275 1 shmem_lock(shm_handler);
276 {
277 1 int num_regions = shdata->num_regions;
278
3/4
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 3 times.
✗ Branch 3 not taken.
4 for (int region_id = 0; region_id < num_regions && *nelems < max_len; ++region_id) {
279 3 pid_t pid = shdata->talp_region[region_id].pid;
280
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (pid != NOBODY) {
281 // pid is valid, check if already in pidlist
282 int i;
283
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
4 for (i=0; i<(*nelems); ++i) {
284
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (pid == pidlist[i])
285 1 break;
286 }
287 // add if not found
288
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 1 times.
3 if (i == *nelems) {
289 2 pidlist[(*nelems)++] = pid;
290 }
291 }
292 }
293 }
294 1 shmem_unlock(shm_handler);
295 1 return DLB_SUCCESS;
296 }
297
298 4 static int cmp_region_list(const void *elem1, const void *elem2) {
299 4 return ((talp_region_list_t*)elem1)->pid - ((talp_region_list_t*)elem2)->pid;
300 }
301
302 /* Look up for a registered monitoring region with the given "name" and "pid". */
303 5 int shmem_talp__get_region(talp_region_list_t *region, pid_t pid, const char *name) {
304
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 5 times.
5 if (shm_handler == NULL) return DLB_ERR_NOSHMEM;
305
306 5 int error = DLB_ERR_NOPROC;
307 5 shmem_lock(shm_handler);
308 {
309 5 int num_regions = shdata->num_regions;
310
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 2 times.
8 for (int region_id = 0; region_id < num_regions; ++region_id) {
311 6 talp_region_t *talp_region = &shdata->talp_region[region_id];
312
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (talp_region->pid == pid
313
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 && strncmp(talp_region->name, name, DLB_MONITOR_NAME_MAX-1) == 0) {
314 3 *region = (const talp_region_list_t) {
315 .pid = pid,
316 .region_id = region_id,
317 3 .mpi_time = DLB_ATOMIC_LD_RLX(&talp_region->mpi_time),
318 3 .useful_time = DLB_ATOMIC_LD_RLX(&talp_region->useful_time),
319 3 .avg_cpus = talp_region->avg_cpus,
320 };
321 3 error = DLB_SUCCESS;
322 3 break;
323 }
324 }
325 }
326 5 shmem_unlock(shm_handler);
327
328 5 return error;
329 }
330
331 /* Obtain a list of regions for a given name, sorted by PID */
332 13 int shmem_talp__get_regionlist(talp_region_list_t *region_list, int *nelems,
333 int max_len, const char *name) {
334
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 12 times.
13 if (shm_handler == NULL) return DLB_ERR_NOSHMEM;
335
336 12 *nelems = 0;
337 12 shmem_lock(shm_handler);
338 {
339 12 int num_regions = shdata->num_regions;
340
4/4
✓ Branch 0 taken 22 times.
✓ Branch 1 taken 11 times.
✓ Branch 2 taken 21 times.
✓ Branch 3 taken 1 times.
33 for (int region_id = 0; region_id < num_regions && *nelems < max_len; ++region_id) {
341 21 talp_region_t *talp_region = &shdata->talp_region[region_id];
342
1/2
✓ Branch 0 taken 21 times.
✗ Branch 1 not taken.
21 if (talp_region->pid != NOBODY
343
2/2
✓ Branch 0 taken 15 times.
✓ Branch 1 taken 6 times.
21 && strncmp(talp_region->name, name, DLB_MONITOR_NAME_MAX-1) == 0) {
344 15 region_list[(*nelems)++] = (const talp_region_list_t) {
345 15 .pid = talp_region->pid,
346 .region_id = region_id,
347 15 .mpi_time = DLB_ATOMIC_LD_RLX(&talp_region->mpi_time),
348 15 .useful_time = DLB_ATOMIC_LD_RLX(&talp_region->useful_time),
349 15 .avg_cpus = talp_region->avg_cpus,
350 };
351 }
352 }
353 }
354 12 shmem_unlock(shm_handler);
355
356 /* Sort array by PID */
357 12 qsort(region_list, *nelems, sizeof(talp_region_list_t), cmp_region_list);
358
359 12 return DLB_SUCCESS;
360 }
361
362 8 int shmem_talp__get_times(int region_id, int64_t *mpi_time, int64_t *useful_time) {
363
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (unlikely(shm_handler == NULL)) return DLB_ERR_NOSHMEM;
364
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (unlikely(region_id >= max_regions)) return DLB_ERR_NOMEM;
365
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 5 times.
6 if (unlikely(region_id >= shdata->num_regions)) return DLB_ERR_NOENT;
366
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 4 times.
5 if (unlikely(region_id < 0)) return DLB_ERR_NOENT;
367
368 4 talp_region_t *talp_region = &shdata->talp_region[region_id];
369
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
4 if (unlikely(talp_region->pid == NOBODY)) return DLB_ERR_NOENT;
370
371 4 *mpi_time = DLB_ATOMIC_LD_RLX(&talp_region->mpi_time);
372 4 *useful_time = DLB_ATOMIC_LD_RLX(&talp_region->useful_time);
373
374 4 return DLB_SUCCESS;
375 }
376
377
378 /*********************************************************************************/
379 /* Setters */
380 /*********************************************************************************/
381
382 14419 int shmem_talp__set_times(int region_id, int64_t mpi_time, int64_t useful_time) {
383
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 14415 times.
14419 if (unlikely(shm_handler == NULL)) return DLB_ERR_NOSHMEM;
384
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14414 times.
14415 if (unlikely(region_id >= max_regions)) return DLB_ERR_NOMEM;
385
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14413 times.
14414 if (unlikely(region_id >= shdata->num_regions)) return DLB_ERR_NOENT;
386
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 14412 times.
14413 if (unlikely(region_id < 0)) return DLB_ERR_NOENT;
387
388 14412 talp_region_t *talp_region = &shdata->talp_region[region_id];
389
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 14412 times.
14412 if (unlikely(talp_region->pid == NOBODY)) return DLB_ERR_NOENT;
390
391 14412 DLB_ATOMIC_ST_RLX(&talp_region->mpi_time, mpi_time);
392 14412 DLB_ATOMIC_ST_RLX(&talp_region->useful_time, useful_time);
393
394 14412 return DLB_SUCCESS;
395 }
396
397 1 int shmem_talp__set_avg_cpus(int region_id, float avg_cpus) {
398
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (unlikely(shm_handler == NULL)) return DLB_ERR_NOSHMEM;
399 if (unlikely(region_id >= max_regions)) return DLB_ERR_NOMEM;
400 if (unlikely(region_id >= shdata->num_regions)) return DLB_ERR_NOENT;
401 if (unlikely(region_id < 0)) return DLB_ERR_NOENT;
402
403 talp_region_t *talp_region = &shdata->talp_region[region_id];
404 if (unlikely(talp_region->pid == NOBODY)) return DLB_ERR_NOENT;
405
406 talp_region->avg_cpus = avg_cpus;
407
408 return DLB_SUCCESS;
409 }
410
411
412 /*********************************************************************************/
413 /* Misc */
414 /*********************************************************************************/
415
416 7 void shmem_talp__print_info(const char *shmem_key, int shmem_size_multiplier) {
417
418 /* If the shmem is not opened, obtain a temporary fd */
419 7 bool temporary_shmem = shm_handler == NULL;
420
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (temporary_shmem) {
421 6 shmem_talp_ext__init(shmem_key, shmem_size_multiplier);
422 }
423
424 /* Make a full copy of the shared memory */
425 7 shdata_t *shdata_copy = malloc(shmem_talp__size());
426 7 shmem_lock(shm_handler);
427 {
428 7 memcpy(shdata_copy, shdata, shmem_talp__size());
429 }
430 7 shmem_unlock(shm_handler);
431
432 /* Close shmem if needed */
433
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 1 times.
7 if (temporary_shmem) {
434 6 shmem_talp_ext__finalize();
435 }
436
437 /* Find the max number of characters per column */
438 7 pid_t max_pid = 111; /* 3 digits for 'PID' */
439 7 int max_name = 4; /* 'Name' */
440 7 int max_mpi = 8; /* 'MPI time' */
441 7 int max_useful = 11; /* 'Useful time' */
442 7 int num_regions = shdata_copy->num_regions;
443
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 for (int region_id = 0; region_id < num_regions; ++region_id) {
444 3 talp_region_t *talp_region = &shdata_copy->talp_region[region_id];
445
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (talp_region->pid != NOBODY) {
446 int len;
447 /* PID */
448 3 max_pid = max_int(talp_region->pid, max_pid);
449 /* Name */
450 3 len = strlen(talp_region->name);
451 3 max_name = max_int(len, max_name);
452 /* MPI time */
453 3 len = snprintf(NULL, 0, "%"PRId64, talp_region->mpi_time);
454 3 max_mpi = max_int(len, max_mpi);
455 /* Useful time */
456 3 len = snprintf(NULL, 0, "%"PRId64, talp_region->useful_time);
457 3 max_useful = max_int(len, max_useful);
458 }
459 }
460 7 int max_pid_digits = snprintf(NULL, 0, "%d", max_pid);
461
462 /* Initialize buffer */
463 print_buffer_t buffer;
464 7 printbuffer_init(&buffer);
465
466 /* Set up line buffer */
467 enum { MAX_LINE_LEN = 512 };
468 char line[MAX_LINE_LEN];
469
470
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 for (int region_id = 0; region_id < num_regions; ++region_id) {
471 3 talp_region_t *talp_region = &shdata_copy->talp_region[region_id];
472
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (talp_region->pid != NOBODY) {
473
474 /* Append line to buffer */
475 3 snprintf(line, MAX_LINE_LEN,
476 " | %*d | %*s | %*"PRId64" | %*"PRId64" |",
477 max_pid_digits, talp_region->pid,
478 3 max_name, talp_region->name,
479 3 max_mpi, talp_region->mpi_time,
480 3 max_useful, talp_region->useful_time),
481 3 printbuffer_append(&buffer, line);
482 }
483 }
484
485 /* Print if not empty */
486
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 6 times.
7 if (buffer.addr[0] != '\0' ) {
487 /* Construct header */
488 1 snprintf(line, MAX_LINE_LEN,
489 " | %*s | %*s | %*s | %*s |",
490 max_pid_digits, "PID",
491 max_name, "Name",
492 max_mpi, "MPI time",
493 max_useful, "Useful time");
494
495 /* Print header + buffer */
496 1 info0("=== TALP Regions ===\n"
497 "%s\n"
498 "%s", line, buffer.addr);
499 }
500
501 7 printbuffer_destroy(&buffer);
502 7 free(shdata_copy);
503 7 }
504
505 1 bool shmem_talp__exists(void) {
506 1 return shm_handler != NULL;
507 }
508
509 6 bool shmem_talp__initialized(void) {
510
3/4
✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 4 times.
✓ Branch 3 taken 2 times.
6 return shdata && shdata->initialized;
511 }
512
513 1 int shmem_talp__version(void) {
514 1 return SHMEM_TALP_VERSION;
515 }
516
517 41 size_t shmem_talp__size(void) {
518 // max_regions contains a value once shmem is initialized,
519 // otherwise return default size
520 41 return sizeof(shdata_t) + sizeof(talp_region_t) * (
521
2/2
✓ Branch 0 taken 40 times.
✓ Branch 1 taken 1 times.
41 max_regions > 0 ? max_regions : mu_get_system_size());
522 }
523
524 3 int shmem_talp__get_max_regions(void) {
525 3 return max_regions;
526 }
527
528 4803 int shmem_talp__get_num_regions(void) {
529 4803 return shdata->num_regions;
530 }
531