GCC Code Coverage Report


Directory: src/
File: src/LB_core/spd.c
Date: 2024-11-22 17:07:10
Exec Total Coverage
Lines: 49 49 100.0%
Functions: 9 9 100.0%
Branches: 6 6 100.0%

Line Branch Exec Source
1 /*********************************************************************************/
2 /* Copyright 2009-2021 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_core/spd.h"
21
22 #include "support/debug.h"
23 #include "support/gtree.h"
24
25 #include <stdlib.h>
26 #include <string.h>
27 #include <pthread.h>
28
29 /* TLS global variable to store the spd pointer */
30 __thread subprocess_descriptor_t *thread_spd = NULL;
31
32 /* Global subprocess descriptor */
33 static subprocess_descriptor_t global_spd = { 0 };
34
35 /* GTree containing each subprocess descriptor */
36 typedef struct SPDInfo {
37 const subprocess_descriptor_t *spd;
38 pthread_t pthread;
39 } spd_info_t;
40 static GTree *spd_tree = NULL;
41 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
42
43
44 /*********************************************************************************/
45 /* TLS global variable */
46 /*********************************************************************************/
47 1163 void spd_enter_dlb(subprocess_descriptor_t *spd) {
48
2/2
✓ Branch 0 taken 1129 times.
✓ Branch 1 taken 34 times.
1163 thread_spd = spd ? spd : &global_spd;
49 1163 }
50
51 /*********************************************************************************/
52 /* GTree modification functions */
53 /*********************************************************************************/
54 82 static gint key_compare_func(gconstpointer a, gconstpointer b) {
55
2/2
✓ Branch 0 taken 56 times.
✓ Branch 1 taken 26 times.
82 return (uintptr_t)a < (uintptr_t)b ? -1 : (uintptr_t)a > (uintptr_t)b;
56 }
57
58 28 void spd_register(subprocess_descriptor_t *spd) {
59 28 spd_info_t *spd_info = malloc(sizeof(spd_info_t));
60 28 spd_info->spd = spd;
61 28 spd_info->pthread = 0;
62
63 28 pthread_mutex_lock(&mutex);
64 {
65
2/2
✓ Branch 0 taken 6 times.
✓ Branch 1 taken 22 times.
28 if (spd_tree == NULL) {
66 6 spd_tree = g_tree_new_full(
67 (GCompareDataFunc)key_compare_func,
68 NULL, NULL, free);
69 }
70 28 g_tree_insert(spd_tree, spd, spd_info);
71 }
72 28 pthread_mutex_unlock(&mutex);
73 28 }
74
75 28 void spd_unregister(const subprocess_descriptor_t *spd) {
76 28 pthread_mutex_lock(&mutex);
77 {
78 28 g_tree_remove(spd_tree, spd);
79 }
80 28 pthread_mutex_unlock(&mutex);
81 28 }
82
83 __attribute__((destructor))
84 78 static void spd_tree_dtor(void) {
85 78 g_tree_destroy(spd_tree);
86 78 }
87
88 /*********************************************************************************/
89 /* Setter and getter of the assigned pthread per spd */
90 /*********************************************************************************/
91 2 void spd_set_pthread(const subprocess_descriptor_t *spd, pthread_t pthread) {
92 2 pthread_mutex_lock(&mutex);
93 {
94 2 spd_info_t *spd_info = g_tree_lookup(spd_tree, spd);
95 2 spd_info->pthread = pthread;
96 }
97 2 pthread_mutex_unlock(&mutex);
98 2 }
99
100 3 pthread_t spd_get_pthread(const subprocess_descriptor_t *spd) {
101 pthread_t pthread;
102 3 pthread_mutex_lock(&mutex);
103 {
104 3 spd_info_t *spd_info = g_tree_lookup(spd_tree, spd);
105 3 pthread = spd_info->pthread;
106 }
107 3 pthread_mutex_unlock(&mutex);
108 3 return pthread;
109 }
110
111 /*********************************************************************************/
112 /* Obtain a list of pointers (NULL terminated) of spds */
113 /*********************************************************************************/
114 2 static gint tree_to_list(gpointer key, gpointer value, gpointer data) {
115 2 subprocess_descriptor_t *spd = key;
116 2 subprocess_descriptor_t ***list_p = data;
117 2 **list_p = spd;
118 2 ++(*list_p);
119
120 /* return false to not stop traversing */
121 2 return false;
122 }
123
124 3 const subprocess_descriptor_t** spd_get_spds(void) {
125 const subprocess_descriptor_t **spds;
126 3 pthread_mutex_lock(&mutex);
127 {
128 3 spds = malloc(sizeof(subprocess_descriptor_t *) * (g_tree_nnodes(spd_tree)+1));
129 3 const subprocess_descriptor_t **p = spds;
130 3 g_tree_foreach(spd_tree, tree_to_list, &p);
131 3 *p = NULL;
132 }
133 3 pthread_mutex_unlock(&mutex);
134
135 3 return spds;
136 }
137