GCC Code Coverage Report


Directory: src/
File: src/LB_comm/shmem_lewi_light.c
Date: 2026-09-15 07:37:49
Exec Total Coverage
Lines: 65 76 85.5%
Functions: 11 12 91.7%
Branches: 31 48 64.6%

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_comm/shmem_lewi_light.h"
21
22 #include "LB_comm/shmem.h"
23 #include "support/tracing.h"
24 #include "support/debug.h"
25 #include "support/types.h"
26
27 #include <stdlib.h>
28
29 static int defaultCPUS;
30 static int greedy;
31
32 struct shdata {
33 int idleCpus;
34 int attached_nprocs;
35 };
36
37 static struct shdata *shdata = NULL;
38 static shmem_handler_t *shm_handler = NULL;
39 static const char *shmem_name = "lewi";
40 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
41 static int subprocesses_attached = 0;
42
43 1 static void cleanup_shmem(void *shdata_ptr, int pid) {
44 1 struct shdata *shared_data = shdata_ptr;
45 1 __sync_fetch_and_sub(&shared_data->attached_nprocs, 1);
46 1 }
47
48 17 static bool is_shmem_empty(void) {
49
2/4
✓ Branch 0 taken 17 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
✗ Branch 3 not taken.
17 return shdata && shdata->attached_nprocs == 0;
50 }
51
52 31 static void open_shmem(const char *shmem_key) {
53 31 pthread_mutex_lock(&mutex);
54 {
55
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
31 if (shm_handler == NULL) {
56 36 shm_handler = shmem_init((void**)&shdata,
57 18 &(const shmem_props_t) {
58 .size = sizeof(struct shdata),
59 .name = shmem_name,
60 .key = shmem_key,
61 .version = SHMEM_VERSION_IGNORE,
62 .cleanup_fn = cleanup_shmem,
63 });
64 18 subprocesses_attached = 1;
65 } else {
66 13 ++subprocesses_attached;
67 }
68 }
69 31 pthread_mutex_unlock(&mutex);
70 31 }
71
72 31 void shmem_lewi_light__init(int def_cpus, int is_greedy, const char *shmem_key) {
73
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 30 times.
31 verbose(VB_SHMEM, "Initializing shmem_lewi_light");
74 31 defaultCPUS = def_cpus;
75 31 greedy = is_greedy;
76
77 // Shared memory creation
78 31 open_shmem(shmem_key);
79
80
2/2
✓ Branch 0 taken 18 times.
✓ Branch 1 taken 13 times.
31 if (__sync_fetch_and_add(&shdata->attached_nprocs, 1) == 0) {
81 // Initialize shared memory if this is the 1st process attached
82
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17 times.
18 verbose(VB_SHMEM, "setting values to the shared mem");
83
84 /* idleCPUS */
85 18 shdata->idleCpus = 0;
86 add_event(IDLE_CPUS_EVENT, 0);
87
88
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 17 times.
18 verbose(VB_SHMEM, "Finished setting values to the shared mem");
89 }
90 31 }
91
92 30 static void close_shmem(void) {
93 30 pthread_mutex_lock(&mutex);
94 {
95
2/2
✓ Branch 0 taken 17 times.
✓ Branch 1 taken 13 times.
30 if (--subprocesses_attached == 0) {
96 17 shmem_finalize(shm_handler, is_shmem_empty);
97 17 shm_handler = NULL;
98 17 shdata = NULL;
99 }
100 }
101 30 pthread_mutex_unlock(&mutex);
102 30 }
103
104 30 void shmem_lewi_light__finalize(void) {
105
1/2
✓ Branch 0 taken 30 times.
✗ Branch 1 not taken.
30 if (shm_handler) {
106 30 __sync_fetch_and_sub(&shdata->attached_nprocs, 1);
107 30 close_shmem();
108 }
109 30 }
110
111 13 int shmem_lewi_light__release_cpus(int cpus) {
112
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
13 verbose(VB_SHMEM, "Releasing CPUS...");
113
114 13 __sync_fetch_and_add (&(shdata->idleCpus), cpus);
115 add_event(IDLE_CPUS_EVENT, shdata->idleCpus);
116
117
2/2
✓ Branch 0 taken 5 times.
✓ Branch 1 taken 8 times.
13 verbose(VB_SHMEM, "DONE Releasing CPUS (idle %d)", shdata->idleCpus);
118
119 13 return 0;
120 }
121
122 12 int shmem_lewi_light__acquire_cpus(int current_cpus) {
123
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 verbose(VB_SHMEM, "Acquiring CPUS...");
124 12 int cpus = defaultCPUS-current_cpus;
125
126 //I don't care if there aren't enough cpus
127
128
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 12 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
12 if((__sync_sub_and_fetch (&(shdata->idleCpus), cpus)>0) && greedy) {
129 cpus+=__sync_val_compare_and_swap(&(shdata->idleCpus), shdata->idleCpus, 0);
130 }
131 add_event(IDLE_CPUS_EVENT, shdata->idleCpus);
132
133
2/2
✓ Branch 0 taken 3 times.
✓ Branch 1 taken 9 times.
12 verbose(VB_SHMEM, "Using %d CPUS... %d Idle", cpus, shdata->idleCpus);
134
135 12 return cpus+current_cpus;
136 }
137
138 2 int shmem_lewi_light__check_idle_cpus(int my_cpus, int max_resources) {
139
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 verbose(VB_SHMEM, "Checking idle CPUS... %d", shdata->idleCpus);
140 int cpus;
141 int aux;
142 //WARNING//
143 //if more CPUS than the availables are used release some
144
1/4
✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
2 if ((shdata->idleCpus < 0) && (my_cpus>defaultCPUS) ) {
145 aux=shdata->idleCpus;
146 cpus=min_int(abs(aux), my_cpus-defaultCPUS);
147 if(__sync_bool_compare_and_swap(&(shdata->idleCpus), aux, aux+cpus)) {
148 my_cpus-=cpus;
149 }
150
151 //if there are idle CPUS use them
152
2/2
✓ Branch 0 taken 1 times.
✓ Branch 1 taken 1 times.
2 } else if( shdata->idleCpus > 0) {
153 1 aux=shdata->idleCpus;
154
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1 times.
1 if(aux>max_resources) { aux=max_resources; }
155
156
1/2
✓ Branch 0 taken 1 times.
✗ Branch 1 not taken.
1 if(__sync_bool_compare_and_swap(&(shdata->idleCpus), shdata->idleCpus, shdata->idleCpus-aux)) {
157 1 my_cpus+=aux;
158 }
159 }
160 add_event(IDLE_CPUS_EVENT, shdata->idleCpus);
161
162
1/2
✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
2 verbose(VB_SHMEM, "Using %d CPUS... %d Idle", my_cpus, shdata->idleCpus);
163 2 return my_cpus;
164 }
165
166 19 void shmem_lewi_light__atfork_prepare(void) {
167 19 pthread_mutex_lock(&mutex);
168 19 }
169
170 19 void shmem_lewi_light__atfork_parent(void) {
171 19 pthread_mutex_unlock(&mutex);
172 19 }
173
174 void shmem_lewi_light__atfork_child(void) {
175
176 pthread_mutex_init(&mutex, NULL);
177
178 if (shm_handler != NULL) {
179 shmem_detach_after_fork(shm_handler);
180 shdata = NULL;
181 shm_handler = NULL;
182 }
183 }
184