Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(147)

Side by Side Diff: nspr/pr/src/misc/prtrace.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « nspr/pr/src/misc/prtpool.c ('k') | nspr/pr/src/pthreads/ptio.c » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 ** prtrace.c -- NSPR Trace Instrumentation
8 **
9 ** Implement the API defined in prtrace.h
10 **
11 **
12 **
13 */
14
15 #include <string.h>
16 #include "primpl.h"
17
18
19 #define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 )
20 #define DEFAULT_BUFFER_SEGMENTS 2
21
22 /*
23 ** Enumerate states in a RName structure
24 */
25 typedef enum TraceState
26 {
27 Running = 1,
28 Suspended = 2
29 } TraceState;
30
31 /*
32 ** Define QName structure
33 */
34 typedef struct QName
35 {
36 PRCList link;
37 PRCList rNameList;
38 char name[PRTRACE_NAME_MAX+1];
39 } QName;
40
41 /*
42 ** Define RName structure
43 */
44 typedef struct RName
45 {
46 PRCList link;
47 PRLock *lock;
48 QName *qName;
49 TraceState state;
50 char name[PRTRACE_NAME_MAX+1];
51 char desc[PRTRACE_DESC_MAX+1];
52 } RName;
53
54
55 /*
56 ** The Trace Facility database
57 **
58 */
59 static PRLogModuleInfo *lm;
60
61 static PRLock *traceLock; /* Facility Lock */
62 static PRCList qNameList; /* anchor to all QName structures */
63 static TraceState traceState = Running;
64
65 /*
66 ** in-memory trace buffer controls
67 */
68 static PRTraceEntry *tBuf; /* pointer to buffer */
69 static PRInt32 bufSize; /* size of buffer, in bytes, rounded up to s izeof(PRTraceEntry) */
70 static volatile PRInt32 next; /* index to next PRTraceEntry */
71 static PRInt32 last; /* index of highest numbered trace entry */
72
73 /*
74 ** Real-time buffer capture controls
75 */
76 static PRInt32 fetchLastSeen = 0;
77 static PRBool fetchLostData = PR_FALSE;
78
79 /*
80 ** Buffer write-to-file controls
81 */
82 static PRLock *logLock; /* Sync lock */
83 static PRCondVar *logCVar; /* Sync Condidtion Variable */
84 /*
85 ** Inter-thread state communication.
86 ** Controling thread writes to logOrder under protection of logCVar
87 ** the logging thread reads logOrder and sets logState on Notify.
88 **
89 ** logSegments, logCount, logLostData must be read and written under
90 ** protection of logLock, logCVar.
91 **
92 */
93 static enum LogState
94 {
95 LogNotRunning, /* Initial state */
96 LogReset, /* Causes logger to re-calc controls */
97 LogActive, /* Logging in progress, set only by log thread */
98 LogSuspend, /* Suspend Logging */
99 LogResume, /* Resume Logging => LogActive */
100 LogStop /* Stop the log thread */
101 } logOrder, logState, localState; /* controlling state variables */
102 static PRInt32 logSegments; /* Number of buffer segments */
103 static PRInt32 logEntries; /* number of Trace Entries in the bu ffer */
104 static PRInt32 logEntriesPerSegment; /* number of PRTraceEntries per buff er segment */
105 static PRInt32 logSegSize; /* size of buffer segment */
106 static PRInt32 logCount; /* number of segments pending output */
107 static PRInt32 logLostData; /* number of lost log buffer segment s */
108
109 /*
110 ** end Trace Database
111 **
112 */
113
114 /*
115 ** _PR_InitializeTrace() -- Initialize the trace facility
116 */
117 static void NewTraceBuffer( PRInt32 size )
118 {
119 /*
120 ** calculate the size of the buffer
121 ** round down so that each segment has the same number of
122 ** trace entries
123 */
124 logSegments = DEFAULT_BUFFER_SEGMENTS;
125 logEntries = size / sizeof(PRTraceEntry);
126 logEntriesPerSegment = logEntries / logSegments;
127 logEntries = logSegments * logEntriesPerSegment;
128 bufSize = logEntries * sizeof(PRTraceEntry);
129 logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry);
130 PR_ASSERT( bufSize != 0);
131 PR_LOG( lm, PR_LOG_ERROR,
132 ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegmen t: %ld, logSegSize: %ld",
133 logSegments, logEntries, logEntriesPerSegment, logSegSize ));
134
135
136 tBuf = PR_Malloc( bufSize );
137 if ( tBuf == NULL )
138 {
139 PR_LOG( lm, PR_LOG_ERROR,
140 ("PRTrace: Failed to get trace buffer"));
141 PR_ASSERT( 0 );
142 }
143 else
144 {
145 PR_LOG( lm, PR_LOG_NOTICE,
146 ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf));
147 }
148
149 next = 0;
150 last = logEntries -1;
151 logCount = 0;
152 logLostData = PR_TRUE; /* not really on first call */
153 logOrder = LogReset;
154
155 } /* end NewTraceBuffer() */
156
157 /*
158 ** _PR_InitializeTrace() -- Initialize the trace facility
159 */
160 static void _PR_InitializeTrace( void )
161 {
162 /* The lock pointer better be null on this call */
163 PR_ASSERT( traceLock == NULL );
164
165 traceLock = PR_NewLock();
166 PR_ASSERT( traceLock != NULL );
167
168 PR_Lock( traceLock );
169
170 PR_INIT_CLIST( &qNameList );
171
172 lm = PR_NewLogModule("trace");
173
174 bufSize = DEFAULT_TRACE_BUFSIZE;
175 NewTraceBuffer( bufSize );
176
177 /* Initialize logging controls */
178 logLock = PR_NewLock();
179 logCVar = PR_NewCondVar( logLock );
180
181 PR_Unlock( traceLock );
182 return;
183 } /* end _PR_InitializeTrace() */
184
185 /*
186 ** Create a Trace Handle
187 */
188 PR_IMPLEMENT(PRTraceHandle)
189 PR_CreateTrace(
190 const char *qName, /* QName for this trace handle */
191 const char *rName, /* RName for this trace handle */
192 const char *description /* description for this trace handle */
193 )
194 {
195 QName *qnp;
196 RName *rnp;
197 PRBool matchQname = PR_FALSE;
198
199 /* Self initialize, if necessary */
200 if ( traceLock == NULL )
201 _PR_InitializeTrace();
202
203 /* Validate input arguments */
204 PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX );
205 PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX );
206 PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX );
207
208 PR_LOG( lm, PR_LOG_DEBUG,
209 ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName));
210
211 /* Lock the Facility */
212 PR_Lock( traceLock );
213
214 /* Do we already have a matching QName? */
215 if (!PR_CLIST_IS_EMPTY( &qNameList ))
216 {
217 qnp = (QName *) PR_LIST_HEAD( &qNameList );
218 do {
219 if ( strcmp(qnp->name, qName) == 0)
220 {
221 matchQname = PR_TRUE;
222 break;
223 }
224 qnp = (QName *)PR_NEXT_LINK( &qnp->link );
225 } while( qnp != (QName *)&qNameList );
226 }
227 /*
228 ** If we did not find a matching QName,
229 ** allocate one and initialize it.
230 ** link it onto the qNameList.
231 **
232 */
233 if ( matchQname != PR_TRUE )
234 {
235 qnp = PR_NEWZAP( QName );
236 PR_ASSERT( qnp != NULL );
237 PR_INIT_CLIST( &qnp->link );
238 PR_INIT_CLIST( &qnp->rNameList );
239 strcpy( qnp->name, qName );
240 PR_APPEND_LINK( &qnp->link, &qNameList );
241 }
242
243 /* Do we already have a matching RName? */
244 if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
245 {
246 rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
247 do {
248 /*
249 ** No duplicate RNames are allowed within a QName
250 **
251 */
252 PR_ASSERT( strcmp(rnp->name, rName));
253 rnp = (RName *)PR_NEXT_LINK( &rnp->link );
254 } while( rnp != (RName *)&qnp->rNameList );
255 }
256
257 /* Get a new RName structure; initialize its members */
258 rnp = PR_NEWZAP( RName );
259 PR_ASSERT( rnp != NULL );
260 PR_INIT_CLIST( &rnp->link );
261 strcpy( rnp->name, rName );
262 strcpy( rnp->desc, description );
263 rnp->lock = PR_NewLock();
264 rnp->state = Running;
265 if ( rnp->lock == NULL )
266 {
267 PR_ASSERT(0);
268 }
269
270 PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnLis t */
271 rnp->qName = qnp; /* point the RName to the QName */
272
273 /* Unlock the Facility */
274 PR_Unlock( traceLock );
275 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t" ,
276 qName, qnp, rName, rnp ));
277
278 return((PRTraceHandle)rnp);
279 } /* end PR_CreateTrace() */
280
281 /*
282 **
283 */
284 PR_IMPLEMENT(void)
285 PR_DestroyTrace(
286 PRTraceHandle handle /* Handle to be destroyed */
287 )
288 {
289 RName *rnp = (RName *)handle;
290 QName *qnp = rnp->qName;
291
292 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s",
293 qnp->name, rnp->name));
294
295 /* Lock the Facility */
296 PR_Lock( traceLock );
297
298 /*
299 ** Remove RName from the list of RNames in QName
300 ** and free RName
301 */
302 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p",
303 rnp->name, rnp));
304 PR_REMOVE_LINK( &rnp->link );
305 PR_Free( rnp->lock );
306 PR_DELETE( rnp );
307
308 /*
309 ** If this is the last RName within QName
310 ** remove QName from the qNameList and free it
311 */
312 if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
313 {
314 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p",
315 qnp->name, qnp));
316 PR_REMOVE_LINK( &qnp->link );
317 PR_DELETE( qnp );
318 }
319
320 /* Unlock the Facility */
321 PR_Unlock( traceLock );
322 return;
323 } /* end PR_DestroyTrace() */
324
325 /*
326 ** Create a TraceEntry in the trace buffer
327 */
328 PR_IMPLEMENT(void)
329 PR_Trace(
330 PRTraceHandle handle, /* use this trace handle */
331 PRUint32 userData0, /* User supplied data word 0 */
332 PRUint32 userData1, /* User supplied data word 1 */
333 PRUint32 userData2, /* User supplied data word 2 */
334 PRUint32 userData3, /* User supplied data word 3 */
335 PRUint32 userData4, /* User supplied data word 4 */
336 PRUint32 userData5, /* User supplied data word 5 */
337 PRUint32 userData6, /* User supplied data word 6 */
338 PRUint32 userData7 /* User supplied data word 7 */
339 )
340 {
341 PRTraceEntry *tep;
342 PRInt32 mark;
343
344 if ( (traceState == Suspended )
345 || ( ((RName *)handle)->state == Suspended ))
346 return;
347
348 /*
349 ** Get the next trace entry slot w/ minimum delay
350 */
351 PR_Lock( traceLock );
352
353 tep = &tBuf[next++];
354 if ( next > last )
355 next = 0;
356 if ( fetchLostData == PR_FALSE && next == fetchLastSeen )
357 fetchLostData = PR_TRUE;
358
359 mark = next;
360
361 PR_Unlock( traceLock );
362
363 /*
364 ** We have a trace entry. Fill it in.
365 */
366 tep->thread = PR_GetCurrentThread();
367 tep->handle = handle;
368 tep->time = PR_Now();
369 tep->userData[0] = userData0;
370 tep->userData[1] = userData1;
371 tep->userData[2] = userData2;
372 tep->userData[3] = userData3;
373 tep->userData[4] = userData4;
374 tep->userData[5] = userData5;
375 tep->userData[6] = userData6;
376 tep->userData[7] = userData7;
377
378 /* When buffer segment is full, signal trace log thread to run */
379 if (( mark % logEntriesPerSegment) == 0 )
380 {
381 PR_Lock( logLock );
382 logCount++;
383 PR_NotifyCondVar( logCVar );
384 PR_Unlock( logLock );
385 /*
386 ** Gh0D! This is awful!
387 ** Anyway, to minimize lost trace data segments,
388 ** I inserted the PR_Sleep(0) to cause a context switch
389 ** so that the log thread could run.
390 ** I know, it perturbs the universe and may cause
391 ** funny things to happen in the optimized builds.
392 ** Take it out, lose data; leave it in risk Heisenberg.
393 */
394 /* PR_Sleep(0); */
395 }
396
397 return;
398 } /* end PR_Trace() */
399
400 /*
401 **
402 */
403 PR_IMPLEMENT(void)
404 PR_SetTraceOption(
405 PRTraceOption command, /* One of the enumerated values */
406 void *value /* command value or NULL */
407 )
408 {
409 RName * rnp;
410
411 switch ( command )
412 {
413 case PRTraceBufSize :
414 PR_Lock( traceLock );
415 PR_Free( tBuf );
416 bufSize = *(PRInt32 *)value;
417 NewTraceBuffer( bufSize );
418 PR_Unlock( traceLock );
419 PR_LOG( lm, PR_LOG_DEBUG,
420 ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize));
421 break;
422
423 case PRTraceEnable :
424 rnp = *(RName **)value;
425 rnp->state = Running;
426 PR_LOG( lm, PR_LOG_DEBUG,
427 ("PRSetTraceOption: PRTraceEnable: %p", rnp));
428 break;
429
430 case PRTraceDisable :
431 rnp = *(RName **)value;
432 rnp->state = Suspended;
433 PR_LOG( lm, PR_LOG_DEBUG,
434 ("PRSetTraceOption: PRTraceDisable: %p", rnp));
435 break;
436
437 case PRTraceSuspend :
438 traceState = Suspended;
439 PR_LOG( lm, PR_LOG_DEBUG,
440 ("PRSetTraceOption: PRTraceSuspend"));
441 break;
442
443 case PRTraceResume :
444 traceState = Running;
445 PR_LOG( lm, PR_LOG_DEBUG,
446 ("PRSetTraceOption: PRTraceResume"));
447 break;
448
449 case PRTraceSuspendRecording :
450 PR_Lock( logLock );
451 logOrder = LogSuspend;
452 PR_NotifyCondVar( logCVar );
453 PR_Unlock( logLock );
454 PR_LOG( lm, PR_LOG_DEBUG,
455 ("PRSetTraceOption: PRTraceSuspendRecording"));
456 break;
457
458 case PRTraceResumeRecording :
459 PR_LOG( lm, PR_LOG_DEBUG,
460 ("PRSetTraceOption: PRTraceResumeRecording"));
461 if ( logState != LogSuspend )
462 break;
463 PR_Lock( logLock );
464 logOrder = LogResume;
465 PR_NotifyCondVar( logCVar );
466 PR_Unlock( logLock );
467 break;
468
469 case PRTraceStopRecording :
470 PR_Lock( logLock );
471 logOrder = LogStop;
472 PR_NotifyCondVar( logCVar );
473 PR_Unlock( logLock );
474 PR_LOG( lm, PR_LOG_DEBUG,
475 ("PRSetTraceOption: PRTraceStopRecording"));
476 break;
477
478 case PRTraceLockHandles :
479 PR_LOG( lm, PR_LOG_DEBUG,
480 ("PRSetTraceOption: PRTraceLockTraceHandles"));
481 PR_Lock( traceLock );
482 break;
483
484 case PRTraceUnLockHandles :
485 PR_LOG( lm, PR_LOG_DEBUG,
486 ("PRSetTraceOption: PRTraceUnLockHandles"));
487 PR_Unlock( traceLock );
488 break;
489
490 default:
491 PR_LOG( lm, PR_LOG_ERROR,
492 ("PRSetTraceOption: Invalid command %ld", command ));
493 PR_ASSERT( 0 );
494 break;
495 } /* end switch() */
496 return;
497 } /* end PR_SetTraceOption() */
498
499 /*
500 **
501 */
502 PR_IMPLEMENT(void)
503 PR_GetTraceOption(
504 PRTraceOption command, /* One of the enumerated values */
505 void *value /* command value or NULL */
506 )
507 {
508 switch ( command )
509 {
510 case PRTraceBufSize :
511 *((PRInt32 *)value) = bufSize;
512 PR_LOG( lm, PR_LOG_DEBUG,
513 ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize ));
514 break;
515
516 default:
517 PR_LOG( lm, PR_LOG_ERROR,
518 ("PRGetTraceOption: Invalid command %ld", command ));
519 PR_ASSERT( 0 );
520 break;
521 } /* end switch() */
522 return;
523 } /* end PR_GetTraceOption() */
524
525 /*
526 **
527 */
528 PR_IMPLEMENT(PRTraceHandle)
529 PR_GetTraceHandleFromName(
530 const char *qName, /* QName search argument */
531 const char *rName /* RName search argument */
532 )
533 {
534 const char *qn, *rn, *desc;
535 PRTraceHandle qh, rh = NULL;
536 RName *rnp = NULL;
537
538 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t"
539 "QName: %s, RName: %s", qName, rName ));
540
541 qh = PR_FindNextTraceQname( NULL );
542 while (qh != NULL)
543 {
544 rh = PR_FindNextTraceRname( NULL, qh );
545 while ( rh != NULL )
546 {
547 PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc );
548 if ( (strcmp( qName, qn ) == 0)
549 && (strcmp( rName, rn ) == 0 ))
550 {
551 rnp = (RName *)rh;
552 goto foundIt;
553 }
554 rh = PR_FindNextTraceRname( rh, qh );
555 }
556 qh = PR_FindNextTraceQname( NULL );
557 }
558
559 foundIt:
560 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )) ;
561 return(rh);
562 } /* end PR_GetTraceHandleFromName() */
563
564 /*
565 **
566 */
567 PR_IMPLEMENT(void)
568 PR_GetTraceNameFromHandle(
569 PRTraceHandle handle, /* handle as search argument */
570 const char **qName, /* pointer to associated QName */
571 const char **rName, /* pointer to associated RName */
572 const char **description /* pointer to associated description */
573 )
574 {
575 RName *rnp = (RName *)handle;
576 QName *qnp = rnp->qName;
577
578 *qName = qnp->name;
579 *rName = rnp->name;
580 *description = rnp->desc;
581
582 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: "
583 "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s",
584 qnp, rnp, qnp->name, rnp->name, rnp->desc ));
585
586 return;
587 } /* end PR_GetTraceNameFromHandle() */
588
589 /*
590 **
591 */
592 PR_IMPLEMENT(PRTraceHandle)
593 PR_FindNextTraceQname(
594 PRTraceHandle handle
595 )
596 {
597 QName *qnp = (QName *)handle;
598
599 if ( PR_CLIST_IS_EMPTY( &qNameList ))
600 qnp = NULL;
601 else if ( qnp == NULL )
602 qnp = (QName *)PR_LIST_HEAD( &qNameList );
603 else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList )
604 qnp = NULL;
605 else
606 qnp = (QName *)PR_NEXT_LINK( &qnp->link );
607
608 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p" ,
609 handle, qnp ));
610
611 return((PRTraceHandle)qnp);
612 } /* end PR_FindNextTraceQname() */
613
614 /*
615 **
616 */
617 PR_IMPLEMENT(PRTraceHandle)
618 PR_FindNextTraceRname(
619 PRTraceHandle rhandle,
620 PRTraceHandle qhandle
621 )
622 {
623 RName *rnp = (RName *)rhandle;
624 QName *qnp = (QName *)qhandle;
625
626
627 if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
628 rnp = NULL;
629 else if ( rnp == NULL )
630 rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
631 else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList )
632 rnp = NULL;
633 else
634 rnp = (RName *)PR_NEXT_LINK( &rnp->link );
635
636 PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p , Returns: %p",
637 rhandle, qhandle, rnp ));
638
639 return((PRTraceHandle)rnp);
640 } /* end PR_FindNextTraceRname() */
641
642 /*
643 **
644 */
645 static PRFileDesc * InitializeRecording( void )
646 {
647 char *logFileName;
648 PRFileDesc *logFile;
649
650 /* Self initialize, if necessary */
651 if ( traceLock == NULL )
652 _PR_InitializeTrace();
653
654 PR_LOG( lm, PR_LOG_DEBUG,
655 ("PR_RecordTraceEntries: begins"));
656
657 logLostData = 0; /* reset at entry */
658 logState = LogReset;
659
660 /* Get the filename for the logfile from the environment */
661 logFileName = PR_GetEnvSecure( "NSPR_TRACE_LOG" );
662 if ( logFileName == NULL )
663 {
664 PR_LOG( lm, PR_LOG_ERROR,
665 ("RecordTraceEntries: Environment variable not defined. Exiting"));
666 return NULL;
667 }
668
669 /* Open the logfile */
670 logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 );
671 if ( logFile == NULL )
672 {
673 PR_LOG( lm, PR_LOG_ERROR,
674 ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %l d",
675 logFileName, PR_GetOSError()));
676 return NULL;
677 }
678 return logFile;
679 } /* end InitializeRecording() */
680
681 /*
682 **
683 */
684 static void ProcessOrders( void )
685 {
686 switch ( logOrder )
687 {
688 case LogReset :
689 logOrder = logState = localState;
690 PR_LOG( lm, PR_LOG_DEBUG,
691 ("RecordTraceEntries: LogReset"));
692 break;
693
694 case LogSuspend :
695 localState = logOrder = logState = LogSuspend;
696 PR_LOG( lm, PR_LOG_DEBUG,
697 ("RecordTraceEntries: LogSuspend"));
698 break;
699
700 case LogResume :
701 localState = logOrder = logState = LogActive;
702 PR_LOG( lm, PR_LOG_DEBUG,
703 ("RecordTraceEntries: LogResume"));
704 break;
705
706 case LogStop :
707 logOrder = logState = LogStop;
708 PR_LOG( lm, PR_LOG_DEBUG,
709 ("RecordTraceEntries: LogStop"));
710 break;
711
712 default :
713 PR_LOG( lm, PR_LOG_ERROR,
714 ("RecordTraceEntries: Invalid logOrder: %ld", logOrder ));
715 PR_ASSERT( 0 );
716 break;
717 } /* end switch() */
718 return ;
719 } /* end ProcessOrders() */
720
721 /*
722 **
723 */
724 static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount )
725 {
726 PRInt32 rc;
727
728
729 PR_LOG( lm, PR_LOG_ERROR,
730 ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount));
731 rc = PR_Write( logFile, buf , amount );
732 if ( rc == -1 )
733 PR_LOG( lm, PR_LOG_ERROR,
734 ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() ));
735 else if ( rc != amount )
736 PR_LOG( lm, PR_LOG_ERROR,
737 ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", a mount, rc));
738 else
739 PR_LOG( lm, PR_LOG_DEBUG,
740 ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amou nt));
741
742 return;
743 } /* end WriteTraceSegment() */
744
745 /*
746 **
747 */
748 PR_IMPLEMENT(void)
749 PR_RecordTraceEntries(
750 void
751 )
752 {
753 PRFileDesc *logFile;
754 PRInt32 lostSegments;
755 PRInt32 currentSegment = 0;
756 void *buf;
757 PRBool doWrite;
758
759 logFile = InitializeRecording();
760 if ( logFile == NULL )
761 {
762 PR_LOG( lm, PR_LOG_DEBUG,
763 ("PR_RecordTraceEntries: Failed to initialize"));
764 return;
765 }
766
767 /* Do this until told to stop */
768 while ( logState != LogStop )
769 {
770
771 PR_Lock( logLock );
772
773 while ( (logCount == 0) && ( logOrder == logState ) )
774 PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT );
775
776 /* Handle state transitions */
777 if ( logOrder != logState )
778 ProcessOrders();
779
780 /* recalculate local controls */
781 if ( logCount )
782 {
783 lostSegments = logCount - logSegments;
784 if ( lostSegments > 0 )
785 {
786 logLostData += ( logCount - logSegments );
787 logCount = (logCount % logSegments);
788 currentSegment = logCount;
789 PR_LOG( lm, PR_LOG_DEBUG,
790 ("PR_RecordTraceEntries: LostData segments: %ld", logLostDat a));
791 }
792 else
793 {
794 logCount--;
795 }
796
797 buf = tBuf + ( logEntriesPerSegment * currentSegment );
798 if (++currentSegment >= logSegments )
799 currentSegment = 0;
800 doWrite = PR_TRUE;
801 }
802 else
803 doWrite = PR_FALSE;
804
805 PR_Unlock( logLock );
806
807 if ( doWrite == PR_TRUE )
808 {
809 if ( localState != LogSuspend )
810 WriteTraceSegment( logFile, buf, logSegSize );
811 else
812 PR_LOG( lm, PR_LOG_DEBUG,
813 ("RecordTraceEntries: PR_Write(): is suspended" ));
814 }
815
816 } /* end while(logState...) */
817
818 PR_Close( logFile );
819 PR_LOG( lm, PR_LOG_DEBUG,
820 ("RecordTraceEntries: exiting"));
821 return;
822 } /* end PR_RecordTraceEntries() */
823
824 /*
825 **
826 */
827 PR_IMPLEMENT(PRIntn)
828 PR_GetTraceEntries(
829 PRTraceEntry *buffer, /* where to write output */
830 PRInt32 count, /* number to get */
831 PRInt32 *found /* number you got */
832 )
833 {
834 PRInt32 rc;
835 PRInt32 copied = 0;
836
837 PR_Lock( traceLock );
838
839 /*
840 ** Depending on where the LastSeen and Next indices are,
841 ** copy the trace buffer in one or two pieces.
842 */
843 PR_LOG( lm, PR_LOG_ERROR,
844 ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen));
845
846 if ( fetchLastSeen <= next )
847 {
848 while (( count-- > 0 ) && (fetchLastSeen < next ))
849 {
850 *(buffer + copied++) = *(tBuf + fetchLastSeen++);
851 }
852 PR_LOG( lm, PR_LOG_ERROR,
853 ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLast Seen));
854 }
855 else /* copy in 2 parts */
856 {
857 while ( count-- > 0 && fetchLastSeen <= last )
858 {
859 *(buffer + copied++) = *(tBuf + fetchLastSeen++);
860 }
861 fetchLastSeen = 0;
862
863 PR_LOG( lm, PR_LOG_ERROR,
864 ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLast Seen));
865
866 while ( count-- > 0 && fetchLastSeen < next )
867 {
868 *(buffer + copied++) = *(tBuf + fetchLastSeen++);
869 }
870 PR_LOG( lm, PR_LOG_ERROR,
871 ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLast Seen));
872 }
873
874 *found = copied;
875 rc = ( fetchLostData == PR_TRUE )? 1 : 0;
876 fetchLostData = PR_FALSE;
877
878 PR_Unlock( traceLock );
879 return rc;
880 } /* end PR_GetTraceEntries() */
881
882 /* end prtrace.c */
OLDNEW
« no previous file with comments | « nspr/pr/src/misc/prtpool.c ('k') | nspr/pr/src/pthreads/ptio.c » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698