clang -cc1 -cc1 -triple x86_64-pc-linux-gnu -analyze -disable-free -clear-ast-before-backend -disable-llvm-verifier -discard-value-names -main-file-name switch.c -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -fmath-errno -ffp-contract=on -fno-rounding-math -mconstructor-aliases -funwind-tables=2 -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fdebug-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -fcoverage-compilation-dir=/var/lib/jenkins/workspace/nss-scan-build/nspr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests -resource-dir /usr/lib/llvm-18/lib/clang/18 -U NDEBUG -D DEBUG_jenkins -D PACKAGE_NAME="" -D PACKAGE_TARNAME="" -D PACKAGE_VERSION="" -D PACKAGE_STRING="" -D PACKAGE_BUGREPORT="" -D PACKAGE_URL="" -D DEBUG=1 -D HAVE_VISIBILITY_HIDDEN_ATTRIBUTE=1 -D HAVE_VISIBILITY_PRAGMA=1 -D XP_UNIX=1 -D _GNU_SOURCE=1 -D HAVE_FCNTL_FILE_LOCKING=1 -D HAVE_POINTER_LOCALTIME_R=1 -D LINUX=1 -D HAVE_DLADDR=1 -D HAVE_GETTID=1 -D HAVE_LCHOWN=1 -D HAVE_SETPRIORITY=1 -D HAVE_STRERROR=1 -D HAVE_SYSCALL=1 -D HAVE_SECURE_GETENV=1 -D _REENTRANT=1 -D FORCE_PR_LOG -D _PR_PTHREADS -U HAVE_CVAR_BUILT_ON_SEM -I /var/lib/jenkins/workspace/nss-scan-build/nss/../dist/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/include -I ../../../pr/include -I ../../../pr/include/private -internal-isystem /usr/lib/llvm-18/lib/clang/18/include -internal-isystem /usr/local/include -internal-isystem /usr/lib/gcc/x86_64-linux-gnu/14/../../../../x86_64-linux-gnu/include -internal-externc-isystem /usr/include/x86_64-linux-gnu -internal-externc-isystem /include -internal-externc-isystem /usr/include -ferror-limit 19 -fvisibility=hidden -fgnuc-version=4.2.1 -fno-inline -analyzer-output=html -analyzer-config stable-report-filename=true -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /tmp/scan-build-2024-05-18-082241-28900-1 -x c ../../../pr/tests/switch.c
1 | |
2 | |
3 | |
4 | |
5 | |
6 | |
7 | |
8 | |
9 | |
10 | |
11 | #include "prinit.h" |
12 | #include "prcvar.h" |
13 | #include "prmem.h" |
14 | #include "prinrval.h" |
15 | #include "prlock.h" |
16 | #include "prlog.h" |
17 | #include "prthread.h" |
18 | #include "prprf.h" |
19 | |
20 | #include "plerror.h" |
21 | #include "plgetopt.h" |
22 | |
23 | #include "private/pprio.h" |
24 | |
25 | #include <stdlib.h> |
26 | |
27 | #define INNER_LOOPS 100 |
28 | #define DEFAULT_LOOPS 100 |
29 | #define DEFAULT_THREADS 10 |
30 | |
31 | static PRFileDesc *debug_out = NULL; |
32 | static PRBool debug_mode = PR_FALSE, verbosity = PR_FALSE, failed = PR_FALSE; |
33 | |
34 | typedef struct Shared |
35 | { |
36 | PRLock *ml; |
37 | PRCondVar *cv; |
38 | PRBool twiddle; |
39 | PRThread *thread; |
40 | struct Shared *next; |
41 | } Shared; |
42 | |
43 | static void Help(void) |
44 | { |
45 | debug_out = PR_STDOUT; |
46 | |
47 | PR_fprintf( |
48 | debug_out, "Usage: >./switch [-c n] [-t n] [-d] [-v] [-G] [-C n]\n"); |
49 | PR_fprintf( |
50 | debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS); |
51 | PR_fprintf( |
52 | debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS); |
53 | PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n"); |
54 | PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n"); |
55 | PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n"); |
56 | PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n"); |
57 | } |
58 | |
59 | static void PR_CALLBACK Notified(void *arg) |
60 | { |
61 | Shared *shared = (Shared*)arg; |
62 | PRStatus status = PR_SUCCESS; |
63 | while (PR_SUCCESS == status) |
64 | { |
65 | PR_Lock(shared->ml); |
66 | while (shared->twiddle && (PR_SUCCESS == status)) { |
67 | status = PR_WaitCondVar(shared->cv, PR_INTERVAL_NO_TIMEOUT); |
68 | } |
69 | if (verbosity) { |
70 | PR_fprintf(debug_out, "+"); |
71 | } |
72 | shared->twiddle = PR_TRUE; |
73 | shared->next->twiddle = PR_FALSE; |
74 | PR_NotifyCondVar(shared->next->cv); |
75 | PR_Unlock(shared->ml); |
76 | } |
77 | } |
78 | |
79 | static Shared home; |
80 | PRIntn PR_CALLBACK Switch(PRIntn argc, char **argv) |
81 | { |
82 | PLOptStatus os; |
83 | PRStatus status; |
84 | PRBool help = PR_FALSE; |
85 | PRUintn concurrency = 1; |
86 | Shared *shared, *link; |
| 1 | 'shared' declared without an initial value | |
|
87 | PRIntervalTime timein, timeout; |
88 | PRThreadScope thread_scope = PR_LOCAL_THREAD; |
89 | PRUintn thread_count, inner_count, loop_count, average; |
90 | PRUintn thread_limit = DEFAULT_THREADS, loop_limit = DEFAULT_LOOPS; |
91 | PLOptState *opt = PL_CreateOptState(argc, argv, "hdvc:t:C:G"); |
92 | while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) |
| 2 | | Assuming the condition is true | |
|
| 3 | | Loop condition is true. Entering loop body | |
|
| 7 | | Execution continues on line 92 | |
|
| 8 | | Assuming the condition is true | |
|
| 9 | | Loop condition is true. Entering loop body | |
|
| 13 | | Execution continues on line 92 | |
|
| 14 | | Assuming the condition is false | |
|
| 15 | | Loop condition is false. Execution continues on line 124 | |
|
93 | { |
94 | if (PL_OPT_BAD == os) { |
| 4 | | Assuming 'os' is not equal to PL_OPT_BAD | |
|
| |
| 10 | | Assuming 'os' is not equal to PL_OPT_BAD | |
|
| |
95 | continue; |
96 | } |
97 | switch (opt->option) |
| 6 | | Control jumps to 'case 116:' at line 107 | |
|
| 12 | | Control jumps to 'case 99:' at line 104 | |
|
98 | { |
99 | case 'v': |
100 | verbosity = PR_TRUE; |
101 | case 'd': |
102 | debug_mode = PR_TRUE; |
103 | break; |
104 | case 'c': |
105 | loop_limit = atoi(opt->value); |
106 | break; |
107 | case 't': |
108 | thread_limit = atoi(opt->value); |
109 | break; |
110 | case 'C': |
111 | concurrency = atoi(opt->value); |
112 | break; |
113 | case 'G': |
114 | thread_scope = PR_GLOBAL_THREAD; |
115 | break; |
116 | case 'h': |
117 | Help(); |
118 | help = PR_TRUE; |
119 | break; |
120 | default: |
121 | break; |
122 | } |
123 | } |
124 | PL_DestroyOptState(opt); |
125 | |
126 | if (help) { |
| |
127 | return -1; |
128 | } |
129 | |
130 | if (PR_TRUE == debug_mode) |
| 17 | | Assuming 'debug_mode' is not equal to PR_TRUE | |
|
| |
131 | { |
132 | debug_out = PR_STDOUT; |
133 | PR_fprintf(debug_out, "Test parameters\n"); |
134 | PR_fprintf(debug_out, "\tThreads involved: %d\n", thread_limit); |
135 | PR_fprintf(debug_out, "\tIteration limit: %d\n", loop_limit); |
136 | PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency); |
137 | PR_fprintf( |
138 | debug_out, "\tThread type: %s\n", |
139 | (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL"); |
140 | } |
141 | |
142 | PR_SetConcurrency(concurrency); |
143 | |
144 | link = &home; |
145 | home.ml = PR_NewLock(); |
146 | home.cv = PR_NewCondVar(home.ml); |
147 | home.twiddle = PR_FALSE; |
148 | home.next = NULL; |
149 | |
150 | timeout = 0; |
151 | |
152 | for (thread_count = 1; thread_count <= thread_limit; ++thread_count) |
| 19 | | Assuming 'thread_count' is > 'thread_limit' | |
|
| 20 | | Loop condition is false. Execution continues on line 172 | |
|
153 | { |
154 | shared = PR_NEWZAP(Shared); |
155 | |
156 | shared->ml = home.ml; |
157 | shared->cv = PR_NewCondVar(home.ml); |
158 | shared->twiddle = PR_TRUE; |
159 | shared->next = link; |
160 | link = shared; |
161 | |
162 | shared->thread = PR_CreateThread( |
163 | PR_USER_THREAD, Notified, shared, |
164 | PR_PRIORITY_HIGH, thread_scope, |
165 | PR_JOINABLE_THREAD, 0); |
166 | PR_ASSERT(shared->thread != NULL); |
167 | if (NULL == shared->thread) { |
168 | failed = PR_TRUE; |
169 | } |
170 | } |
171 | |
172 | for (loop_count = 1; loop_count <= loop_limit; ++loop_count) |
| 21 | | Assuming 'loop_count' is > 'loop_limit' | |
|
| 22 | | Loop condition is false. Execution continues on line 193 | |
|
173 | { |
174 | timein = PR_IntervalNow(); |
175 | for (inner_count = 0; inner_count < INNER_LOOPS; ++inner_count) |
176 | { |
177 | PR_Lock(home.ml); |
178 | home.twiddle = PR_TRUE; |
179 | shared->twiddle = PR_FALSE; |
180 | PR_NotifyCondVar(shared->cv); |
181 | while (home.twiddle) |
182 | { |
183 | status = PR_WaitCondVar(home.cv, PR_INTERVAL_NO_TIMEOUT); |
184 | if (PR_FAILURE == status) { |
185 | failed = PR_TRUE; |
186 | } |
187 | } |
188 | PR_Unlock(home.ml); |
189 | } |
190 | timeout += (PR_IntervalNow() - timein); |
191 | } |
192 | |
193 | if (debug_mode) |
| 23 | | Assuming 'debug_mode' is 0 | |
|
| |
194 | { |
195 | average = PR_IntervalToMicroseconds(timeout) |
196 | / (INNER_LOOPS * loop_limit * thread_count); |
197 | PR_fprintf( |
198 | debug_out, "Average switch times %d usecs for %d threads\n", |
199 | average, thread_limit); |
200 | } |
201 | |
202 | link = shared; |
| 25 | | Assigned value is garbage or undefined |
|
203 | for (thread_count = 1; thread_count <= thread_limit; ++thread_count) |
204 | { |
205 | if (&home == link) { |
206 | break; |
207 | } |
208 | status = PR_Interrupt(link->thread); |
209 | if (PR_SUCCESS != status) |
210 | { |
211 | failed = PR_TRUE; |
212 | if (debug_mode) { |
213 | PL_FPrintError(debug_out, "Failed to interrupt"); |
214 | } |
215 | } |
216 | link = link->next; |
217 | } |
218 | |
219 | for (thread_count = 1; thread_count <= thread_limit; ++thread_count) |
220 | { |
221 | link = shared->next; |
222 | status = PR_JoinThread(shared->thread); |
223 | if (PR_SUCCESS != status) |
224 | { |
225 | failed = PR_TRUE; |
226 | if (debug_mode) { |
227 | PL_FPrintError(debug_out, "Failed to join"); |
228 | } |
229 | } |
230 | PR_DestroyCondVar(shared->cv); |
231 | PR_DELETE(shared); |
232 | if (&home == link) { |
233 | break; |
234 | } |
235 | shared = link; |
236 | } |
237 | PR_DestroyCondVar(home.cv); |
238 | PR_DestroyLock(home.ml); |
239 | |
240 | PR_fprintf(PR_STDOUT, ((failed) ? "FAILED\n" : "PASSED\n")); |
241 | return ((failed) ? 1 : 0); |
242 | } |
243 | |
244 | int main(int argc, char **argv) |
245 | { |
246 | PRIntn result; |
247 | PR_STDIO_INIT(); |
248 | result = PR_Initialize(Switch, argc, argv, 0); |
249 | return result; |
250 | } |
251 | |
252 | |