GCC Code Coverage Report


Directory: src/
File: src/talp/regions.c
Date: 2026-09-15 07:37:49
Exec Total Coverage
Lines: 216 222 97.3%
Functions: 17 17 100.0%
Branches: 107 128 83.6%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2026 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 "talp/regions.h"
25
26 #include "LB_comm/shmem_talp.h"
27 #include "LB_core/spd.h"
28 #include "LB_core/thread_ctx.h"
29 #include "apis/dlb_errors.h"
30 #include "apis/dlb_talp.h"
31 #include "support/debug.h"
32 #include "support/gtree.h"
33 #include "support/mask_utils.h"
34 #include "support/tracing.h"
35 #include "talp/sample.h"
36 #include "talp/talp.h"
37 #include "talp/talp_output.h"
38 #include "talp/talp_types.h"
39
40 #include <pthread.h>
41 #include <stdio.h>
42 #include <stdlib.h>
43 #include <string.h>
44
45
46 /*********************************************************************************/
47 /* Thread-local Monitoring Regions */
48 /*********************************************************************************/
49
50 typedef struct {
51 dlb_monitor_t *monitor; /* global region record to flush into at close */
52 talp_sample_t snapshot; /* sample at open time; delta = close - snapshot */
53 int cpuid; /* single CPU that participates in this region */
54 } local_region_entry_t;
55
56 __thread GSList *local_regions = NULL;
57
58 1 static int region_start_thread(const subprocess_descriptor_t *spd, dlb_monitor_t *monitor) {
59
60 1 monitor_data_t *monitor_data = monitor->_data;
61
2/4
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 1 times.
1 if (monitor_data->flags.started || !monitor_data->flags.enabled) {
62 return DLB_NOUPDT;
63 }
64
65 1 talp_info_t *talp_info = spd->talp_info;
66
67 /* Update this sample first */
68 1 talp_sample_update(talp_info);
69
70
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 verbose(VB_TALP, "Starting region %s", monitor->name);
71 instrument_event(MONITOR_REGION, monitor_data->id, EVENT_BEGIN);
72
73 1 const talp_sample_t *sample = talp_sample_get(spd->talp_info);
74
75 /* For thread-local regions we can't modify the sample, we just keep a snapshot */
76 1 local_region_entry_t *entry = malloc(sizeof(local_region_entry_t));
77 1 *entry = (local_region_entry_t) {
78 .monitor = monitor,
79 .snapshot = {
80 1 .timers = sample->timers,
81 1 .counters = sample->counters,
82 1 .stats = sample->stats,
83 },
84 1 .cpuid = sched_getcpu(),
85 };
86
87 1 local_regions = g_slist_prepend(local_regions, entry);
88
89 1 return DLB_SUCCESS;
90 }
91
92 1 static int region_stop_thread(const subprocess_descriptor_t *spd, dlb_monitor_t *monitor) {
93
94 1 local_region_entry_t *entry = NULL;
95
96 /* Get region entry if monitor is a special value */
97
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (monitor == DLB_LAST_OPEN_REGION) {
98 if (local_regions != NULL) {
99 entry = local_regions->data;
100 monitor = entry->monitor;
101 } else {
102 return DLB_ERR_NOENT;
103 }
104 }
105
106 /* Get region entry if monitor is an actual pointer */
107 1 for (GSList *node = local_regions;
108
3/4
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✗ Branch 3 not taken.
2 node != NULL && entry == NULL;
109 1 node = node->next) {
110
111 1 local_region_entry_t *e = node->data;
112
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if (e->monitor == monitor) {
113 1 entry = e;
114 }
115 }
116
117
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (entry == NULL) return DLB_NOUPDT;
118
119 1 talp_info_t *talp_info = spd->talp_info;
120
121 /* Update this sample first */
122 1 talp_sample_update(talp_info);
123
124
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 verbose(VB_TALP, "Stopping region %s", monitor->name);
125 instrument_event(MONITOR_REGION, ((monitor_data_t*)monitor->_data)->id, EVENT_END);
126
127 /* Compute delta since this region was started */
128 1 const talp_sample_t *sample = talp_sample_get(talp_info);
129 1 talp_sample_t delta = talp_sample_delta(sample, &entry->snapshot);
130 1 int64_t elapsed = sample->last_updated_ts - entry->snapshot.last_updated_ts;
131
132 /* We don't want the previous CPU mask in the sample because we were not able to
133 * reset it on local region start. Instead, we set the cpuid obtained at that point. */
134 1 CPU_ZERO(&delta.cpu_mask);
135
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 CPU_SET(entry->cpuid, &delta.cpu_mask);
136
137 /* Aggregate delta to region */
138 1 talp_aggregate_sample_to_region(talp_info, monitor, &delta, elapsed);
139
140 1 local_regions = g_slist_remove(local_regions, entry);
141 1 free(entry);
142
143 1 return DLB_SUCCESS;
144 }
145
146
147 /*********************************************************************************/
148 /* TALP Monitoring Regions */
149 /*********************************************************************************/
150
151 const char *global_region_name = DLB_GLOBAL_REGION_NAME;
152
153
154 /* Unique region ids */
155 2280 static int get_new_monitor_id(void) {
156 static atomic_int id = 0;
157 2280 return DLB_ATOMIC_ADD_FETCH_RLX(&id, 1);
158 }
159
160 /* Unique anonymous regions */
161 4 static int get_new_anonymous_id(void) {
162 static atomic_int id = 0;
163 4 return DLB_ATOMIC_ADD_FETCH_RLX(&id, 1);
164 }
165
166 /* Return true if the region is to be enabled.
167 * region_select format:
168 * --talp-region-select=[(include|exclude):]<region-list>
169 */
170 2280 static bool parse_region_select(const char *region_select, const char *region_name) {
171
172 /* Default case, all regions enabled */
173
1/2
✓ Branch 0 taken 2280 times.
✗ Branch 1 not taken.
2280 if (region_select == NULL
174
2/2
✓ Branch 0 taken 2266 times.
✓ Branch 1 taken 14 times.
2280 || region_select[0] == '\0') {
175 2266 return true;
176 }
177
178 /* Select inclusion or exclusion mode,
179 * and advance pointer */
180 14 bool in_inclusion_mode = true;
181
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 10 times.
14 if (strncmp(region_select, "exclude:", strlen("exclude:")) == 0) {
182 4 in_inclusion_mode = false;
183 4 region_select += strlen("exclude:");
184
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 7 times.
10 } else if (strncmp(region_select, "include:", strlen("include:")) == 0) {
185 3 region_select += strlen("include:");
186 }
187
188 /* If "[(include|exclude):]all" */
189
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 11 times.
14 if (strcmp(region_select, "all") == 0) {
190 3 return in_inclusion_mode;
191 }
192
193 /* Break region_select into tokens and find region_name */
194 11 bool found_in_select = false;
195 11 size_t len = strlen(region_select);
196 11 char *region_select_copy = malloc(sizeof(char)*(len+1));
197 11 strcpy(region_select_copy, region_select);
198 11 char *saveptr = NULL;
199 11 char *token = strtok_r(region_select_copy, ",", &saveptr);
200
2/2
✓ Branch 0 taken 16 times.
✓ Branch 1 taken 5 times.
21 while (token) {
201 /* Region name is found */
202
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 11 times.
16 if (strcmp(token, region_name) == 0) {
203 5 found_in_select = true;
204 5 break;
205 }
206
207 /* Region name is same as global region, and same as token (ignoring case) */
208
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 8 times.
11 if (strcasecmp(region_name, global_region_name) == 0
209
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2 times.
3 && strcasecmp(token, global_region_name) == 0) {
210 1 found_in_select = true;
211 1 break;
212 }
213
214 /* next token */
215 10 token = strtok_r(NULL, ",", &saveptr);
216 }
217 11 free(region_select_copy);
218
219
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 return in_inclusion_mode ? found_in_select : !found_in_select;
220 }
221
222 2280 static void region_initialize(dlb_monitor_t *monitor, int id, const
223 char *name, pid_t pid, float avg_cpus, const char *region_select, bool have_shmem) {
224 /* Initialize private monitor data */
225 2280 monitor_data_t *monitor_data = malloc(sizeof(monitor_data_t));
226 2280 *monitor_data = (const monitor_data_t) {
227 .id = id,
228 .node_shared_id = -1,
229 };
230
231 /* Parse --talp-region-select if needed */
232 2280 monitor_data->flags.enabled = parse_region_select(region_select, name);
233
234 /* Allocate monitor name */
235 2280 char *allocated_name = malloc(DLB_MONITOR_NAME_MAX*sizeof(char));
236 2280 snprintf(allocated_name, DLB_MONITOR_NAME_MAX, "%s", name);
237
238 /* Initialize monitor */
239 2280 *monitor = (const dlb_monitor_t) {
240 .name = allocated_name,
241 .avg_cpus = avg_cpus,
242 ._data = monitor_data,
243 };
244
245 /* Register name in the instrumentation tool */
246 instrument_register_event(MONITOR_REGION, monitor_data->id, name);
247
248 /* Register region in shmem */
249
2/2
✓ Branch 0 taken 1232 times.
✓ Branch 1 taken 1048 times.
2280 if (have_shmem) {
250 1232 int err = shmem_talp__register(pid, avg_cpus, monitor->name, &monitor_data->node_shared_id);
251
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 1229 times.
1232 if (err == DLB_ERR_NOMEM) {
252 3 warning("Region %s has been correctly registered but cannot be shared among other"
253 " processes due to lack of space in the TALP shared memory. Features like"
254 " node report or gathering data from external processes may not work for"
255 " this region. If needed, increase the TALP shared memory capacity using"
256 " the flag --shm-size-multiplier. Run dlb -hh for more info.",
257 monitor->name);
258
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1229 times.
1229 } else if (err < DLB_SUCCESS) {
259 fatal("Unknown error registering region %s, please report bug at %s",
260 monitor->name, PACKAGE_BUGREPORT);
261 }
262 }
263 2280 }
264
265 9 struct dlb_monitor_t* region_get_global(const subprocess_descriptor_t *spd) {
266 9 talp_info_t *talp_info = spd->talp_info;
267
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 1 times.
9 return talp_info ? talp_info->monitor : NULL;
268 }
269
270 46 const char* region_get_global_name(void) {
271 46 return global_region_name;
272 }
273
274 /* Helper function for GTree: Compare region names */
275 39434 int region_compare_by_name(const void *a, const void *b) {
276 39434 return strncmp(a, b, DLB_MONITOR_NAME_MAX-1);
277 }
278
279 /* Helper function for GTree: deallocate */
280 2280 void region_dealloc(void *data) {
281
282 2280 dlb_monitor_t *monitor = data;
283
284 /* Free private data */
285 2280 monitor_data_t *monitor_data = monitor->_data;
286 2280 free(monitor_data);
287 2280 monitor_data = NULL;
288
289 /* Free name */
290 2280 free((char*)monitor->name);
291 2280 monitor->name = NULL;
292
293 /* Free monitor */
294 2280 free(monitor);
295 2280 }
296
297 2293 dlb_monitor_t* region_register(const subprocess_descriptor_t *spd, const char* name) {
298
299 /* Forbidden names */
300
2/2
✓ Branch 0 taken 2292 times.
✓ Branch 1 taken 1 times.
2293 if (name == DLB_LAST_OPEN_REGION
301
2/2
✓ Branch 0 taken 2289 times.
✓ Branch 1 taken 3 times.
2292 || (name != NULL
302
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2287 times.
2289 && strncasecmp("all", name, DLB_MONITOR_NAME_MAX-1) == 0)) {
303 3 return NULL;
304 }
305
306 2290 talp_info_t *talp_info = spd->talp_info;
307
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 2289 times.
2290 if (talp_info == NULL) return NULL;
308
309 2289 dlb_monitor_t *monitor = NULL;
310
4/4
✓ Branch 0 taken 2286 times.
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 2285 times.
2289 bool anonymous_region = (name == NULL || *name == '\0');
311
4/4
✓ Branch 0 taken 2285 times.
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 39 times.
✓ Branch 3 taken 2246 times.
2289 bool global_region = !anonymous_region && name == global_region_name;
312
313 /* Check again if the pointers are different but the string content is the
314 * same as the global region, ignoring case */
315
2/2
✓ Branch 0 taken 2285 times.
✓ Branch 1 taken 4 times.
2289 if (!anonymous_region
316
2/2
✓ Branch 0 taken 2246 times.
✓ Branch 1 taken 39 times.
2285 && !global_region
317
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 2241 times.
2246 && strncasecmp(global_region_name, name, DLB_MONITOR_NAME_MAX-1) == 0) {
318 5 name = global_region_name;
319 5 global_region = true;
320 }
321
322 /* Found monitor if already registered */
323
2/2
✓ Branch 0 taken 2285 times.
✓ Branch 1 taken 4 times.
2289 if (!anonymous_region) {
324 2285 pthread_mutex_lock(&talp_info->regions_mutex);
325 {
326 2285 monitor = g_tree_lookup(talp_info->regions, name);
327 }
328 2285 pthread_mutex_unlock(&talp_info->regions_mutex);
329
330
2/2
✓ Branch 0 taken 9 times.
✓ Branch 1 taken 2276 times.
2285 if (monitor != NULL) {
331 9 return monitor;
332 }
333 }
334
335 /* Otherwise, create new monitoring region */
336 2280 monitor = malloc(sizeof(dlb_monitor_t));
337
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2280 times.
2280 fatal_cond(!monitor, "Could not register a new monitoring region."
338 " Please report at "PACKAGE_BUGREPORT);
339
340 /* Determine the initial number of assigned CPUs for the region */
341 2280 float avg_cpus = CPU_COUNT(&spd->process_mask);
342
343 /* Construct name if anonymous region */
344 char monitor_name[DLB_MONITOR_NAME_MAX];
345
2/2
✓ Branch 0 taken 4 times.
✓ Branch 1 taken 2276 times.
2280 if (anonymous_region) {
346 4 snprintf(monitor_name, DLB_MONITOR_NAME_MAX, "Anonymous Region %d",
347 get_new_anonymous_id());
348 4 name = monitor_name;
349 }
350
351 /* Initialize values */
352 4560 bool have_shmem = talp_info->flags.have_shmem
353
3/6
✓ Branch 0 taken 1048 times.
✓ Branch 1 taken 1232 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 1048 times.
✗ Branch 4 not taken.
✗ Branch 5 not taken.
2280 || (talp_info->flags.have_minimal_shmem && global_region);
354 2280 region_initialize(monitor, get_new_monitor_id(), name,
355 2280 spd->id, avg_cpus, spd->options.talp_region_select, have_shmem);
356
357 /* Finally, insert */
358 2280 pthread_mutex_lock(&talp_info->regions_mutex);
359 {
360 2280 g_tree_insert(talp_info->regions, (gpointer)monitor->name, monitor);
361 }
362 2280 pthread_mutex_unlock(&talp_info->regions_mutex);
363
364 2280 return monitor;
365 }
366
367 19 int region_reset(const subprocess_descriptor_t *spd, dlb_monitor_t *monitor) {
368
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
19 if (monitor == DLB_GLOBAL_REGION) {
369 1 talp_info_t *talp_info = spd->talp_info;
370 1 monitor = talp_info->monitor;
371 }
372
373 19 monitor_data_t *monitor_data = monitor->_data;
374
375 /* Close region if started */
376
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 18 times.
19 if (monitor_data->flags.started) {
377
378 1 talp_info_t *talp_info = spd->talp_info;
379
380 1 pthread_mutex_lock(&talp_info->regions_mutex);
381 {
382 1 monitor_data->flags.started = false;
383 1 talp_info->open_regions = g_slist_remove(talp_info->open_regions, monitor);
384 }
385 1 pthread_mutex_unlock(&talp_info->regions_mutex);
386
387
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 verbose(VB_TALP, "Stopping region %s", monitor->name);
388 instrument_event(MONITOR_REGION, monitor_data->id, EVENT_END);
389 }
390
391 /* Reset everything except these fields: */
392 19 *monitor = (const dlb_monitor_t) {
393 19 .name = monitor->name,
394 19 .num_resets = monitor->num_resets + 1,
395 19 ._data = monitor->_data,
396 };
397
398 19 return DLB_SUCCESS;
399 }
400
401 2724 int region_start(const subprocess_descriptor_t *spd, dlb_monitor_t *monitor) {
402
403 /* Observer and unknown threads don't have a valid sample so they cannot start/stop regions */
404
2/2
✓ Branch 1 taken 3 times.
✓ Branch 2 taken 2721 times.
2724 if (unlikely(!thread_is_profiled())) return DLB_ERR_PERM;
405
406 /* Not compatible special value */
407
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 2721 times.
2721 if (unlikely(monitor == DLB_LAST_OPEN_REGION)) return DLB_ERR_NOENT;
408
409 2721 talp_info_t *talp_info = spd->talp_info;
410
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2718 times.
2721 if (monitor == DLB_GLOBAL_REGION) {
411 3 monitor = talp_info->monitor;
412 }
413
414 /* Specific case: thread-local regions if thread is inside a parallel */
415
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2720 times.
2721 if (thread_is_parallel()) {
416 /* Thread-local regions cannot manage global region */
417
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (monitor == talp_info->monitor) return DLB_ERR_PERM;
418
419 1 return region_start_thread(spd, monitor);
420 }
421
422 int error;
423 2720 monitor_data_t *monitor_data = monitor->_data;
424
425
4/4
✓ Branch 0 taken 2703 times.
✓ Branch 1 taken 17 times.
✓ Branch 2 taken 2695 times.
✓ Branch 3 taken 8 times.
2720 if (!monitor_data->flags.started && monitor_data->flags.enabled) {
426
427 /* Update this sample first */
428 2695 talp_sample_update(talp_info);
429
430 /* Gather samples from all threads and update regions */
431 2695 talp_aggregate_samples_to_regions(talp_info);
432
433
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2675 times.
2695 verbose(VB_TALP, "Starting region %s", monitor->name);
434 instrument_event(MONITOR_REGION, monitor_data->id, EVENT_BEGIN);
435
436 /* Thread sample was just updated, use timestamp as starting time */
437 2695 talp_sample_t *thread_sample = talp_sample_get(talp_info);
438 2695 monitor->start_time = thread_sample->last_updated_ts;
439 2695 monitor->stop_time = 0;
440
441 2695 pthread_mutex_lock(&talp_info->regions_mutex);
442 {
443 2695 monitor_data->flags.started = true;
444 2695 talp_info->open_regions = g_slist_prepend(talp_info->open_regions, monitor);
445 }
446 2695 pthread_mutex_unlock(&talp_info->regions_mutex);
447
448 2695 error = DLB_SUCCESS;
449 } else {
450 25 error = DLB_NOUPDT;
451 }
452
453 2720 return error;
454 }
455
456 2836 int region_stop(const subprocess_descriptor_t *spd, dlb_monitor_t *monitor) {
457
458 /* Observer and unknown threads don't have a valid sample so they cannot start/stop regions */
459
2/2
✓ Branch 1 taken 4 times.
✓ Branch 2 taken 2832 times.
2836 if (unlikely(!thread_is_profiled())) return DLB_ERR_PERM;
460
461 2832 talp_info_t *talp_info = spd->talp_info;
462
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 2829 times.
2832 if (monitor == DLB_GLOBAL_REGION) {
463 3 monitor = talp_info->monitor;
464 }
465
466 /* Specific case: thread-local regions if thread is inside a parallel */
467
2/2
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 2831 times.
2832 if (thread_is_parallel()) {
468 /* Thread-local regions cannot manage global region */
469
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (monitor == talp_info->monitor) return DLB_ERR_PERM;
470
471 1 return region_stop_thread(spd, monitor);
472 }
473
474
2/2
✓ Branch 0 taken 106 times.
✓ Branch 1 taken 2725 times.
2831 if (monitor == DLB_LAST_OPEN_REGION) {
475
2/2
✓ Branch 0 taken 105 times.
✓ Branch 1 taken 1 times.
106 if (talp_info->open_regions != NULL) {
476 105 monitor = talp_info->open_regions->data;
477 } else {
478 1 return DLB_ERR_NOENT;
479 }
480 }
481
482 int error;
483 2830 monitor_data_t *monitor_data = monitor->_data;
484
485
2/2
✓ Branch 0 taken 2694 times.
✓ Branch 1 taken 136 times.
2830 if (monitor_data->flags.started) {
486
487 /* Update this sample first */
488 2694 talp_sample_update(talp_info);
489
490 /* Gather samples from all threads and update regions */
491 2694 talp_aggregate_samples_to_regions(talp_info);
492
493 /* Stop timer */
494 2694 talp_sample_t *thread_sample = talp_sample_get(talp_info);
495 2694 monitor->stop_time = thread_sample->last_updated_ts;
496 2694 monitor->elapsed_time += monitor->stop_time - monitor->start_time;
497 2694 ++(monitor->num_measurements);
498
499 2694 pthread_mutex_lock(&talp_info->regions_mutex);
500 {
501 2694 monitor_data->flags.started = false;
502 2694 talp_info->open_regions = g_slist_remove(talp_info->open_regions, monitor);
503 }
504 2694 pthread_mutex_unlock(&talp_info->regions_mutex);
505
506
2/2
✓ Branch 0 taken 20 times.
✓ Branch 1 taken 2674 times.
2694 verbose(VB_TALP, "Stopping region %s", monitor->name);
507 instrument_event(MONITOR_REGION, monitor_data->id, EVENT_END);
508 2694 error = DLB_SUCCESS;
509 } else {
510 136 error = DLB_NOUPDT;
511 }
512
513 2830 return error;
514 }
515
516 14 bool region_is_started(const dlb_monitor_t *monitor) {
517 14 return ((monitor_data_t*)monitor->_data)->flags.started;
518 }
519
520 10 void region_set_internal(struct dlb_monitor_t *monitor, bool internal) {
521 10 ((monitor_data_t*)monitor->_data)->flags.internal = internal;
522 10 }
523
524 8 int region_report(const subprocess_descriptor_t *spd, const dlb_monitor_t *monitor) {
525 8 talp_info_t *talp_info = spd->talp_info;
526
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (monitor == DLB_GLOBAL_REGION) {
527 1 monitor = talp_info->monitor;
528 }
529
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 7 times.
8 if (((monitor_data_t*)monitor->_data)->flags.internal) {
530 1 return DLB_NOUPDT;
531 }
532
533 7 talp_output_print_monitoring_region(monitor, talp_info->flags);
534
535 7 return DLB_SUCCESS;
536 }
537