Bug Summary

File:pr/Linux4.19_x86_64_gcc_glibc_PTH_64_DBG.OBJ/pr/tests/../../../pr/tests/thruput.c
Warning:line 276, column 13
Value stored to 'rv' 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 thruput.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/thruput.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/*
7** File: thruput.c
8** Description: Test server's throughput capability comparing various
9** implmentation strategies.
10**
11** Note: Requires a server machine and an aribitrary number of
12** clients to bang on it. Trust the numbers on the server
13** more than those being displayed by the various clients.
14*/
15
16#include "prerror.h"
17#include "prinrval.h"
18#include "prinit.h"
19#include "prio.h"
20#include "prlock.h"
21#include "prmem.h"
22#include "prnetdb.h"
23#include "prprf.h"
24#include "prthread.h"
25#include "pprio.h"
26#include "plerror.h"
27#include "plgetopt.h"
28
29#define ADDR_BUFFER100 100
30
31#ifdef DEBUG1
32#define PORT_INC_DO+100 +100
33#else
34#define PORT_INC_DO+100
35#endif
36#ifdef IS_64
37#define PORT_INC_3264+200 +200
38#else
39#define PORT_INC_3264+200
40#endif
41
42#define PORT_NUMBER51877 +100 +200 51877 PORT_INC_DO+100 PORT_INC_3264+200
43
44#define SAMPLING_INTERVAL10 10
45#define BUFFER_SIZE(32 * 1024) (32 * 1024)
46
47static PRInt32 domain = PR_AF_INET2;
48static PRInt32 protocol = 6; /* TCP */
49static PRFileDesc *err = NULL((void*)0);
50static PRIntn concurrency = 1;
51static PRInt32 xport_buffer = -1;
52static PRUint32 initial_streams = 1;
53static PRInt32 buffer_size = BUFFER_SIZE(32 * 1024);
54static PRThreadScope thread_scope = PR_LOCAL_THREAD;
55
56typedef struct Shared
57{
58 PRLock *ml;
59 PRUint32 sampled;
60 PRUint32 threads;
61 PRIntervalTime timein;
62 PRNetAddr server_address;
63} Shared;
64
65static Shared *shared = NULL((void*)0);
66
67static PRStatus PrintAddress(const PRNetAddr* address)
68{
69 char buffer[ADDR_BUFFER100];
70 PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
71 if (PR_SUCCESS == rv) {
72 PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
73 }
74 else {
75 PL_FPrintError(err, "PR_NetAddrToString");
76 }
77 return rv;
78} /* PrintAddress */
79
80
81static void PR_CALLBACK Clientel(void *arg)
82{
83 PRStatus rv;
84 PRFileDesc *xport;
85 PRInt32 bytes, sampled;
86 PRIntervalTime now, interval;
87 PRBool do_display = PR_FALSE0;
88 Shared *shared = (Shared*)arg;
89 char *buffer = (char*)PR_Malloc(buffer_size);
90 PRNetAddr *server_address = &shared->server_address;
91 PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
92 PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL10);
93
94 PR_fprintf(err, "Client connecting to ");
95 (void)PrintAddress(server_address);
96
97 do
98 {
99 xport = PR_Socket(domain, PR_SOCK_STREAMSOCK_STREAM, protocol);
100 if (NULL((void*)0) == xport)
101 {
102 PL_FPrintError(err, "PR_Socket");
103 return;
104 }
105
106 if (xport_buffer != -1)
107 {
108 PRSocketOptionData data;
109 data.option = PR_SockOpt_RecvBufferSize;
110 data.value.recv_buffer_size = (PRSize)xport_buffer;
111 rv = PR_SetSocketOption(xport, &data);
112 if (PR_FAILURE == rv) {
113 PL_FPrintError(err, "PR_SetSocketOption - ignored");
114 }
115 data.option = PR_SockOpt_SendBufferSize;
116 data.value.send_buffer_size = (PRSize)xport_buffer;
117 rv = PR_SetSocketOption(xport, &data);
118 if (PR_FAILURE == rv) {
119 PL_FPrintError(err, "PR_SetSocketOption - ignored");
120 }
121 }
122
123 rv = PR_Connect(xport, server_address, connect_timeout);
124 if (PR_FAILURE == rv)
125 {
126 PL_FPrintError(err, "PR_Connect");
127 if (PR_IO_TIMEOUT_ERROR(-5990L) != PR_GetError()) {
128 PR_Sleep(connect_timeout);
129 }
130 PR_Close(xport); /* delete it and start over */
131 }
132 } while (PR_FAILURE == rv);
133
134 do
135 {
136 bytes = PR_Recv(
137 xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
138 PR_Lock(shared->ml);
139 now = PR_IntervalNow();
140 shared->sampled += bytes;
141 interval = now - shared->timein;
142 if (interval > sampling_interval)
143 {
144 sampled = shared->sampled;
145 shared->timein = now;
146 shared->sampled = 0;
147 do_display = PR_TRUE1;
148 }
149 PR_Unlock(shared->ml);
150
151 if (do_display)
152 {
153 PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
154 PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
155 do_display = PR_FALSE0;
156 }
157
158 } while (bytes > 0);
159} /* Clientel */
160
161static void Client(const char *server_name)
162{
163 PRStatus rv;
164 PRHostEnt host;
165 char buffer[PR_NETDB_BUF_SIZE2048];
166 PRIntervalTime dally = PR_SecondsToInterval(60);
167 PR_fprintf(err, "Translating the name %s\n", server_name);
168 rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host);
169 if (PR_FAILURE == rv) {
170 PL_FPrintError(err, "PR_GetHostByName");
171 }
172 else
173 {
174 if (PR_EnumerateHostEnt(
175 0, &host, PORT_NUMBER51877 +100 +200, &shared->server_address) < 0) {
176 PL_FPrintError(err, "PR_EnumerateHostEnt");
177 }
178 else
179 {
180 do
181 {
182 shared->threads += 1;
183 (void)PR_CreateThread(
184 PR_USER_THREAD, Clientel, shared,
185 PR_PRIORITY_NORMAL, thread_scope,
186 PR_UNJOINABLE_THREAD, 8 * 1024);
187 if (shared->threads == initial_streams)
188 {
189 PR_Sleep(dally);
190 initial_streams += 1;
191 }
192 } while (PR_TRUE1);
193 }
194 }
195}
196
197static void PR_CALLBACK Servette(void *arg)
198{
199 PRInt32 bytes, sampled;
200 PRIntervalTime now, interval;
201 PRBool do_display = PR_FALSE0;
202 PRFileDesc *client = (PRFileDesc*)arg;
203 char *buffer = (char*)PR_Malloc(buffer_size);
204 PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL10);
205
206 if (xport_buffer != -1)
207 {
208 PRStatus rv;
209 PRSocketOptionData data;
210 data.option = PR_SockOpt_RecvBufferSize;
211 data.value.recv_buffer_size = (PRSize)xport_buffer;
212 rv = PR_SetSocketOption(client, &data);
213 if (PR_FAILURE == rv) {
214 PL_FPrintError(err, "PR_SetSocketOption - ignored");
215 }
216 data.option = PR_SockOpt_SendBufferSize;
217 data.value.send_buffer_size = (PRSize)xport_buffer;
218 rv = PR_SetSocketOption(client, &data);
219 if (PR_FAILURE == rv) {
220 PL_FPrintError(err, "PR_SetSocketOption - ignored");
221 }
222 }
223
224 do
225 {
226 bytes = PR_Send(
227 client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
228
229 PR_Lock(shared->ml);
230 now = PR_IntervalNow();
231 shared->sampled += bytes;
232 interval = now - shared->timein;
233 if (interval > sampling_interval)
234 {
235 sampled = shared->sampled;
236 shared->timein = now;
237 shared->sampled = 0;
238 do_display = PR_TRUE1;
239 }
240 PR_Unlock(shared->ml);
241
242 if (do_display)
243 {
244 PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
245 PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
246 do_display = PR_FALSE0;
247 }
248 } while (bytes > 0);
249} /* Servette */
250
251static void Server(void)
252{
253 PRStatus rv;
254 PRNetAddr server_address, client_address;
255 PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAMSOCK_STREAM, protocol);
256
257 if (NULL((void*)0) == xport)
258 {
259 PL_FPrintError(err, "PR_Socket");
260 return;
261 }
262
263 rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER51877 +100 +200, &server_address);
264 if (PR_FAILURE == rv) {
265 PL_FPrintError(err, "PR_InitializeNetAddr");
266 }
267 else
268 {
269 rv = PR_Bind(xport, &server_address);
270 if (PR_FAILURE == rv) {
271 PL_FPrintError(err, "PR_Bind");
272 }
273 else
274 {
275 PRFileDesc *client;
276 rv = PR_Listen(xport, 10);
Value stored to 'rv' is never read
277 PR_fprintf(err, "Server listening on ");
278 (void)PrintAddress(&server_address);
279 do
280 {
281 client = PR_Accept(
282 xport, &client_address, PR_INTERVAL_NO_TIMEOUT0xffffffffUL);
283 if (NULL((void*)0) == client) {
284 PL_FPrintError(err, "PR_Accept");
285 }
286 else
287 {
288 PR_fprintf(err, "Server accepting from ");
289 (void)PrintAddress(&client_address);
290 shared->threads += 1;
291 (void)PR_CreateThread(
292 PR_USER_THREAD, Servette, client,
293 PR_PRIORITY_NORMAL, thread_scope,
294 PR_UNJOINABLE_THREAD, 8 * 1024);
295 }
296 } while (PR_TRUE1);
297
298 }
299 }
300} /* Server */
301
302static void Help(void)
303{
304 PR_fprintf(err, "Usage: [-h] [<server>]\n");
305 PR_fprintf(err, "\t-s <n> Initial # of connections (default: 1)\n");
306 PR_fprintf(err, "\t-C <n> Set 'concurrency' (default: 1)\n");
307 PR_fprintf(err, "\t-b <nK> Client buffer size (default: 32k)\n");
308 PR_fprintf(err, "\t-B <nK> Transport recv/send buffer size (default: sys)\n");
309 PR_fprintf(err, "\t-G Use GLOBAL threads (default: LOCAL)\n");
310 PR_fprintf(err, "\t-X Use XTP transport (default: TCP)\n");
311 PR_fprintf(err, "\t-6 Use IPv6 (default: IPv4)\n");
312 PR_fprintf(err, "\t-h This message and nothing else\n");
313 PR_fprintf(err, "\t<server> DNS name of server\n");
314 PR_fprintf(err, "\t\tIf <server> is not specified, this host will be\n");
315 PR_fprintf(err, "\t\tthe server and not act as a client.\n");
316} /* Help */
317
318int main(int argc, char **argv)
319{
320 PLOptStatus os;
321 const char *server_name = NULL((void*)0);
322 PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:");
323
324 err = PR_GetSpecialFD(PR_StandardError);
325
326 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
327 {
328 if (PL_OPT_BAD == os) {
329 continue;
330 }
331 switch (opt->option)
332 {
333 case 0: /* Name of server */
334 server_name = opt->value;
335 break;
336 case 'G': /* Globular threads */
337 thread_scope = PR_GLOBAL_THREAD;
338 break;
339 case 'X': /* Use XTP as the transport */
340 protocol = 36;
341 break;
342 case '6': /* Use IPv6 */
343 domain = PR_AF_INET610;
344 break;
345 case 's': /* initial_streams */
346 initial_streams = atoi(opt->value);
347 break;
348 case 'C': /* concurrency */
349 concurrency = atoi(opt->value);
350 break;
351 case 'b': /* buffer size */
352 buffer_size = 1024 * atoi(opt->value);
353 break;
354 case 'B': /* buffer size */
355 xport_buffer = 1024 * atoi(opt->value);
356 break;
357 case 'h': /* user wants some guidance */
358 default:
359 Help(); /* so give him an earful */
360 return 2; /* but not a lot else */
361 }
362 }
363 PL_DestroyOptState(opt);
364
365 shared = PR_NEWZAP(Shared)((Shared*)PR_Calloc(1, sizeof(Shared)));
366 shared->ml = PR_NewLock();
367
368 PR_fprintf(err,
369 "This machine is %s\n",
370 (NULL((void*)0) == server_name) ? "the SERVER" : "a CLIENT");
371
372 PR_fprintf(err,
373 "Transport being used is %s\n",
374 (6 == protocol) ? "TCP" : "XTP");
375
376 if (PR_GLOBAL_THREAD == thread_scope)
377 {
378 if (1 != concurrency)
379 {
380 PR_fprintf(err, " **Concurrency > 1 and GLOBAL threads!?!?\n");
381 PR_fprintf(err, " **Ignoring concurrency\n");
382 concurrency = 1;
383 }
384 }
385
386 if (1 != concurrency)
387 {
388 PR_SetConcurrency(concurrency);
389 PR_fprintf(err, "Concurrency set to %u\n", concurrency);
390 }
391
392 PR_fprintf(err,
393 "All threads will be %s\n",
394 (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
395
396 PR_fprintf(err, "Client buffer size will be %u\n", buffer_size);
397
398 if (-1 != xport_buffer)
399 PR_fprintf(
400 err, "Transport send & receive buffer size will be %u\n", xport_buffer);
401
402
403 if (NULL((void*)0) == server_name) {
404 Server();
405 }
406 else {
407 Client(server_name);
408 }
409
410 return 0;
411} /* main */
412
413/* thruput.c */
414