GCC Code Coverage Report


Directory: src/
File: src/LB_numThreads/numThreads.c
Date: 2024-11-22 17:07:10
Exec Total Coverage
Lines: 158 173 91.3%
Functions: 14 15 93.3%
Branches: 58 70 82.9%

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_numThreads/numThreads.h"
21
22 #include "LB_core/spd.h"
23 #include "apis/dlb_errors.h"
24 #include "support/tracing.h"
25 #include "support/debug.h"
26 #include "support/mask_utils.h"
27
28 #include <sched.h>
29 #include <pthread.h>
30
31 #define OMP_SYMBOLS_DEFINED ( \
32 omp_set_num_threads \
33 )
34
35 /* Weak symbols */
36 void omp_set_num_threads(int nthreads) __attribute__((weak));
37 int omp_get_max_threads(void) __attribute__((weak));
38
39 static void packed_omp_set_num_threads(int nthreads, void *arg) {
40 omp_set_num_threads(nthreads);
41 }
42
43
44 89 void pm_init(pm_interface_t *pm) {
45
46 89 *pm = (const pm_interface_t) {};
47
48 /* OpenMP */
49
2/2
✓ Branch 0 taken 2 times.
✓ Branch 1 taken 87 times.
89 if (OMP_SYMBOLS_DEFINED) {
50 2 pm->dlb_callback_set_num_threads_ptr = packed_omp_set_num_threads;
51 }
52 /* Undefined */
53 else {}
54 89 }
55
56 79 void pm_finalize(pm_interface_t *pm) {
57 /* Reset all fields */
58 79 *pm = (const pm_interface_t) {};
59 79 }
60
61 27 int pm_get_num_threads(void) {
62
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 27 times.
27 return omp_get_max_threads ? omp_get_max_threads() : 1;
63 }
64
65 115 int pm_callback_set(pm_interface_t *pm, dlb_callbacks_t which,
66 dlb_callback_t callback, void *arg) {
67
10/10
✓ Branch 0 taken 38 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 11 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 30 times.
✓ Branch 6 taken 26 times.
✓ Branch 7 taken 3 times.
✓ Branch 8 taken 3 times.
✓ Branch 9 taken 1 times.
115 switch(which) {
68 38 case dlb_callback_set_num_threads:
69 38 pm->dlb_callback_set_num_threads_ptr = (dlb_callback_set_num_threads_t)callback;
70 38 pm->dlb_callback_set_num_threads_arg = arg;
71 38 break;
72 1 case dlb_callback_set_active_mask:
73 1 pm->dlb_callback_set_active_mask_ptr = (dlb_callback_set_active_mask_t)callback;
74 1 pm->dlb_callback_set_active_mask_arg = arg;
75 1 break;
76 11 case dlb_callback_set_process_mask:
77 11 pm->dlb_callback_set_process_mask_ptr = (dlb_callback_set_process_mask_t)callback;
78 11 pm->dlb_callback_set_process_mask_arg = arg;
79 11 break;
80 1 case dlb_callback_add_active_mask:
81 1 pm->dlb_callback_add_active_mask_ptr = (dlb_callback_add_active_mask_t)callback;
82 1 pm->dlb_callback_add_active_mask_arg = arg;
83 1 break;
84 1 case dlb_callback_add_process_mask:
85 1 pm->dlb_callback_add_process_mask_ptr = (dlb_callback_add_process_mask_t)callback;
86 1 pm->dlb_callback_add_process_mask_arg = arg;
87 1 break;
88 30 case dlb_callback_enable_cpu:
89 30 pm->dlb_callback_enable_cpu_ptr = (dlb_callback_enable_cpu_t)callback;
90 30 pm->dlb_callback_enable_cpu_arg = arg;
91 30 break;
92 26 case dlb_callback_disable_cpu:
93 26 pm->dlb_callback_disable_cpu_ptr = (dlb_callback_disable_cpu_t)callback;
94 26 pm->dlb_callback_disable_cpu_arg = arg;
95 26 break;
96 3 case dlb_callback_enable_cpu_set:
97 3 pm->dlb_callback_enable_cpu_set_ptr = (dlb_callback_enable_cpu_set_t)callback;
98 3 pm->dlb_callback_enable_cpu_set_arg = arg;
99 3 break;
100 3 case dlb_callback_disable_cpu_set:
101 3 pm->dlb_callback_disable_cpu_set_ptr = (dlb_callback_disable_cpu_set_t)callback;
102 3 pm->dlb_callback_disable_cpu_set_arg = arg;
103 3 break;
104 1 default:
105 1 return DLB_ERR_NOCBK;
106 }
107 114 return DLB_SUCCESS;
108 }
109
110 12 int pm_callback_get(const pm_interface_t *pm, dlb_callbacks_t which,
111 dlb_callback_t *callback, void **arg) {
112
10/10
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 1 times.
✓ Branch 4 taken 1 times.
✓ Branch 5 taken 3 times.
✓ Branch 6 taken 1 times.
✓ Branch 7 taken 1 times.
✓ Branch 8 taken 1 times.
✓ Branch 9 taken 1 times.
12 switch(which) {
113 1 case dlb_callback_set_num_threads:
114 1 *callback = (dlb_callback_t)pm->dlb_callback_set_num_threads_ptr;
115 1 *arg = pm->dlb_callback_set_num_threads_arg;
116 1 break;
117 1 case dlb_callback_set_active_mask:
118 1 *callback = (dlb_callback_t)pm->dlb_callback_set_active_mask_ptr;
119 1 *arg = pm->dlb_callback_set_active_mask_arg;
120 1 break;
121 1 case dlb_callback_set_process_mask:
122 1 *callback = (dlb_callback_t)pm->dlb_callback_set_process_mask_ptr;
123 1 *arg = pm->dlb_callback_set_process_mask_arg;
124 1 break;
125 1 case dlb_callback_add_active_mask:
126 1 *callback = (dlb_callback_t)pm->dlb_callback_add_active_mask_ptr;
127 1 *arg = pm->dlb_callback_add_active_mask_arg;
128 1 break;
129 1 case dlb_callback_add_process_mask:
130 1 *callback = (dlb_callback_t)pm->dlb_callback_add_process_mask_ptr;
131 1 *arg = pm->dlb_callback_add_process_mask_arg;
132 1 break;
133 3 case dlb_callback_enable_cpu:
134 3 *callback = (dlb_callback_t)pm->dlb_callback_enable_cpu_ptr;
135 3 *arg = pm->dlb_callback_enable_cpu_arg;
136 3 break;
137 1 case dlb_callback_disable_cpu:
138 1 *callback = (dlb_callback_t)pm->dlb_callback_disable_cpu_ptr;
139 1 *arg = pm->dlb_callback_disable_cpu_arg;
140 1 break;
141 1 case dlb_callback_enable_cpu_set:
142 1 *callback = (dlb_callback_t)pm->dlb_callback_enable_cpu_set_ptr;
143 1 *arg = pm->dlb_callback_enable_cpu_set_arg;
144 1 break;
145 1 case dlb_callback_disable_cpu_set:
146 1 *callback = (dlb_callback_t)pm->dlb_callback_disable_cpu_set_ptr;
147 1 *arg = pm->dlb_callback_disable_cpu_set_arg;
148 1 break;
149 1 default:
150 1 return DLB_ERR_NOCBK;
151 }
152 11 return DLB_SUCCESS;
153 }
154
155 154 int update_threads(const pm_interface_t *pm, int threads) {
156
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 143 times.
154 if (pm->dlb_callback_set_num_threads_ptr == NULL) {
157 11 return DLB_ERR_NOCBK;
158 }
159
160 143 int cpus_node = mu_get_system_size();
161
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 142 times.
143 if (threads > cpus_node) {
162 1 warning("Trying to use more CPUS (%d) than available (%d)", threads, cpus_node);
163 1 threads = cpus_node;
164
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 117 times.
142 } else if (threads < 1) {
165 25 threads = 1;
166 }
167
168 add_event(THREADS_USED_EVENT, threads);
169
170 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
171 143 pm->dlb_callback_set_num_threads_ptr(threads, pm->dlb_callback_set_num_threads_arg);
172 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
173 143 return DLB_SUCCESS;
174 }
175
176 2 int set_mask(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
177
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (pm->dlb_callback_set_active_mask_ptr == NULL) {
178 1 return DLB_ERR_NOCBK;
179 }
180 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
181 1 pm->dlb_callback_set_active_mask_ptr(cpu_set, pm->dlb_callback_set_active_mask_arg);
182 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
183 1 return DLB_SUCCESS;
184 }
185
186 13 int set_process_mask(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
187
2/2
✓ Branch 0 taken 11 times.
✓ Branch 1 taken 2 times.
13 if (pm->dlb_callback_set_process_mask_ptr == NULL) {
188 11 return DLB_ERR_NOCBK;
189 }
190 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
191 2 pm->dlb_callback_set_process_mask_ptr(cpu_set, pm->dlb_callback_set_process_mask_arg);
192 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
193 2 return DLB_SUCCESS;
194 }
195
196 2 int add_mask(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
197
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (pm->dlb_callback_add_active_mask_ptr == NULL) {
198
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if (pm->dlb_callback_enable_cpu_ptr != NULL) {
199 /* fallback to enable_cpu */
200 for (int cpuid = mu_get_first_cpu(cpu_set);
201 cpuid >= 0;
202 cpuid = mu_get_next_cpu(cpu_set, cpuid)) {
203 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
204 pm->dlb_callback_enable_cpu_ptr(cpuid, pm->dlb_callback_enable_cpu_arg);
205 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
206 }
207 return DLB_SUCCESS;
208 }
209 1 return DLB_ERR_NOCBK;
210 }
211 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
212 1 pm->dlb_callback_add_active_mask_ptr(cpu_set, pm->dlb_callback_add_active_mask_arg);
213 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
214 1 return DLB_SUCCESS;
215 }
216
217 2 int add_process_mask(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
218
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 if (pm->dlb_callback_add_process_mask_ptr == NULL) {
219 1 return DLB_ERR_NOCBK;
220 }
221 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
222 1 pm->dlb_callback_add_process_mask_ptr(cpu_set, pm->dlb_callback_add_process_mask_arg);
223 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
224 1 return DLB_SUCCESS;
225 }
226
227 159 int enable_cpu(const pm_interface_t *pm, int cpuid) {
228 /* fallback case */
229
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 156 times.
159 if (pm->dlb_callback_enable_cpu_ptr == NULL
230
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 3 times.
3 && pm->dlb_callback_add_active_mask_ptr) {
231 cpu_set_t cpu_set;
232 CPU_ZERO(&cpu_set);
233 CPU_SET(cpuid, &cpu_set);
234 return enable_cpu_set(pm, &cpu_set);
235 }
236
237
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 156 times.
159 if (pm->dlb_callback_enable_cpu_ptr == NULL) {
238 3 return DLB_ERR_NOCBK;
239 }
240 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
241 156 pm->dlb_callback_enable_cpu_ptr(cpuid, pm->dlb_callback_enable_cpu_arg);
242 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
243 156 return DLB_SUCCESS;
244 }
245
246 29 int enable_cpu_set(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
247
2/2
✓ Branch 0 taken 25 times.
✓ Branch 1 taken 4 times.
29 if (pm->dlb_callback_enable_cpu_set_ptr == NULL) {
248
1/2
✓ Branch 0 taken 25 times.
✗ Branch 1 not taken.
25 if (pm->dlb_callback_enable_cpu_ptr != NULL) {
249 /* fallback to enable_cpu */
250 25 for (int cpuid = mu_get_first_cpu(cpu_set);
251
2/2
✓ Branch 0 taken 61 times.
✓ Branch 1 taken 25 times.
86 cpuid >= 0;
252 61 cpuid = mu_get_next_cpu(cpu_set, cpuid)) {
253 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
254 61 pm->dlb_callback_enable_cpu_ptr(cpuid, pm->dlb_callback_enable_cpu_arg);
255 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
256 }
257 25 return DLB_SUCCESS;
258 }
259 return DLB_ERR_NOCBK;
260 }
261 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
262 4 pm->dlb_callback_enable_cpu_set_ptr(cpu_set, pm->dlb_callback_enable_cpu_set_arg);
263 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
264 4 return DLB_SUCCESS;
265 }
266
267 21 int disable_cpu(const pm_interface_t *pm, int cpuid) {
268 /* fallback case */
269
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if (pm->dlb_callback_disable_cpu_ptr == NULL
270
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 && pm->dlb_callback_set_active_mask_ptr) {
271 cpu_set_t cpu_set;
272 sched_getaffinity(0, sizeof(cpu_set_t), &cpu_set);
273 CPU_CLR(cpuid, &cpu_set);
274 return set_mask(pm, &cpu_set);
275 }
276
277
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 20 times.
21 if (pm->dlb_callback_disable_cpu_ptr == NULL) {
278 1 return DLB_ERR_NOCBK;
279 }
280 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
281 20 pm->dlb_callback_disable_cpu_ptr(cpuid, pm->dlb_callback_disable_cpu_arg);
282 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
283 20 return DLB_SUCCESS;
284 }
285
286 6 int disable_cpu_set(const pm_interface_t *pm, const cpu_set_t *cpu_set) {
287
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 3 times.
6 if (pm->dlb_callback_disable_cpu_set_ptr == NULL) {
288
1/2
✓ Branch 0 taken 3 times.
✗ Branch 1 not taken.
3 if (pm->dlb_callback_disable_cpu_ptr != NULL) {
289 /* fallback to disable_cpu */
290 3 for (int cpuid = mu_get_first_cpu(cpu_set);
291
2/2
✓ Branch 0 taken 8 times.
✓ Branch 1 taken 3 times.
11 cpuid >= 0;
292 8 cpuid = mu_get_next_cpu(cpu_set, cpuid)) {
293 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
294 8 pm->dlb_callback_disable_cpu_ptr(cpuid, pm->dlb_callback_disable_cpu_arg);
295 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
296 }
297 3 return DLB_SUCCESS;
298 }
299 return DLB_ERR_NOCBK;
300 }
301 instrument_event(CALLBACK_EVENT, 1, EVENT_BEGIN);
302 3 pm->dlb_callback_disable_cpu_set_ptr(cpu_set, pm->dlb_callback_disable_cpu_set_arg);
303 instrument_event(CALLBACK_EVENT, 0, EVENT_END);
304 3 return DLB_SUCCESS;
305 }
306