Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/perf.c
Warning:line 56, column 9
Value stored to 'time' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

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 perf.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/perf.c
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5
6#include "nspr.h"
7#include "plgetopt.h"
8
9#include <stdio.h>
10#include <stdlib.h>
11#include <string.h>
12
13int _debug_on = 0;
14#define DPRINTF(arg)if (_debug_on) printf arg if (_debug_on) printf arg
15
16#include "obsolete/prsem.h"
17
18PRLock *lock;
19PRMonitor *mon;
20PRMonitor *mon2;
21
22#define DEFAULT_COUNT1000 1000
23
24PRInt32 count;
25
26static void nop(int a, int b, int c)
27{
28}
29
30static void LocalProcedureCall(void)
31{
32 PRInt32 i;
33
34 for (i = 0; i < count; i++) {
35 nop(i, i, 5);
36 }
37}
38
39static void DLLProcedureCall(void)
40{
41 PRInt32 i;
42 PRThreadState state;
43 PRThread *self = PR_GetCurrentThread();
44
45 for (i = 0; i < count; i++) {
46 state = PR_GetThreadState(self);
47 }
48}
49
50static void Now(void)
51{
52 PRInt32 i;
53 PRTime time;
54
55 for (i = 0; i < count; i++) {
56 time = PR_Now();
Value stored to 'time' is never read
57 }
58}
59
60static void Interval(void)
61{
62 PRInt32 i;
63 PRIntervalTime time;
64
65 for (i = 0; i < count; i++) {
66 time = PR_IntervalNow();
67 }
68}
69
70static void IdleLock(void)
71{
72 PRInt32 i;
73
74 for (i = 0; i < count; i++) {
75 PR_Lock(lock);
76 PR_Unlock(lock);
77 }
78}
79
80static void IdleMonitor(void)
81{
82 PRInt32 i;
83
84 for (i = 0; i < count; i++) {
85 PR_EnterMonitor(mon);
86 PR_ExitMonitor(mon);
87 }
88}
89
90static void IdleCMonitor(void)
91{
92 PRInt32 i;
93
94 for (i = 0; i < count; i++) {
95 PR_CEnterMonitor((void*)7);
96 PR_CExitMonitor((void*)7);
97 }
98}
99
100/************************************************************************/
101
102static void PR_CALLBACK dull(void *arg)
103{
104}
105
106static void CDThread(void)
107{
108 PRInt32 i;
109 int num_threads = count;
110
111 /*
112 * Cannot create too many threads
113 */
114 if (num_threads > 1000) {
115 num_threads = 1000;
116 }
117
118 for (i = 0; i < num_threads; i++) {
119 PRThread *t = PR_CreateThread(PR_USER_THREAD,
120 dull, 0,
121 PR_PRIORITY_NORMAL,
122 PR_LOCAL_THREAD,
123 PR_UNJOINABLE_THREAD,
124 0);
125 if (NULL((void*)0) == t) {
126 fprintf(stderrstderr, "CDThread: cannot create thread %3d\n", i);
127 } else {
128 DPRINTF(("CDThread: created thread %3d \n",i))if (_debug_on) printf ("CDThread: created thread %3d \n",i);
129 }
130 PR_Sleep(0);
131 }
132}
133
134static int alive;
135static int cxq;
136
137static void PR_CALLBACK CXReader(void *arg)
138{
139 PRInt32 i, n;
140
141 PR_EnterMonitor(mon);
142 n = count / 2;
143 for (i = 0; i < n; i++) {
144 while (cxq == 0) {
145 DPRINTF(("CXReader: thread = 0x%lx waiting\n",if (_debug_on) printf ("CXReader: thread = 0x%lx waiting\n", PR_GetCurrentThread
())
146 PR_GetCurrentThread()))if (_debug_on) printf ("CXReader: thread = 0x%lx waiting\n", PR_GetCurrentThread
())
;
147 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
148 }
149 --cxq;
150 PR_Notify(mon);
151 }
152 PR_ExitMonitor(mon);
153
154 PR_EnterMonitor(mon2);
155 --alive;
156 PR_Notify(mon2);
157 PR_ExitMonitor(mon2);
158 DPRINTF(("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("CXReader: thread = 0x%lx exiting\n", PR_GetCurrentThread
())
;
159}
160
161static void PR_CALLBACK CXWriter(void *arg)
162{
163 PRInt32 i, n;
164
165 PR_EnterMonitor(mon);
166 n = count / 2;
167 for (i = 0; i < n; i++) {
168 while (cxq == 1) {
169 DPRINTF(("CXWriter: thread = 0x%lx waiting\n",if (_debug_on) printf ("CXWriter: thread = 0x%lx waiting\n", PR_GetCurrentThread
())
170 PR_GetCurrentThread()))if (_debug_on) printf ("CXWriter: thread = 0x%lx waiting\n", PR_GetCurrentThread
())
;
171 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
172 }
173 ++cxq;
174 PR_Notify(mon);
175 }
176 PR_ExitMonitor(mon);
177
178 PR_EnterMonitor(mon2);
179 --alive;
180 PR_Notify(mon2);
181 PR_ExitMonitor(mon2);
182 DPRINTF(("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("CXWriter: thread = 0x%lx exiting\n", PR_GetCurrentThread
())
;
183}
184
185static void ContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
186{
187 PRThread *t1, *t2;
188
189 PR_EnterMonitor(mon2);
190 alive = 2;
191 cxq = 0;
192
193 t1 = PR_CreateThread(PR_USER_THREAD,
194 CXReader, 0,
195 PR_PRIORITY_NORMAL,
196 scope1,
197 PR_UNJOINABLE_THREAD,
198 0);
199 if (NULL((void*)0) == t1) {
200 fprintf(stderrstderr, "ContextSwitch: cannot create thread\n");
201 } else {
202 DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
203 (scope1 == PR_GLOBAL_THREAD ?if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
204 "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
205 t1))if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
;
206 }
207 t2 = PR_CreateThread(PR_USER_THREAD,
208 CXWriter, 0,
209 PR_PRIORITY_NORMAL,
210 scope2,
211 PR_UNJOINABLE_THREAD,
212 0);
213 if (NULL((void*)0) == t2) {
214 fprintf(stderrstderr, "ContextSwitch: cannot create thread\n");
215 } else {
216 DPRINTF(("ContextSwitch: created %s thread = 0x%lx\n",if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
217 (scope2 == PR_GLOBAL_THREAD ?if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
218 "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
219 t2))if (_debug_on) printf ("ContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
;
220 }
221
222 /* Wait for both of the threads to exit */
223 while (alive) {
224 PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
225 }
226 PR_ExitMonitor(mon2);
227}
228
229static void ContextSwitchUU(void)
230{
231 ContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
232}
233
234static void ContextSwitchUK(void)
235{
236 ContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
237}
238
239static void ContextSwitchKU(void)
240{
241 ContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
242}
243
244static void ContextSwitchKK(void)
245{
246 ContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
247}
248
249/************************************************************************/
250
251static void PR_CALLBACK SemaThread(void *argSema)
252{
253 PRSemaphore **sem = (PRSemaphore **)argSema;
254 PRInt32 i, n;
255
256 n = count / 2;
257 for (i = 0; i < n; i++) {
258 DPRINTF(("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n",if (_debug_on) printf ("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n"
, PR_GetCurrentThread(), sem[0])
259 PR_GetCurrentThread(), sem[0]))if (_debug_on) printf ("SemaThread: thread = 0x%lx waiting on sem = 0x%lx\n"
, PR_GetCurrentThread(), sem[0])
;
260 PR_WaitSem(sem[0]);
261 DPRINTF(("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n",if (_debug_on) printf ("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n"
, PR_GetCurrentThread(), sem[1])
262 PR_GetCurrentThread(), sem[1]))if (_debug_on) printf ("SemaThread: thread = 0x%lx posting on sem = 0x%lx\n"
, PR_GetCurrentThread(), sem[1])
;
263 PR_PostSem(sem[1]);
264 }
265
266 PR_EnterMonitor(mon2);
267 --alive;
268 PR_Notify(mon2);
269 PR_ExitMonitor(mon2);
270 DPRINTF(("SemaThread: thread = 0x%lx exiting\n", PR_GetCurrentThread()))if (_debug_on) printf ("SemaThread: thread = 0x%lx exiting\n"
, PR_GetCurrentThread())
;
271}
272
273static PRSemaphore *sem_set1[2];
274static PRSemaphore *sem_set2[2];
275
276static void SemaContextSwitch(PRThreadScope scope1, PRThreadScope scope2)
277{
278 PRThread *t1, *t2;
279 sem_set1[0] = PR_NewSem(1);
280 sem_set1[1] = PR_NewSem(0);
281 sem_set2[0] = sem_set1[1];
282 sem_set2[1] = sem_set1[0];
283
284 PR_EnterMonitor(mon2);
285 alive = 2;
286 cxq = 0;
287
288 t1 = PR_CreateThread(PR_USER_THREAD,
289 SemaThread,
290 sem_set1,
291 PR_PRIORITY_NORMAL,
292 scope1,
293 PR_UNJOINABLE_THREAD,
294 0);
295 if (NULL((void*)0) == t1) {
296 fprintf(stderrstderr, "SemaContextSwitch: cannot create thread\n");
297 } else {
298 DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
299 (scope1 == PR_GLOBAL_THREAD ?if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
300 "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
301 t1))if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope1 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t1)
;
302 }
303 t2 = PR_CreateThread(PR_USER_THREAD,
304 SemaThread,
305 sem_set2,
306 PR_PRIORITY_NORMAL,
307 scope2,
308 PR_UNJOINABLE_THREAD,
309 0);
310 if (NULL((void*)0) == t2) {
311 fprintf(stderrstderr, "SemaContextSwitch: cannot create thread\n");
312 } else {
313 DPRINTF(("SemaContextSwitch: created %s thread = 0x%lx\n",if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
314 (scope2 == PR_GLOBAL_THREAD ?if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
315 "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"),if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
316 t2))if (_debug_on) printf ("SemaContextSwitch: created %s thread = 0x%lx\n"
, (scope2 == PR_GLOBAL_THREAD ? "PR_GLOBAL_THREAD" : "PR_LOCAL_THREAD"
), t2)
;
317 }
318
319 /* Wait for both of the threads to exit */
320 while (alive) {
321 PR_Wait(mon2, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
322 }
323 PR_ExitMonitor(mon2);
324
325 PR_DestroySem(sem_set1[0]);
326 PR_DestroySem(sem_set1[1]);
327}
328
329static void SemaContextSwitchUU(void)
330{
331 SemaContextSwitch(PR_LOCAL_THREAD, PR_LOCAL_THREAD);
332}
333
334static void SemaContextSwitchUK(void)
335{
336 SemaContextSwitch(PR_LOCAL_THREAD, PR_GLOBAL_THREAD);
337}
338
339static void SemaContextSwitchKU(void)
340{
341 SemaContextSwitch(PR_GLOBAL_THREAD, PR_LOCAL_THREAD);
342}
343
344static void SemaContextSwitchKK(void)
345{
346 SemaContextSwitch(PR_GLOBAL_THREAD, PR_GLOBAL_THREAD);
347}
348
349
350/************************************************************************/
351
352static void Measure(void (*func)(void), const char *msg)
353{
354 PRIntervalTime start, stop;
355 double d;
356
357 start = PR_IntervalNow();
358 (*func)();
359 stop = PR_IntervalNow() - start;
360 d = (double)PR_IntervalToMicroseconds(stop);
361
362 printf("%40s: %6.2f usec\n", msg, d / count);
363}
364
365int main(int argc, char **argv)
366{
367 PLOptStatus os;
368 PLOptState *opt = PL_CreateOptState(argc, argv, "dc:");
369 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
370 {
371 if (PL_OPT_BAD == os) {
372 continue;
373 }
374 switch (opt->option)
375 {
376 case 'd': /* debug mode */
377 _debug_on = 1;
378 break;
379 case 'c': /* loop count */
380 count = atoi(opt->value);
381 break;
382 default:
383 break;
384 }
385 }
386 PL_DestroyOptState(opt);
387
388 if (0 == count) {
389 count = DEFAULT_COUNT1000;
390 }
391
392 PR_Init(PR_USER_THREAD, PR_PRIORITY_NORMAL, 0);
393 PR_BlockClockInterrupts();
394 PR_UnblockClockInterrupts();
395 PR_STDIO_INIT();
396
397 lock = PR_NewLock();
398 mon = PR_NewMonitor();
399 mon2 = PR_NewMonitor();
400
401 Measure(LocalProcedureCall, "local procedure call overhead");
402 Measure(DLLProcedureCall, "DLL procedure call overhead");
403 Measure(Now, "current calendar time");
404 Measure(Interval, "interval time");
405 Measure(IdleLock, "idle lock lock/unlock pair");
406 Measure(IdleMonitor, "idle monitor entry/exit pair");
407 Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
408 Measure(CDThread, "create/destroy thread pair");
409 Measure(ContextSwitchUU, "context switch - user/user");
410 Measure(ContextSwitchUK, "context switch - user/kernel");
411 Measure(ContextSwitchKU, "context switch - kernel/user");
412 Measure(ContextSwitchKK, "context switch - kernel/kernel");
413 Measure(SemaContextSwitchUU, "sema context switch - user/user");
414 Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
415 Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
416 Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
417
418 printf("--------------\n");
419 printf("Adding 7 additional CPUs\n");
420
421 PR_SetConcurrency(8);
422 printf("--------------\n");
423
424 Measure(LocalProcedureCall, "local procedure call overhead");
425 Measure(DLLProcedureCall, "DLL procedure call overhead");
426 Measure(Now, "current calendar time");
427 Measure(Interval, "interval time");
428 Measure(IdleLock, "idle lock lock/unlock pair");
429 Measure(IdleMonitor, "idle monitor entry/exit pair");
430 Measure(IdleCMonitor, "idle cache monitor entry/exit pair");
431 Measure(CDThread, "create/destroy thread pair");
432 Measure(ContextSwitchUU, "context switch - user/user");
433 Measure(ContextSwitchUK, "context switch - user/kernel");
434 Measure(ContextSwitchKU, "context switch - kernel/user");
435 Measure(ContextSwitchKK, "context switch - kernel/kernel");
436 Measure(SemaContextSwitchUU, "sema context switch - user/user");
437 Measure(SemaContextSwitchUK, "sema context switch - user/kernel");
438 Measure(SemaContextSwitchKU, "sema context switch - kernel/user");
439 Measure(SemaContextSwitchKK, "sema context switch - kernel/kernel");
440
441 PR_DestroyLock(lock);
442 PR_DestroyMonitor(mon);
443 PR_DestroyMonitor(mon2);
444
445 PR_Cleanup();
446 return 0;
447}