andre@0: /* This Source Code Form is subject to the terms of the Mozilla Public andre@0: * License, v. 2.0. If a copy of the MPL was not distributed with this andre@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ andre@0: andre@0: /* andre@0: ** nssilock.h - Instrumented locking functions for NSS andre@0: ** andre@0: ** Description: andre@0: ** nssilock provides instrumentation for locks and monitors in andre@0: ** the NSS libraries. The instrumentation, when enabled, causes andre@0: ** each call to the instrumented function to record data about andre@0: ** the call to an external file. The external file andre@0: ** subsequently used to extract performance data and other andre@0: ** statistical information about the operation of locks used in andre@0: ** the nss library. andre@0: ** andre@0: ** To enable compilation with instrumentation, build NSS with andre@0: ** the compile time switch NEED_NSS_ILOCK defined. andre@0: ** andre@0: ** say: "gmake OS_CFLAGS+=-DNEED_NSS_ILOCK" at make time. andre@0: ** andre@0: ** At runtime, to enable recording from nssilock, one or more andre@0: ** environment variables must be set. For each nssILockType to andre@0: ** be recorded, an environment variable of the form NSS_ILOCK_x andre@0: ** must be set to 1. For example: andre@0: ** andre@0: ** set NSS_ILOCK_Cert=1 andre@0: ** andre@0: ** nssilock uses PRLOG is used to record to trace data. The andre@0: ** PRLogModule name associated with nssilock data is: "nssilock". andre@0: ** To enable recording of nssilock data you will need to set the andre@0: ** environment variable NSPR_LOG_MODULES to enable andre@0: ** recording for the nssilock log module. Similarly, you will andre@0: ** need to set the environment variable NSPR_LOG_FILE to specify andre@0: ** the filename to receive the recorded data. See prlog.h for usage. andre@0: ** Example: andre@0: ** andre@0: ** export NSPR_LOG_MODULES=nssilock:6 andre@0: ** export NSPR_LOG_FILE=xxxLogfile andre@0: ** andre@0: ** Operation: andre@0: ** nssilock wraps calls to NSPR's PZLock and PZMonitor functions andre@0: ** with similarly named functions: PZ_NewLock(), etc. When NSS is andre@0: ** built with lock instrumentation enabled, the PZ* functions are andre@0: ** compiled into NSS; when lock instrumentation is disabled, andre@0: ** calls to PZ* functions are directly mapped to PR* functions andre@0: ** and the instrumentation arguments to the PZ* functions are andre@0: ** compiled away. andre@0: ** andre@0: ** andre@0: ** File Format: andre@0: ** The format of the external file is implementation andre@0: ** dependent. Where NSPR's PR_LOG() function is used, the file andre@0: ** contains data defined for PR_LOG() plus the data written by andre@0: ** the wrapped function. On some platforms and under some andre@0: ** circumstances, platform dependent logging or andre@0: ** instrumentation probes may be used. In any case, the andre@0: ** relevant data provided by the lock instrumentation is: andre@0: ** andre@0: ** lockType, func, address, duration, line, file [heldTime] andre@0: ** andre@0: ** where: andre@0: ** andre@0: ** lockType: a character representation of nssILockType for the andre@0: ** call. e.g. ... "cert" andre@0: ** andre@0: ** func: the function doing the tracing. e.g. "NewLock" andre@0: ** andre@0: ** address: address of the instrumented lock or monitor andre@0: ** andre@0: ** duration: is how long was spent in the instrumented function, andre@0: ** in PRIntervalTime "ticks". andre@0: ** andre@0: ** line: the line number within the calling function andre@0: ** andre@0: ** file: the file from which the call was made andre@0: ** andre@0: ** heldTime: how long the lock/monitor was held. field andre@0: ** present only for PZ_Unlock() and PZ_ExitMonitor(). andre@0: ** andre@0: ** Design Notes: andre@0: ** The design for lock instrumentation was influenced by the andre@0: ** need to gather performance data on NSS 3.x. It is intended andre@0: ** that the effort to modify NSS to use lock instrumentation andre@0: ** be minimized. Existing calls to locking functions need only andre@0: ** have their names changed to the instrumentation function andre@0: ** names. andre@0: ** andre@0: ** Private NSS Interface: andre@0: ** nssilock.h defines a private interface for use by NSS. andre@0: ** nssilock.h is experimental in nature and is subject to andre@0: ** change or revocation without notice. ... Don't mess with andre@0: ** it. andre@0: ** andre@0: */ andre@0: andre@0: /* andre@0: * $Id: andre@0: */ andre@0: andre@0: #ifndef _NSSILCKT_H_ andre@0: #define _NSSILCKT_H_ andre@0: andre@0: #include "utilrename.h" andre@0: #include "prtypes.h" andre@0: #include "prmon.h" andre@0: #include "prlock.h" andre@0: #include "prcvar.h" andre@0: andre@0: typedef enum { andre@0: nssILockArena = 0, andre@0: nssILockSession = 1, andre@0: nssILockObject = 2, andre@0: nssILockRefLock = 3, andre@0: nssILockCert = 4, andre@0: nssILockCertDB = 5, andre@0: nssILockDBM = 6, andre@0: nssILockCache = 7, andre@0: nssILockSSL = 8, andre@0: nssILockList = 9, andre@0: nssILockSlot = 10, andre@0: nssILockFreelist = 11, andre@0: nssILockOID = 12, andre@0: nssILockAttribute = 13, andre@0: nssILockPK11cxt = 14, /* pk11context */ andre@0: nssILockRWLock = 15, andre@0: nssILockOther = 16, andre@0: nssILockSelfServ = 17, andre@0: nssILockKeyDB = 18, andre@0: nssILockLast /* don't use this one! */ andre@0: } nssILockType; andre@0: andre@0: /* andre@0: ** conditionally compile in nssilock features andre@0: */ andre@0: #if defined(NEED_NSS_ILOCK) andre@0: andre@0: /* andre@0: ** Declare operation type enumerator andre@0: ** enumerations identify the function being performed andre@0: */ andre@0: typedef enum { andre@0: FlushTT = 0, andre@0: NewLock = 1, andre@0: Lock = 2, andre@0: Unlock = 3, andre@0: DestroyLock = 4, andre@0: NewCondVar = 5, andre@0: WaitCondVar = 6, andre@0: NotifyCondVar = 7, andre@0: NotifyAllCondVar = 8, andre@0: DestroyCondVar = 9, andre@0: NewMonitor = 10, andre@0: EnterMonitor = 11, andre@0: ExitMonitor = 12, andre@0: Notify = 13, andre@0: NotifyAll = 14, andre@0: Wait = 15, andre@0: DestroyMonitor = 16 andre@0: } nssILockOp; andre@0: andre@0: /* andre@0: ** Declare the trace record andre@0: */ andre@0: struct pzTrace_s { andre@0: PRUint32 threadID; /* PR_GetThreadID() */ andre@0: nssILockOp op; /* operation being performed */ andre@0: nssILockType ltype; /* lock type identifier */ andre@0: PRIntervalTime callTime; /* time spent in function */ andre@0: PRIntervalTime heldTime; /* lock held time, or -1 */ andre@0: void *lock; /* address of lock structure */ andre@0: PRIntn line; /* line number */ andre@0: char file[24]; /* filename */ andre@0: }; andre@0: andre@0: /* andre@0: ** declare opaque types. See: nssilock.c andre@0: */ andre@0: typedef struct pzlock_s PZLock; andre@0: typedef struct pzcondvar_s PZCondVar; andre@0: typedef struct pzmonitor_s PZMonitor; andre@0: andre@0: #else /* NEED_NSS_ILOCK */ andre@0: andre@0: #define PZLock PRLock andre@0: #define PZCondVar PRCondVar andre@0: #define PZMonitor PRMonitor andre@0: andre@0: #endif /* NEED_NSS_ILOCK */ andre@0: andre@0: #endif /* _NSSILCKT_H_ */