VirtualBox

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

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

import

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 13.6 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: instrumt.c
40** Description: This test is for the NSPR debug aids defined in
41** prcountr.h, prtrace.h, prolock.h
42**
43** The test case tests the three debug aids in NSPR:
44**
45** Diagnostic messages can be enabled using "instrumt -v 6"
46** This sets the msgLevel to something that PR_LOG() likes.
47** Also define in the environment "NSPR_LOG_MODULES=Test:6"
48**
49** CounterTest() tests the counter facility. This test
50** creates 4 threads. Each thread either increments, decrements,
51** adds to or subtracts from a counter, depending on an argument
52** passed to the thread at thread-create time. Each of these threads
53** does COUNT_LIMIT iterations doing its thing. When all 4 threads
54** are done, the result of the counter is evaluated. If all was atomic,
55** the the value of the counter should be zero.
56**
57** TraceTest():
58** This test mingles with the counter test. Counters trace.
59** A thread to extract trace entries on the fly is started.
60** A thread to dump trace entries to a file is started.
61**
62** OrderedLockTest():
63**
64**
65**
66**
67**
68*/
69
70#include <stdio.h>
71#include <plstr.h>
72#include <prclist.h>
73#include <prmem.h>
74#include <plgetopt.h>
75#include <prlog.h>
76#include <prmon.h>
77#include <pratom.h>
78#include <prtrace.h>
79#include <prcountr.h>
80#include <prolock.h>
81
82#define COUNT_LIMIT (10 * ( 1024))
83
84#define SMALL_TRACE_BUFSIZE ( 60 * 1024 )
85
86typedef enum
87{
88 CountLoop = 1,
89 TraceLoop = 2,
90 TraceFlow = 3
91} TraceTypes;
92
93
94PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;
95
96PRBool help = PR_FALSE;
97PRBool failed = PR_FALSE;
98
99
100PRLogModuleInfo *lm;
101PRMonitor *mon;
102PRInt32 activeThreads = 0;
103PR_DEFINE_COUNTER( hCounter );
104PR_DEFINE_TRACE( hTrace );
105
106static void Help(void)
107{
108 printf("Help? ... Ha!\n");
109}
110
111static void ListCounters(void)
112{
113 PR_DEFINE_COUNTER( qh );
114 PR_DEFINE_COUNTER( rh );
115 const char *qn, *rn, *dn;
116 const char **qname = &qn, **rname = &rn, **desc = &dn;
117 PRUint32 tCtr;
118
119 PR_INIT_COUNTER_HANDLE( qh, NULL );
120 PR_FIND_NEXT_COUNTER_QNAME(qh, qh );
121 while ( qh != NULL )
122 {
123 PR_INIT_COUNTER_HANDLE( rh, NULL );
124 PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
125 while ( rh != NULL )
126 {
127 PR_GET_COUNTER_NAME_FROM_HANDLE( rh, qname, rname, desc );
128 tCtr = PR_GET_COUNTER(tCtr, rh);
129 PR_LOG( lm, msgLevel,
130 ( "QName: %s RName: %s Desc: %s Value: %ld\n",
131 qn, rn, dn, tCtr ));
132 PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh );
133 }
134 PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
135 }
136 return;
137} /* end ListCounters() */
138
139static void ListTraces(void)
140{
141 PR_DEFINE_TRACE( qh );
142 PR_DEFINE_TRACE( rh );
143 const char *qn, *rn, *dn;
144 const char **qname = &qn, **rname = &rn, **desc = &dn;
145
146 PR_INIT_TRACE_HANDLE( qh, NULL );
147 PR_FIND_NEXT_TRACE_QNAME(qh, qh );
148 while ( qh != NULL )
149 {
150 PR_INIT_TRACE_HANDLE( rh, NULL );
151 PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
152 while ( rh != NULL )
153 {
154 PR_GET_TRACE_NAME_FROM_HANDLE( rh, qname, rname, desc );
155 PR_LOG( lm, msgLevel,
156 ( "QName: %s RName: %s Desc: %s",
157 qn, rn, dn ));
158 PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh );
159 }
160 PR_FIND_NEXT_TRACE_QNAME(qh, qh);
161 }
162 return;
163} /* end ListCounters() */
164
165
166static PRInt32 one = 1;
167static PRInt32 two = 2;
168static PRInt32 three = 3;
169static PRInt32 four = 4;
170
171/*
172** Thread to iteratively count something.
173*/
174static void PR_CALLBACK CountSomething( void *arg )
175{
176 PRInt32 switchVar = *((PRInt32 *)arg);
177 PRInt32 i;
178
179 PR_LOG( lm, msgLevel,
180 ("CountSomething: begin thread %ld", switchVar ));
181
182 for ( i = 0; i < COUNT_LIMIT ; i++)
183 {
184 switch ( switchVar )
185 {
186 case 1 :
187 PR_INCREMENT_COUNTER( hCounter );
188 break;
189 case 2 :
190 PR_DECREMENT_COUNTER( hCounter );
191 break;
192 case 3 :
193 PR_ADD_TO_COUNTER( hCounter, 1 );
194 break;
195 case 4 :
196 PR_SUBTRACT_FROM_COUNTER( hCounter, 1 );
197 break;
198 default :
199 PR_ASSERT( 0 );
200 break;
201 }
202 PR_TRACE( hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0 );
203 } /* end for() */
204
205 PR_LOG( lm, msgLevel,
206 ("CounterSomething: end thread %ld", switchVar ));
207
208 PR_EnterMonitor(mon);
209 --activeThreads;
210 PR_Notify( mon );
211 PR_ExitMonitor(mon);
212
213 return;
214} /* end CountSomething() */
215
216/*
217** Create the counter threads.
218*/
219static void CounterTest( void )
220{
221 PRThread *t1, *t2, *t3, *t4;
222 PRIntn i = 0;
223 PR_DEFINE_COUNTER( tc );
224 PR_DEFINE_COUNTER( zCounter );
225
226 PR_LOG( lm, msgLevel,
227 ("Begin CounterTest"));
228
229 /*
230 ** Test Get and Set of a counter.
231 **
232 */
233 PR_CREATE_COUNTER( zCounter, "Atomic", "get/set test", "test get and set of counter" );
234 PR_SET_COUNTER( zCounter, 9 );
235 PR_GET_COUNTER( i, zCounter );
236 if ( i != 9 )
237 {
238 failed = PR_TRUE;
239 PR_LOG( lm, msgLevel,
240 ("Counter set/get failed"));
241 }
242
243 activeThreads += 4;
244 PR_CREATE_COUNTER( hCounter, "Atomic", "SMP Tests", "test atomic nature of counter" );
245
246 PR_GET_COUNTER_HANDLE_FROM_NAME( tc, "Atomic", "SMP Tests" );
247 PR_ASSERT( tc == hCounter );
248
249 t1 = PR_CreateThread(PR_USER_THREAD,
250 CountSomething, &one,
251 PR_PRIORITY_NORMAL,
252 PR_GLOBAL_THREAD,
253 PR_UNJOINABLE_THREAD,
254 0);
255 PR_ASSERT(t1);
256
257 t2 = PR_CreateThread(PR_USER_THREAD,
258 CountSomething, &two,
259 PR_PRIORITY_NORMAL,
260 PR_GLOBAL_THREAD,
261 PR_UNJOINABLE_THREAD,
262 0);
263 PR_ASSERT(t2);
264
265 t3 = PR_CreateThread(PR_USER_THREAD,
266 CountSomething, &three,
267 PR_PRIORITY_NORMAL,
268 PR_GLOBAL_THREAD,
269 PR_UNJOINABLE_THREAD,
270 0);
271 PR_ASSERT(t3);
272
273 t4 = PR_CreateThread(PR_USER_THREAD,
274 CountSomething, &four,
275 PR_PRIORITY_NORMAL,
276 PR_GLOBAL_THREAD,
277 PR_UNJOINABLE_THREAD,
278 0);
279 PR_ASSERT(t4);
280
281 PR_LOG( lm, msgLevel,
282 ("Counter Threads started"));
283
284 ListCounters();
285 return;
286} /* end CounterTest() */
287
288/*
289** Thread to dump trace buffer to a file.
290*/
291static void PR_CALLBACK RecordTrace(void *arg )
292{
293 PR_RECORD_TRACE_ENTRIES();
294
295 PR_EnterMonitor(mon);
296 --activeThreads;
297 PR_Notify( mon );
298 PR_ExitMonitor(mon);
299
300 return;
301} /* end RecordTrace() */
302
303
304
305#define NUM_TRACE_RECORDS ( 10000 )
306/*
307** Thread to extract and print trace entries from the buffer.
308*/
309static void PR_CALLBACK SampleTrace( void *arg )
310{
311#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
312 PRInt32 found, rc;
313 PRTraceEntry *foundEntries;
314 PRInt32 i;
315
316 foundEntries = (PRTraceEntry *)PR_Malloc( NUM_TRACE_RECORDS * sizeof(PRTraceEntry));
317 PR_ASSERT(foundEntries != NULL );
318
319 do
320 {
321 rc = PR_GetTraceEntries( foundEntries, NUM_TRACE_RECORDS, &found);
322 PR_LOG( lm, msgLevel,
323 ("SampleTrace: Lost Data: %ld found: %ld", rc, found ));
324
325 if ( found != 0)
326 {
327 for ( i = 0 ; i < found; i++ )
328 {
329 PR_LOG( lm, msgLevel,
330 ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, UD2: %8.8ld",
331 (foundEntries +i)->thread,
332 (foundEntries +i)->time,
333 (foundEntries +i)->userData[0],
334 (foundEntries +i)->userData[1],
335 (foundEntries +i)->userData[2] ));
336 }
337 }
338 PR_Sleep(PR_MillisecondsToInterval(50));
339 }
340 while( found != 0 && activeThreads >= 1 );
341
342 PR_Free( foundEntries );
343
344 PR_EnterMonitor(mon);
345 --activeThreads;
346 PR_Notify( mon );
347 PR_ExitMonitor(mon);
348
349 PR_LOG( lm, msgLevel,
350 ("SampleTrace(): exiting"));
351
352#endif
353 return;
354} /* end RecordTrace() */
355
356/*
357** Basic trace test.
358*/
359static void TraceTest( void )
360{
361 PRInt32 i;
362 PRInt32 size;
363 PR_DEFINE_TRACE( th );
364 PRThread *t1, *t2;
365
366 PR_LOG( lm, msgLevel,
367 ("Begin TraceTest"));
368
369 size = SMALL_TRACE_BUFSIZE;
370 PR_SET_TRACE_OPTION( PRTraceBufSize, &size );
371 PR_GET_TRACE_OPTION( PRTraceBufSize, &i );
372
373 PR_CREATE_TRACE( th, "TraceTest", "tt2", "A description for the trace test" );
374 PR_CREATE_TRACE( th, "TraceTest", "tt3", "A description for the trace test" );
375 PR_CREATE_TRACE( th, "TraceTest", "tt4", "A description for the trace test" );
376 PR_CREATE_TRACE( th, "TraceTest", "tt5", "A description for the trace test" );
377 PR_CREATE_TRACE( th, "TraceTest", "tt6", "A description for the trace test" );
378 PR_CREATE_TRACE( th, "TraceTest", "tt7", "A description for the trace test" );
379 PR_CREATE_TRACE( th, "TraceTest", "tt8", "A description for the trace test" );
380
381 PR_CREATE_TRACE( th, "Trace Test", "tt0", "QName is Trace Test, not TraceTest" );
382 PR_CREATE_TRACE( th, "Trace Test", "tt1", "QName is Trace Test, not TraceTest" );
383 PR_CREATE_TRACE( th, "Trace Test", "tt2", "QName is Trace Test, not TraceTest" );
384 PR_CREATE_TRACE( th, "Trace Test", "tt3", "QName is Trace Test, not TraceTest" );
385 PR_CREATE_TRACE( th, "Trace Test", "tt4", "QName is Trace Test, not TraceTest" );
386 PR_CREATE_TRACE( th, "Trace Test", "tt5", "QName is Trace Test, not TraceTest" );
387 PR_CREATE_TRACE( th, "Trace Test", "tt6", "QName is Trace Test, not TraceTest" );
388 PR_CREATE_TRACE( th, "Trace Test", "tt7", "QName is Trace Test, not TraceTest" );
389 PR_CREATE_TRACE( th, "Trace Test", "tt8", "QName is Trace Test, not TraceTest" );
390 PR_CREATE_TRACE( th, "Trace Test", "tt9", "QName is Trace Test, not TraceTest" );
391 PR_CREATE_TRACE( th, "Trace Test", "tt10", "QName is Trace Test, not TraceTest" );
392
393
394
395 activeThreads += 2;
396 t1 = PR_CreateThread(PR_USER_THREAD,
397 RecordTrace, NULL,
398 PR_PRIORITY_NORMAL,
399 PR_GLOBAL_THREAD,
400 PR_UNJOINABLE_THREAD,
401 0);
402 PR_ASSERT(t1);
403
404 t2 = PR_CreateThread(PR_USER_THREAD,
405 SampleTrace, 0,
406 PR_PRIORITY_NORMAL,
407 PR_GLOBAL_THREAD,
408 PR_UNJOINABLE_THREAD,
409 0);
410 PR_ASSERT(t2);
411
412 ListTraces();
413
414 PR_GET_TRACE_HANDLE_FROM_NAME( th, "TraceTest","tt1" );
415 PR_ASSERT( th == hTrace );
416
417 PR_LOG( lm, msgLevel,
418 ("End TraceTest"));
419 return;
420} /* end TraceTest() */
421
422
423/*
424** Ordered lock test.
425*/
426static void OrderedLockTest( void )
427{
428 PR_LOG( lm, msgLevel,
429 ("Begin OrderedLockTest"));
430
431
432} /* end OrderedLockTest() */
433
434
435PRIntn main(PRIntn argc, char *argv[])
436{
437#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
438 PRUint32 counter;
439 PLOptStatus os;
440 PLOptState *opt = PL_CreateOptState(argc, argv, "hdv:");
441 lm = PR_NewLogModule("Test");
442
443 while (PL_OPT_EOL != (os = PL_GetNextOpt(opt)))
444 {
445 if (PL_OPT_BAD == os) continue;
446 switch (opt->option)
447 {
448 case 'v': /* verbose mode */
449 msgLevel = (PRLogModuleLevel)atol( opt->value);
450 break;
451 case 'h': /* help message */
452 Help();
453 help = PR_TRUE;
454 break;
455 default:
456 break;
457 }
458 }
459 PL_DestroyOptState(opt);
460
461 PR_CREATE_TRACE( hTrace, "TraceTest", "tt1", "A description for the trace test" );
462 mon = PR_NewMonitor();
463 PR_EnterMonitor( mon );
464
465 TraceTest();
466 CounterTest();
467 OrderedLockTest();
468
469 /* Wait for all threads to exit */
470 while ( activeThreads > 0 ) {
471 if ( activeThreads == 1 )
472 PR_SET_TRACE_OPTION( PRTraceStopRecording, NULL );
473 PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
474 PR_GET_COUNTER( counter, hCounter );
475 }
476 PR_ExitMonitor( mon );
477
478 /*
479 ** Evaluate results
480 */
481 PR_GET_COUNTER( counter, hCounter );
482 if ( counter != 0 )
483 {
484 failed = PR_TRUE;
485 PR_LOG( lm, msgLevel,
486 ("Expected counter == 0, found: %ld", counter));
487 printf("FAIL\n");
488 }
489 else
490 {
491 printf("PASS\n");
492 }
493
494
495 PR_DESTROY_COUNTER( hCounter );
496
497 PR_DestroyMonitor( mon );
498
499 PR_TRACE( hTrace, TraceFlow, 0xfff,0,0,0,0,0,0);
500 PR_DESTROY_TRACE( hTrace );
501#else
502 printf("Test not defined\n");
503#endif
504 return 0;
505} /* main() */
506/* end instrumt.c */
507
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

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