VirtualBox

source: vbox/trunk/src/libs/xpcom18a4/nsprpub/pr/tests/thruput.c@ 55761

最後變更 在這個檔案從55761是 1,由 vboxsync 提交於 55 年 前

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.1 KB
 
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2/* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is the Netscape Portable Runtime (NSPR).
16 *
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998-2000
20 * the Initial Developer. All Rights Reserved.
21 *
22 * Contributor(s):
23 *
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
35 *
36 * ***** END LICENSE BLOCK ***** */
37
38/*
39** File: thruput.c
40** Description: Test server's throughput capability comparing various
41** implmentation strategies.
42**
43** Note: Requires a server machine and an aribitrary number of
44** clients to bang on it. Trust the numbers on the server
45** more than those being displayed by the various clients.
46*/
47
48#include "prerror.h"
49#include "prinrval.h"
50#include "prinit.h"
51#include "prio.h"
52#include "prlock.h"
53#include "prmem.h"
54#include "prnetdb.h"
55#include "prprf.h"
56#include "prthread.h"
57
58#include "pprio.h"
59
60#include "plerror.h"
61#include "plgetopt.h"
62
63#define ADDR_BUFFER 100
64#define PORT_NUMBER 51877
65#define SAMPLING_INTERVAL 10
66#define BUFFER_SIZE (32 * 1024)
67
68static PRInt32 domain = PR_AF_INET;
69static PRInt32 protocol = 6; /* TCP */
70static PRFileDesc *err = NULL;
71static PRIntn concurrency = 1;
72static PRInt32 xport_buffer = -1;
73static PRUint32 initial_streams = 1;
74static PRInt32 buffer_size = BUFFER_SIZE;
75static PRThreadScope thread_scope = PR_LOCAL_THREAD;
76
77typedef struct Shared
78{
79 PRLock *ml;
80 PRUint32 sampled;
81 PRUint32 threads;
82 PRIntervalTime timein;
83 PRNetAddr server_address;
84} Shared;
85
86static Shared *shared = NULL;
87
88static PRStatus PrintAddress(const PRNetAddr* address)
89{
90 char buffer[ADDR_BUFFER];
91 PRStatus rv = PR_NetAddrToString(address, buffer, sizeof(buffer));
92 if (PR_SUCCESS == rv)
93 PR_fprintf(err, "%s:%u\n", buffer, PR_ntohs(address->inet.port));
94 else PL_FPrintError(err, "PR_NetAddrToString");
95 return rv;
96} /* PrintAddress */
97
98
99static void PR_CALLBACK Clientel(void *arg)
100{
101 PRStatus rv;
102 PRFileDesc *xport;
103 PRInt32 bytes, sampled;
104 PRIntervalTime now, interval;
105 PRBool do_display = PR_FALSE;
106 Shared *shared = (Shared*)arg;
107 char *buffer = (char*)PR_Malloc(buffer_size);
108 PRNetAddr *server_address = &shared->server_address;
109 PRIntervalTime connect_timeout = PR_SecondsToInterval(5);
110 PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
111
112 PR_fprintf(err, "Client connecting to ");
113 (void)PrintAddress(server_address);
114
115 do
116 {
117 xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
118 if (NULL == xport)
119 {
120 PL_FPrintError(err, "PR_Socket");
121 return;
122 }
123
124 if (xport_buffer != -1)
125 {
126 PRSocketOptionData data;
127 data.option = PR_SockOpt_RecvBufferSize;
128 data.value.recv_buffer_size = (PRSize)xport_buffer;
129 rv = PR_SetSocketOption(xport, &data);
130 if (PR_FAILURE == rv)
131 PL_FPrintError(err, "PR_SetSocketOption - ignored");
132 data.option = PR_SockOpt_SendBufferSize;
133 data.value.send_buffer_size = (PRSize)xport_buffer;
134 rv = PR_SetSocketOption(xport, &data);
135 if (PR_FAILURE == rv)
136 PL_FPrintError(err, "PR_SetSocketOption - ignored");
137 }
138
139 rv = PR_Connect(xport, server_address, connect_timeout);
140 if (PR_FAILURE == rv)
141 {
142 PL_FPrintError(err, "PR_Connect");
143 if (PR_IO_TIMEOUT_ERROR != PR_GetError())
144 PR_Sleep(connect_timeout);
145 PR_Close(xport); /* delete it and start over */
146 }
147 } while (PR_FAILURE == rv);
148
149 do
150 {
151 bytes = PR_Recv(
152 xport, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
153 PR_Lock(shared->ml);
154 now = PR_IntervalNow();
155 shared->sampled += bytes;
156 interval = now - shared->timein;
157 if (interval > sampling_interval)
158 {
159 sampled = shared->sampled;
160 shared->timein = now;
161 shared->sampled = 0;
162 do_display = PR_TRUE;
163 }
164 PR_Unlock(shared->ml);
165
166 if (do_display)
167 {
168 PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
169 PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
170 do_display = PR_FALSE;
171 }
172
173 } while (bytes > 0);
174} /* Clientel */
175
176static void Client(const char *server_name)
177{
178 PRStatus rv;
179 PRHostEnt host;
180 char buffer[PR_NETDB_BUF_SIZE];
181 PRIntervalTime dally = PR_SecondsToInterval(60);
182 PR_fprintf(err, "Translating the name %s\n", server_name);
183 rv = PR_GetHostByName(server_name, buffer, sizeof(buffer), &host);
184 if (PR_FAILURE == rv)
185 PL_FPrintError(err, "PR_GetHostByName");
186 else
187 {
188 if (PR_EnumerateHostEnt(
189 0, &host, PORT_NUMBER, &shared->server_address) < 0)
190 PL_FPrintError(err, "PR_EnumerateHostEnt");
191 else
192 {
193 do
194 {
195 shared->threads += 1;
196 (void)PR_CreateThread(
197 PR_USER_THREAD, Clientel, shared,
198 PR_PRIORITY_NORMAL, thread_scope,
199 PR_UNJOINABLE_THREAD, 8 * 1024);
200 if (shared->threads == initial_streams)
201 {
202 PR_Sleep(dally);
203 initial_streams += 1;
204 }
205 } while (PR_TRUE);
206 }
207 }
208}
209
210static void PR_CALLBACK Servette(void *arg)
211{
212 PRInt32 bytes, sampled;
213 PRIntervalTime now, interval;
214 PRBool do_display = PR_FALSE;
215 PRFileDesc *client = (PRFileDesc*)arg;
216 char *buffer = (char*)PR_Malloc(buffer_size);
217 PRIntervalTime sampling_interval = PR_SecondsToInterval(SAMPLING_INTERVAL);
218
219 if (xport_buffer != -1)
220 {
221 PRStatus rv;
222 PRSocketOptionData data;
223 data.option = PR_SockOpt_RecvBufferSize;
224 data.value.recv_buffer_size = (PRSize)xport_buffer;
225 rv = PR_SetSocketOption(client, &data);
226 if (PR_FAILURE == rv)
227 PL_FPrintError(err, "PR_SetSocketOption - ignored");
228 data.option = PR_SockOpt_SendBufferSize;
229 data.value.send_buffer_size = (PRSize)xport_buffer;
230 rv = PR_SetSocketOption(client, &data);
231 if (PR_FAILURE == rv)
232 PL_FPrintError(err, "PR_SetSocketOption - ignored");
233 }
234
235 do
236 {
237 bytes = PR_Send(
238 client, buffer, buffer_size, 0, PR_INTERVAL_NO_TIMEOUT);
239
240 PR_Lock(shared->ml);
241 now = PR_IntervalNow();
242 shared->sampled += bytes;
243 interval = now - shared->timein;
244 if (interval > sampling_interval)
245 {
246 sampled = shared->sampled;
247 shared->timein = now;
248 shared->sampled = 0;
249 do_display = PR_TRUE;
250 }
251 PR_Unlock(shared->ml);
252
253 if (do_display)
254 {
255 PRUint32 rate = sampled / PR_IntervalToMilliseconds(interval);
256 PR_fprintf(err, "%u streams @ %u Kbytes/sec\n", shared->threads, rate);
257 do_display = PR_FALSE;
258 }
259 } while (bytes > 0);
260} /* Servette */
261
262static void Server(void)
263{
264 PRStatus rv;
265 PRNetAddr server_address, client_address;
266 PRFileDesc *xport = PR_Socket(domain, PR_SOCK_STREAM, protocol);
267
268 if (NULL == xport)
269 {
270 PL_FPrintError(err, "PR_Socket");
271 return;
272 }
273
274 rv = PR_InitializeNetAddr(PR_IpAddrAny, PORT_NUMBER, &server_address);
275 if (PR_FAILURE == rv) PL_FPrintError(err, "PR_InitializeNetAddr");
276 else
277 {
278 rv = PR_Bind(xport, &server_address);
279 if (PR_FAILURE == rv) PL_FPrintError(err, "PR_Bind");
280 else
281 {
282 PRFileDesc *client;
283 rv = PR_Listen(xport, 10);
284 PR_fprintf(err, "Server listening on ");
285 (void)PrintAddress(&server_address);
286 do
287 {
288 client = PR_Accept(
289 xport, &client_address, PR_INTERVAL_NO_TIMEOUT);
290 if (NULL == client) PL_FPrintError(err, "PR_Accept");
291 else
292 {
293 PR_fprintf(err, "Server accepting from ");
294 (void)PrintAddress(&client_address);
295 shared->threads += 1;
296 (void)PR_CreateThread(
297 PR_USER_THREAD, Servette, client,
298 PR_PRIORITY_NORMAL, thread_scope,
299 PR_UNJOINABLE_THREAD, 8 * 1024);
300 }
301 } while (PR_TRUE);
302
303 }
304 }
305} /* Server */
306
307static void Help(void)
308{
309 PR_fprintf(err, "Usage: [-h] [<server>]\n");
310 PR_fprintf(err, "\t-s <n> Initial # of connections (default: 1)\n");
311 PR_fprintf(err, "\t-C <n> Set 'concurrency' (default: 1)\n");
312 PR_fprintf(err, "\t-b <nK> Client buffer size (default: 32k)\n");
313 PR_fprintf(err, "\t-B <nK> Transport recv/send buffer size (default: sys)\n");
314 PR_fprintf(err, "\t-G Use GLOBAL threads (default: LOCAL)\n");
315 PR_fprintf(err, "\t-X Use XTP transport (default: TCP)\n");
316 PR_fprintf(err, "\t-6 Use IPv6 (default: IPv4)\n");
317 PR_fprintf(err, "\t-h This message and nothing else\n");
318 PR_fprintf(err, "\t<server> DNS name of server\n");
319 PR_fprintf(err, "\t\tIf <server> is not specified, this host will be\n");
320 PR_fprintf(err, "\t\tthe server and not act as a client.\n");
321} /* Help */
322
323PRIntn main(PRIntn argc, char **argv)
324{
325 PLOptStatus os;
326 const char *server_name = NULL;
327 PLOptState *opt = PL_CreateOptState(argc, argv, "hGX6C:b:s:B:");
328
329 err = PR_GetSpecialFD(PR_StandardError);
330
331 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
332 {
333 if (PL_OPT_BAD == os) continue;
334 switch (opt->option)
335 {
336 case 0: /* Name of server */
337 server_name = opt->value;
338 break;
339 case 'G': /* Globular threads */
340 thread_scope = PR_GLOBAL_THREAD;
341 break;
342 case 'X': /* Use XTP as the transport */
343 protocol = 36;
344 break;
345 case '6': /* Use IPv6 */
346 domain = PR_AF_INET6;
347 break;
348 case 's': /* initial_streams */
349 initial_streams = atoi(opt->value);
350 break;
351 case 'C': /* concurrency */
352 concurrency = atoi(opt->value);
353 break;
354 case 'b': /* buffer size */
355 buffer_size = 1024 * atoi(opt->value);
356 break;
357 case 'B': /* buffer size */
358 xport_buffer = 1024 * atoi(opt->value);
359 break;
360 case 'h': /* user wants some guidance */
361 default:
362 Help(); /* so give him an earful */
363 return 2; /* but not a lot else */
364 }
365 }
366 PL_DestroyOptState(opt);
367
368 shared = PR_NEWZAP(Shared);
369 shared->ml = PR_NewLock();
370
371 PR_fprintf(err,
372 "This machine is %s\n",
373 (NULL == server_name) ? "the SERVER" : "a CLIENT");
374
375 PR_fprintf(err,
376 "Transport being used is %s\n",
377 (6 == protocol) ? "TCP" : "XTP");
378
379 if (PR_GLOBAL_THREAD == thread_scope)
380 {
381 if (1 != concurrency)
382 {
383 PR_fprintf(err, " **Concurrency > 1 and GLOBAL threads!?!?\n");
384 PR_fprintf(err, " **Ignoring concurrency\n");
385 concurrency = 1;
386 }
387 }
388
389 if (1 != concurrency)
390 {
391 PR_SetConcurrency(concurrency);
392 PR_fprintf(err, "Concurrency set to %u\n", concurrency);
393 }
394
395 PR_fprintf(err,
396 "All threads will be %s\n",
397 (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
398
399 PR_fprintf(err, "Client buffer size will be %u\n", buffer_size);
400
401 if (-1 != xport_buffer)
402 PR_fprintf(
403 err, "Transport send & receive buffer size will be %u\n", xport_buffer);
404
405
406 if (NULL == server_name) Server();
407 else Client(server_name);
408
409} /* main */
410
411/* thruput.c */
412
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette