Index: mozilla/nsprpub/pr/src/misc/prtrace.c |
=================================================================== |
--- mozilla/nsprpub/pr/src/misc/prtrace.c (revision 191424) |
+++ mozilla/nsprpub/pr/src/misc/prtrace.c (working copy) |
@@ -1,888 +0,0 @@ |
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
-/* This Source Code Form is subject to the terms of the Mozilla Public |
- * License, v. 2.0. If a copy of the MPL was not distributed with this |
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
- |
-/* |
-** prtrace.c -- NSPR Trace Instrumentation |
-** |
-** Implement the API defined in prtrace.h |
-** |
-** |
-** |
-*/ |
- |
-#include <string.h> |
-#include "primpl.h" |
- |
- |
-#define DEFAULT_TRACE_BUFSIZE ( 1024 * 1024 ) |
-#define DEFAULT_BUFFER_SEGMENTS 2 |
- |
-/* |
-** Enumerate states in a RName structure |
-*/ |
-typedef enum TraceState |
-{ |
- Running = 1, |
- Suspended = 2 |
-} TraceState; |
- |
-/* |
-** Define QName structure |
-*/ |
-typedef struct QName |
-{ |
- PRCList link; |
- PRCList rNameList; |
- char name[PRTRACE_NAME_MAX+1]; |
-} QName; |
- |
-/* |
-** Define RName structure |
-*/ |
-typedef struct RName |
-{ |
- PRCList link; |
- PRLock *lock; |
- QName *qName; |
- TraceState state; |
- char name[PRTRACE_NAME_MAX+1]; |
- char desc[PRTRACE_DESC_MAX+1]; |
-} RName; |
- |
- |
-/* |
-** The Trace Facility database |
-** |
-*/ |
-static PRLogModuleInfo *lm; |
- |
-static PRLock *traceLock; /* Facility Lock */ |
-static PRCList qNameList; /* anchor to all QName structures */ |
-static TraceState traceState = Running; |
- |
-/* |
-** in-memory trace buffer controls |
-*/ |
-static PRTraceEntry *tBuf; /* pointer to buffer */ |
-static PRInt32 bufSize; /* size of buffer, in bytes, rounded up to sizeof(PRTraceEntry) */ |
-static volatile PRInt32 next; /* index to next PRTraceEntry */ |
-static PRInt32 last; /* index of highest numbered trace entry */ |
- |
-/* |
-** Real-time buffer capture controls |
-*/ |
-static PRInt32 fetchLastSeen = 0; |
-static PRBool fetchLostData = PR_FALSE; |
- |
-/* |
-** Buffer write-to-file controls |
-*/ |
-static PRLock *logLock; /* Sync lock */ |
-static PRCondVar *logCVar; /* Sync Condidtion Variable */ |
-/* |
-** Inter-thread state communication. |
-** Controling thread writes to logOrder under protection of logCVar |
-** the logging thread reads logOrder and sets logState on Notify. |
-** |
-** logSegments, logCount, logLostData must be read and written under |
-** protection of logLock, logCVar. |
-** |
-*/ |
-static enum LogState |
-{ |
- LogNotRunning, /* Initial state */ |
- LogReset, /* Causes logger to re-calc controls */ |
- LogActive, /* Logging in progress, set only by log thread */ |
- LogSuspend, /* Suspend Logging */ |
- LogResume, /* Resume Logging => LogActive */ |
- LogStop /* Stop the log thread */ |
-} logOrder, logState, localState; /* controlling state variables */ |
-static PRInt32 logSegments; /* Number of buffer segments */ |
-static PRInt32 logEntries; /* number of Trace Entries in the buffer */ |
-static PRInt32 logEntriesPerSegment; /* number of PRTraceEntries per buffer segment */ |
-static PRInt32 logSegSize; /* size of buffer segment */ |
-static PRInt32 logCount; /* number of segments pending output */ |
-static PRInt32 logLostData; /* number of lost log buffer segments */ |
- |
-/* |
-** end Trace Database |
-** |
-*/ |
- |
-/* |
-** _PR_InitializeTrace() -- Initialize the trace facility |
-*/ |
-static void NewTraceBuffer( PRInt32 size ) |
-{ |
- /* |
- ** calculate the size of the buffer |
- ** round down so that each segment has the same number of |
- ** trace entries |
- */ |
- logSegments = DEFAULT_BUFFER_SEGMENTS; |
- logEntries = size / sizeof(PRTraceEntry); |
- logEntriesPerSegment = logEntries / logSegments; |
- logEntries = logSegments * logEntriesPerSegment; |
- bufSize = logEntries * sizeof(PRTraceEntry); |
- logSegSize = logEntriesPerSegment * sizeof(PRTraceEntry); |
- PR_ASSERT( bufSize != 0); |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("NewTraceBuffer: logSegments: %ld, logEntries: %ld, logEntriesPerSegment: %ld, logSegSize: %ld", |
- logSegments, logEntries, logEntriesPerSegment, logSegSize )); |
- |
- |
- tBuf = PR_Malloc( bufSize ); |
- if ( tBuf == NULL ) |
- { |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PRTrace: Failed to get trace buffer")); |
- PR_ASSERT( 0 ); |
- } |
- else |
- { |
- PR_LOG( lm, PR_LOG_NOTICE, |
- ("PRTrace: Got trace buffer of size: %ld, at %p", bufSize, tBuf)); |
- } |
- |
- next = 0; |
- last = logEntries -1; |
- logCount = 0; |
- logLostData = PR_TRUE; /* not really on first call */ |
- logOrder = LogReset; |
- |
-} /* end NewTraceBuffer() */ |
- |
-/* |
-** _PR_InitializeTrace() -- Initialize the trace facility |
-*/ |
-static void _PR_InitializeTrace( void ) |
-{ |
- /* The lock pointer better be null on this call */ |
- PR_ASSERT( traceLock == NULL ); |
- |
- traceLock = PR_NewLock(); |
- PR_ASSERT( traceLock != NULL ); |
- |
- PR_Lock( traceLock ); |
- |
- PR_INIT_CLIST( &qNameList ); |
- |
- lm = PR_NewLogModule("trace"); |
- |
- bufSize = DEFAULT_TRACE_BUFSIZE; |
- NewTraceBuffer( bufSize ); |
- |
- /* Initialize logging controls */ |
- logLock = PR_NewLock(); |
- logCVar = PR_NewCondVar( logLock ); |
- |
- PR_Unlock( traceLock ); |
- return; |
-} /* end _PR_InitializeTrace() */ |
- |
-/* |
-** Create a Trace Handle |
-*/ |
-PR_IMPLEMENT(PRTraceHandle) |
- PR_CreateTrace( |
- const char *qName, /* QName for this trace handle */ |
- const char *rName, /* RName for this trace handle */ |
- const char *description /* description for this trace handle */ |
-) |
-{ |
- QName *qnp; |
- RName *rnp; |
- PRBool matchQname = PR_FALSE; |
- |
- /* Self initialize, if necessary */ |
- if ( traceLock == NULL ) |
- _PR_InitializeTrace(); |
- |
- /* Validate input arguments */ |
- PR_ASSERT( strlen(qName) <= PRTRACE_NAME_MAX ); |
- PR_ASSERT( strlen(rName) <= PRTRACE_NAME_MAX ); |
- PR_ASSERT( strlen(description) <= PRTRACE_DESC_MAX ); |
- |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRTRACE: CreateTrace: Qname: %s, RName: %s", qName, rName)); |
- |
- /* Lock the Facility */ |
- PR_Lock( traceLock ); |
- |
- /* Do we already have a matching QName? */ |
- if (!PR_CLIST_IS_EMPTY( &qNameList )) |
- { |
- qnp = (QName *) PR_LIST_HEAD( &qNameList ); |
- do { |
- if ( strcmp(qnp->name, qName) == 0) |
- { |
- matchQname = PR_TRUE; |
- break; |
- } |
- qnp = (QName *)PR_NEXT_LINK( &qnp->link ); |
- } while( qnp != (QName *)PR_LIST_HEAD( &qNameList )); |
- } |
- /* |
- ** If we did not find a matching QName, |
- ** allocate one and initialize it. |
- ** link it onto the qNameList. |
- ** |
- */ |
- if ( matchQname != PR_TRUE ) |
- { |
- qnp = PR_NEWZAP( QName ); |
- PR_ASSERT( qnp != NULL ); |
- PR_INIT_CLIST( &qnp->link ); |
- PR_INIT_CLIST( &qnp->rNameList ); |
- strcpy( qnp->name, qName ); |
- PR_APPEND_LINK( &qnp->link, &qNameList ); |
- } |
- |
- /* Do we already have a matching RName? */ |
- if (!PR_CLIST_IS_EMPTY( &qnp->rNameList )) |
- { |
- rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList ); |
- do { |
- /* |
- ** No duplicate RNames are allowed within a QName |
- ** |
- */ |
- PR_ASSERT( strcmp(rnp->name, rName)); |
- rnp = (RName *)PR_NEXT_LINK( &rnp->link ); |
- } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList )); |
- } |
- |
- /* Get a new RName structure; initialize its members */ |
- rnp = PR_NEWZAP( RName ); |
- PR_ASSERT( rnp != NULL ); |
- PR_INIT_CLIST( &rnp->link ); |
- strcpy( rnp->name, rName ); |
- strcpy( rnp->desc, description ); |
- rnp->lock = PR_NewLock(); |
- rnp->state = Running; |
- if ( rnp->lock == NULL ) |
- { |
- PR_ASSERT(0); |
- } |
- |
- PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */ |
- rnp->qName = qnp; /* point the RName to the QName */ |
- |
- /* Unlock the Facility */ |
- PR_Unlock( traceLock ); |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Create: QName: %s %p, RName: %s %p\n\t", |
- qName, qnp, rName, rnp )); |
- |
- return((PRTraceHandle)rnp); |
-} /* end PR_CreateTrace() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(void) |
- PR_DestroyTrace( |
- PRTraceHandle handle /* Handle to be destroyed */ |
-) |
-{ |
- RName *rnp = (RName *)handle; |
- QName *qnp = rnp->qName; |
- |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting: QName: %s, RName: %s", |
- qnp->name, rnp->name)); |
- |
- /* Lock the Facility */ |
- PR_Lock( traceLock ); |
- |
- /* |
- ** Remove RName from the list of RNames in QName |
- ** and free RName |
- */ |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting RName: %s, %p", |
- rnp->name, rnp)); |
- PR_REMOVE_LINK( &rnp->link ); |
- PR_Free( rnp->lock ); |
- PR_DELETE( rnp ); |
- |
- /* |
- ** If this is the last RName within QName |
- ** remove QName from the qNameList and free it |
- */ |
- if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) ) |
- { |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: Deleting unused QName: %s, %p", |
- qnp->name, qnp)); |
- PR_REMOVE_LINK( &qnp->link ); |
- PR_DELETE( qnp ); |
- } |
- |
- /* Unlock the Facility */ |
- PR_Unlock( traceLock ); |
- return; |
-} /* end PR_DestroyTrace() */ |
- |
-/* |
-** Create a TraceEntry in the trace buffer |
-*/ |
-PR_IMPLEMENT(void) |
- PR_Trace( |
- PRTraceHandle handle, /* use this trace handle */ |
- PRUint32 userData0, /* User supplied data word 0 */ |
- PRUint32 userData1, /* User supplied data word 1 */ |
- PRUint32 userData2, /* User supplied data word 2 */ |
- PRUint32 userData3, /* User supplied data word 3 */ |
- PRUint32 userData4, /* User supplied data word 4 */ |
- PRUint32 userData5, /* User supplied data word 5 */ |
- PRUint32 userData6, /* User supplied data word 6 */ |
- PRUint32 userData7 /* User supplied data word 7 */ |
-) |
-{ |
- PRTraceEntry *tep; |
- PRInt32 mark; |
- |
- if ( (traceState == Suspended ) |
- || ( ((RName *)handle)->state == Suspended )) |
- return; |
- |
- /* |
- ** Get the next trace entry slot w/ minimum delay |
- */ |
- PR_Lock( traceLock ); |
- |
- tep = &tBuf[next++]; |
- if ( next > last ) |
- next = 0; |
- if ( fetchLostData == PR_FALSE && next == fetchLastSeen ) |
- fetchLostData = PR_TRUE; |
- |
- mark = next; |
- |
- PR_Unlock( traceLock ); |
- |
- /* |
- ** We have a trace entry. Fill it in. |
- */ |
- tep->thread = PR_GetCurrentThread(); |
- tep->handle = handle; |
- tep->time = PR_Now(); |
- tep->userData[0] = userData0; |
- tep->userData[1] = userData1; |
- tep->userData[2] = userData2; |
- tep->userData[3] = userData3; |
- tep->userData[4] = userData4; |
- tep->userData[5] = userData5; |
- tep->userData[6] = userData6; |
- tep->userData[7] = userData7; |
- |
- /* When buffer segment is full, signal trace log thread to run */ |
- if (( mark % logEntriesPerSegment) == 0 ) |
- { |
- PR_Lock( logLock ); |
- logCount++; |
- PR_NotifyCondVar( logCVar ); |
- PR_Unlock( logLock ); |
- /* |
- ** Gh0D! This is awful! |
- ** Anyway, to minimize lost trace data segments, |
- ** I inserted the PR_Sleep(0) to cause a context switch |
- ** so that the log thread could run. |
- ** I know, it perturbs the universe and may cause |
- ** funny things to happen in the optimized builds. |
- ** Take it out, lose data; leave it in risk Heisenberg. |
- */ |
- /* PR_Sleep(0); */ |
- } |
- |
- return; |
-} /* end PR_Trace() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(void) |
- PR_SetTraceOption( |
- PRTraceOption command, /* One of the enumerated values */ |
- void *value /* command value or NULL */ |
-) |
-{ |
- RName * rnp; |
- |
- switch ( command ) |
- { |
- case PRTraceBufSize : |
- PR_Lock( traceLock ); |
- PR_Free( tBuf ); |
- bufSize = *(PRInt32 *)value; |
- NewTraceBuffer( bufSize ); |
- PR_Unlock( traceLock ); |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceBufSize: %ld", bufSize)); |
- break; |
- |
- case PRTraceEnable : |
- rnp = *(RName **)value; |
- rnp->state = Running; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceEnable: %p", rnp)); |
- break; |
- |
- case PRTraceDisable : |
- rnp = *(RName **)value; |
- rnp->state = Suspended; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceDisable: %p", rnp)); |
- break; |
- |
- case PRTraceSuspend : |
- traceState = Suspended; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceSuspend")); |
- break; |
- |
- case PRTraceResume : |
- traceState = Running; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceResume")); |
- break; |
- |
- case PRTraceSuspendRecording : |
- PR_Lock( logLock ); |
- logOrder = LogSuspend; |
- PR_NotifyCondVar( logCVar ); |
- PR_Unlock( logLock ); |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceSuspendRecording")); |
- break; |
- |
- case PRTraceResumeRecording : |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceResumeRecording")); |
- if ( logState != LogSuspend ) |
- break; |
- PR_Lock( logLock ); |
- logOrder = LogResume; |
- PR_NotifyCondVar( logCVar ); |
- PR_Unlock( logLock ); |
- break; |
- |
- case PRTraceStopRecording : |
- PR_Lock( logLock ); |
- logOrder = LogStop; |
- PR_NotifyCondVar( logCVar ); |
- PR_Unlock( logLock ); |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceStopRecording")); |
- break; |
- |
- case PRTraceLockHandles : |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceLockTraceHandles")); |
- PR_Lock( traceLock ); |
- break; |
- |
- case PRTraceUnLockHandles : |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRSetTraceOption: PRTraceUnLockHandles")); |
- PR_Unlock( traceLock ); |
- break; |
- |
- default: |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PRSetTraceOption: Invalid command %ld", command )); |
- PR_ASSERT( 0 ); |
- break; |
- } /* end switch() */ |
- return; |
-} /* end PR_SetTraceOption() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(void) |
- PR_GetTraceOption( |
- PRTraceOption command, /* One of the enumerated values */ |
- void *value /* command value or NULL */ |
-) |
-{ |
- switch ( command ) |
- { |
- case PRTraceBufSize : |
- *((PRInt32 *)value) = bufSize; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PRGetTraceOption: PRTraceBufSize: %ld", bufSize )); |
- break; |
- |
- default: |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PRGetTraceOption: Invalid command %ld", command )); |
- PR_ASSERT( 0 ); |
- break; |
- } /* end switch() */ |
- return; |
-} /* end PR_GetTraceOption() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(PRTraceHandle) |
- PR_GetTraceHandleFromName( |
- const char *qName, /* QName search argument */ |
- const char *rName /* RName search argument */ |
-) |
-{ |
- const char *qn, *rn, *desc; |
- PRTraceHandle qh, rh = NULL; |
- RName *rnp = NULL; |
- |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetTraceHandleFromName:\n\t" |
- "QName: %s, RName: %s", qName, rName )); |
- |
- qh = PR_FindNextTraceQname( NULL ); |
- while (qh != NULL) |
- { |
- rh = PR_FindNextTraceRname( NULL, qh ); |
- while ( rh != NULL ) |
- { |
- PR_GetTraceNameFromHandle( rh, &qn, &rn, &desc ); |
- if ( (strcmp( qName, qn ) == 0) |
- && (strcmp( rName, rn ) == 0 )) |
- { |
- rnp = (RName *)rh; |
- goto foundIt; |
- } |
- rh = PR_FindNextTraceRname( rh, qh ); |
- } |
- qh = PR_FindNextTraceQname( NULL ); |
- } |
- |
-foundIt: |
- PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp )); |
- return(rh); |
-} /* end PR_GetTraceHandleFromName() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(void) |
- PR_GetTraceNameFromHandle( |
- PRTraceHandle handle, /* handle as search argument */ |
- const char **qName, /* pointer to associated QName */ |
- const char **rName, /* pointer to associated RName */ |
- const char **description /* pointer to associated description */ |
-) |
-{ |
- RName *rnp = (RName *)handle; |
- QName *qnp = rnp->qName; |
- |
- *qName = qnp->name; |
- *rName = rnp->name; |
- *description = rnp->desc; |
- |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: GetConterNameFromHandle: " |
- "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", |
- qnp, rnp, qnp->name, rnp->name, rnp->desc )); |
- |
- return; |
-} /* end PR_GetTraceNameFromHandle() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(PRTraceHandle) |
- PR_FindNextTraceQname( |
- PRTraceHandle handle |
-) |
-{ |
- QName *qnp = (QName *)handle; |
- |
- if ( PR_CLIST_IS_EMPTY( &qNameList )) |
- qnp = NULL; |
- else if ( qnp == NULL ) |
- qnp = (QName *)PR_LIST_HEAD( &qNameList ); |
- else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList ) |
- qnp = NULL; |
- else |
- qnp = (QName *)PR_NEXT_LINK( &qnp->link ); |
- |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextQname: Handle: %p, Returns: %p", |
- handle, qnp )); |
- |
- return((PRTraceHandle)qnp); |
-} /* end PR_FindNextTraceQname() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(PRTraceHandle) |
- PR_FindNextTraceRname( |
- PRTraceHandle rhandle, |
- PRTraceHandle qhandle |
-) |
-{ |
- RName *rnp = (RName *)rhandle; |
- QName *qnp = (QName *)qhandle; |
- |
- |
- if ( PR_CLIST_IS_EMPTY( &qnp->rNameList )) |
- rnp = NULL; |
- else if ( rnp == NULL ) |
- rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList ); |
- else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList ) |
- rnp = NULL; |
- else |
- rnp = (RName *)PR_NEXT_LINK( &rnp->link ); |
- |
- PR_LOG( lm, PR_LOG_DEBUG, ("PRTrace: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", |
- rhandle, qhandle, rnp )); |
- |
- return((PRTraceHandle)rnp); |
-} /* end PR_FindNextTraceRname() */ |
- |
-/* |
-** |
-*/ |
-static PRFileDesc * InitializeRecording( void ) |
-{ |
- char *logFileName; |
- PRFileDesc *logFile; |
- |
- /* Self initialize, if necessary */ |
- if ( traceLock == NULL ) |
- _PR_InitializeTrace(); |
- |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PR_RecordTraceEntries: begins")); |
- |
- logLostData = 0; /* reset at entry */ |
- logState = LogReset; |
- |
-#ifdef XP_UNIX |
- if ((getuid() != geteuid()) || (getgid() != getegid())) { |
- return NULL; |
- } |
-#endif /* XP_UNIX */ |
- |
- /* Get the filename for the logfile from the environment */ |
- logFileName = PR_GetEnv( "NSPR_TRACE_LOG" ); |
- if ( logFileName == NULL ) |
- { |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("RecordTraceEntries: Environment variable not defined. Exiting")); |
- return NULL; |
- } |
- |
- /* Open the logfile */ |
- logFile = PR_Open( logFileName, PR_WRONLY | PR_CREATE_FILE, 0666 ); |
- if ( logFile == NULL ) |
- { |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("RecordTraceEntries: Cannot open %s as trace log file. OS error: %ld", |
- logFileName, PR_GetOSError())); |
- return NULL; |
- } |
- return logFile; |
-} /* end InitializeRecording() */ |
- |
-/* |
-** |
-*/ |
-static void ProcessOrders( void ) |
-{ |
- switch ( logOrder ) |
- { |
- case LogReset : |
- logOrder = logState = localState; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: LogReset")); |
- break; |
- |
- case LogSuspend : |
- localState = logOrder = logState = LogSuspend; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: LogSuspend")); |
- break; |
- |
- case LogResume : |
- localState = logOrder = logState = LogActive; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: LogResume")); |
- break; |
- |
- case LogStop : |
- logOrder = logState = LogStop; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: LogStop")); |
- break; |
- |
- default : |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("RecordTraceEntries: Invalid logOrder: %ld", logOrder )); |
- PR_ASSERT( 0 ); |
- break; |
- } /* end switch() */ |
- return ; |
-} /* end ProcessOrders() */ |
- |
-/* |
-** |
-*/ |
-static void WriteTraceSegment( PRFileDesc *logFile, void *buf, PRInt32 amount ) |
-{ |
- PRInt32 rc; |
- |
- |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("WriteTraceSegment: Buffer: %p, Amount: %ld", buf, amount)); |
- rc = PR_Write( logFile, buf , amount ); |
- if ( rc == -1 ) |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("RecordTraceEntries: PR_Write() failed. Error: %ld", PR_GetError() )); |
- else if ( rc != amount ) |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("RecordTraceEntries: PR_Write() Tried to write: %ld, Wrote: %ld", amount, rc)); |
- else |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: PR_Write(): Buffer: %p, bytes: %ld", buf, amount)); |
- |
- return; |
-} /* end WriteTraceSegment() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(void) |
- PR_RecordTraceEntries( |
- void |
-) |
-{ |
- PRFileDesc *logFile; |
- PRInt32 lostSegments; |
- PRInt32 currentSegment = 0; |
- void *buf; |
- PRBool doWrite; |
- |
- logFile = InitializeRecording(); |
- if ( logFile == NULL ) |
- { |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PR_RecordTraceEntries: Failed to initialize")); |
- return; |
- } |
- |
- /* Do this until told to stop */ |
- while ( logState != LogStop ) |
- { |
- |
- PR_Lock( logLock ); |
- |
- while ( (logCount == 0) && ( logOrder == logState ) ) |
- PR_WaitCondVar( logCVar, PR_INTERVAL_NO_TIMEOUT ); |
- |
- /* Handle state transitions */ |
- if ( logOrder != logState ) |
- ProcessOrders(); |
- |
- /* recalculate local controls */ |
- if ( logCount ) |
- { |
- lostSegments = logCount - logSegments; |
- if ( lostSegments > 0 ) |
- { |
- logLostData += ( logCount - logSegments ); |
- logCount = (logCount % logSegments); |
- currentSegment = logCount; |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("PR_RecordTraceEntries: LostData segments: %ld", logLostData)); |
- } |
- else |
- { |
- logCount--; |
- } |
- |
- buf = tBuf + ( logEntriesPerSegment * currentSegment ); |
- if (++currentSegment >= logSegments ) |
- currentSegment = 0; |
- doWrite = PR_TRUE; |
- } |
- else |
- doWrite = PR_FALSE; |
- |
- PR_Unlock( logLock ); |
- |
- if ( doWrite == PR_TRUE ) |
- { |
- if ( localState != LogSuspend ) |
- WriteTraceSegment( logFile, buf, logSegSize ); |
- else |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: PR_Write(): is suspended" )); |
- } |
- |
- } /* end while(logState...) */ |
- |
- PR_Close( logFile ); |
- PR_LOG( lm, PR_LOG_DEBUG, |
- ("RecordTraceEntries: exiting")); |
- return; |
-} /* end PR_RecordTraceEntries() */ |
- |
-/* |
-** |
-*/ |
-PR_IMPLEMENT(PRIntn) |
- PR_GetTraceEntries( |
- PRTraceEntry *buffer, /* where to write output */ |
- PRInt32 count, /* number to get */ |
- PRInt32 *found /* number you got */ |
-) |
-{ |
- PRInt32 rc; |
- PRInt32 copied = 0; |
- |
- PR_Lock( traceLock ); |
- |
- /* |
- ** Depending on where the LastSeen and Next indices are, |
- ** copy the trace buffer in one or two pieces. |
- */ |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PR_GetTraceEntries: Next: %ld, LastSeen: %ld", next, fetchLastSeen)); |
- |
- if ( fetchLastSeen <= next ) |
- { |
- while (( count-- > 0 ) && (fetchLastSeen < next )) |
- { |
- *(buffer + copied++) = *(tBuf + fetchLastSeen++); |
- } |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); |
- } |
- else /* copy in 2 parts */ |
- { |
- while ( count-- > 0 && fetchLastSeen <= last ) |
- { |
- *(buffer + copied++) = *(tBuf + fetchLastSeen++); |
- } |
- fetchLastSeen = 0; |
- |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); |
- |
- while ( count-- > 0 && fetchLastSeen < next ) |
- { |
- *(buffer + copied++) = *(tBuf + fetchLastSeen++); |
- } |
- PR_LOG( lm, PR_LOG_ERROR, |
- ("PR_GetTraceEntries: Copied: %ld, LastSeen: %ld", copied, fetchLastSeen)); |
- } |
- |
- *found = copied; |
- rc = ( fetchLostData == PR_TRUE )? 1 : 0; |
- fetchLostData = PR_FALSE; |
- |
- PR_Unlock( traceLock ); |
- return rc; |
-} /* end PR_GetTraceEntries() */ |
- |
-/* end prtrace.c */ |