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