michael@0: /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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: #ifndef prcountr_h___ michael@0: #define prcountr_h___ michael@0: michael@0: /*---------------------------------------------------------------------------- michael@0: ** prcountr.h -- NSPR Instrumentation counters michael@0: ** michael@0: ** The NSPR Counter Feature provides a means to "count michael@0: ** something." Counters can be dynamically defined, incremented, michael@0: ** decremented, set, and deleted under application program michael@0: ** control. michael@0: ** michael@0: ** The Counter Feature is intended to be used as instrumentation, michael@0: ** not as operational data. If you need a counter for operational michael@0: ** data, use native integral types. michael@0: ** michael@0: ** Counters are 32bit unsigned intergers. On overflow, a counter michael@0: ** will wrap. No exception is recognized or reported. michael@0: ** michael@0: ** A counter can be dynamically created using a two level naming michael@0: ** convention. A "handle" is returned when the counter is michael@0: ** created. The counter can subsequently be addressed by its michael@0: ** handle. An API is provided to get an existing counter's handle michael@0: ** given the names with which it was originally created. michael@0: ** Similarly, a counter's name can be retrieved given its handle. michael@0: ** michael@0: ** The counter naming convention is a two-level hierarchy. The michael@0: ** QName is the higher level of the hierarchy; RName is the michael@0: ** lower level. RNames can be thought of as existing within a michael@0: ** QName. The same RName can exist within multiple QNames. QNames michael@0: ** are unique. The NSPR Counter is not a near-zero overhead michael@0: ** feature. Application designers should be aware of michael@0: ** serialization issues when using the Counter API. Creating a michael@0: ** counter locks a large asset, potentially causing a stall. This michael@0: ** suggest that applications should create counters at component michael@0: ** initialization, for example, and not create and destroy them michael@0: ** willy-nilly. ... You have been warned. michael@0: ** michael@0: ** Incrementing and Adding to counters uses atomic operations. michael@0: ** The performance of these operations will vary from platform michael@0: ** to platform. On platforms where atomic operations are not michael@0: ** supported the overhead may be substantial. michael@0: ** michael@0: ** When traversing the counter database with FindNext functions, michael@0: ** the instantaneous values of any given counter is that at the michael@0: ** moment of extraction. The state of the entire counter database michael@0: ** may not be viewed as atomic. michael@0: ** michael@0: ** The counter interface may be disabled (No-Op'd) at compile michael@0: ** time. When DEBUG is defined at compile time, the Counter michael@0: ** Feature is compiled into NSPR and applications invoking it. michael@0: ** When DEBUG is not defined, the counter macros compile to michael@0: ** nothing. To force the Counter Feature to be compiled into an michael@0: ** optimized build, define FORCE_NSPR_COUNTERS at compile time michael@0: ** for both NSPR and the application intending to use it. michael@0: ** michael@0: ** Application designers should use the macro form of the Counter michael@0: ** Feature methods to minimize performance impact in optimized michael@0: ** builds. The macros normally compile to nothing on optimized michael@0: ** builds. michael@0: ** michael@0: ** Application designers should be aware of the effects of michael@0: ** debug and optimized build differences when using result of the michael@0: ** Counter Feature macros in expressions. michael@0: ** michael@0: ** The Counter Feature is thread-safe and SMP safe. michael@0: ** michael@0: ** /lth. 09-Jun-1998. michael@0: */ michael@0: michael@0: #include "prtypes.h" michael@0: michael@0: PR_BEGIN_EXTERN_C michael@0: michael@0: /* michael@0: ** Opaque counter handle type. michael@0: ** ... don't even think of looking in here. michael@0: ** michael@0: */ michael@0: typedef void * PRCounterHandle; michael@0: michael@0: #define PRCOUNTER_NAME_MAX 31 michael@0: #define PRCOUNTER_DESC_MAX 255 michael@0: michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle michael@0: ** michael@0: ** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter michael@0: ** handle. michael@0: ** michael@0: */ michael@0: #define PR_DEFINE_COUNTER(name) PRCounterHandle name michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle michael@0: ** michael@0: ** DESCRIPTION: michael@0: ** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle michael@0: ** to value. michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_INIT_COUNTER_HANDLE(handle,value)\ michael@0: (handle) = (PRCounterHandle)(value) michael@0: #else michael@0: #define PR_INIT_COUNTER_HANDLE(handle,value) michael@0: #endif michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_CreateCounter() -- Create a counter michael@0: ** michael@0: ** DESCRIPTION: PR_CreateCounter() creates a counter object and michael@0: ** initializes it to zero. michael@0: ** michael@0: ** The macro form takes as its first argument the name of the michael@0: ** PRCounterHandle to receive the handle returned from michael@0: ** PR_CreateCounter(). michael@0: ** michael@0: ** INPUTS: michael@0: ** qName: The QName for the counter object. The maximum length michael@0: ** of qName is defined by PRCOUNTER_NAME_MAX michael@0: ** michael@0: ** rName: The RName for the counter object. The maximum length michael@0: ** of qName is defined by PRCOUNTER_NAME_MAX michael@0: ** michael@0: ** descrioption: The description of the counter object. The michael@0: ** maximum length of description is defined by michael@0: ** PRCOUNTER_DESC_MAX. michael@0: ** michael@0: ** OUTPUTS: michael@0: ** michael@0: ** RETURNS: michael@0: ** PRCounterHandle. michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_CREATE_COUNTER(handle,qName,rName,description)\ michael@0: (handle) = PR_CreateCounter((qName),(rName),(description)) michael@0: #else michael@0: #define PR_CREATE_COUNTER(handle,qName,rName,description) michael@0: #endif michael@0: michael@0: NSPR_API(PRCounterHandle) michael@0: PR_CreateCounter( michael@0: const char *qName, michael@0: const char *rName, michael@0: const char *description michael@0: ); michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_DestroyCounter() -- Destroy a counter object. michael@0: ** michael@0: ** DESCRIPTION: PR_DestroyCounter() removes a counter and michael@0: ** unregisters its handle from the counter database. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: the PRCounterHandle of the counter to be destroyed. michael@0: ** michael@0: ** OUTPUTS: michael@0: ** The counter is destroyed. michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle)) michael@0: #else michael@0: #define PR_DESTROY_COUNTER(handle) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_DestroyCounter( michael@0: PRCounterHandle handle michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a michael@0: ** counter's handle give its name. michael@0: ** michael@0: ** DESCRIPTION: PR_GetCounterHandleFromName() retreives a michael@0: ** counter's handle from the counter database, given the name michael@0: ** the counter was originally created with. michael@0: ** michael@0: ** INPUTS: michael@0: ** qName: Counter's original QName. michael@0: ** rName: Counter's original RName. michael@0: ** michael@0: ** OUTPUTS: michael@0: ** michael@0: ** RETURNS: michael@0: ** PRCounterHandle or PRCounterError. michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\ michael@0: (handle) = PR_GetCounterHandleFromName((qName),(rName)) michael@0: #else michael@0: #define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName) michael@0: #endif michael@0: michael@0: NSPR_API(PRCounterHandle) michael@0: PR_GetCounterHandleFromName( michael@0: const char *qName, michael@0: const char *rName michael@0: ); michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a michael@0: ** counter's name, given its handle. michael@0: ** michael@0: ** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a michael@0: ** counter's name given its handle. michael@0: ** michael@0: ** INPUTS: michael@0: ** qName: Where to store a pointer to qName. michael@0: ** rName: Where to store a pointer to rName. michael@0: ** description: Where to store a pointer to description. michael@0: ** michael@0: ** OUTPUTS: Pointers to the Counter Feature's copies of the names michael@0: ** used when the counters were created. michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\ michael@0: PR_GetCounterNameFromHandle((handle),(qName),(rName),(description)) michael@0: #else michael@0: #define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description ) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_GetCounterNameFromHandle( michael@0: PRCounterHandle handle, michael@0: const char **qName, michael@0: const char **rName, michael@0: const char **description michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_IncrementCounter() -- Add one to the referenced michael@0: ** counter. michael@0: ** michael@0: ** DESCRIPTION: Add one to the referenced counter. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: The PRCounterHandle of the counter to be incremented michael@0: ** michael@0: ** OUTPUTS: The counter is incrementd. michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle) michael@0: #else michael@0: #define PR_INCREMENT_COUNTER(handle) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_IncrementCounter( michael@0: PRCounterHandle handle michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_DecrementCounter() -- Subtract one from the michael@0: ** referenced counter michael@0: ** michael@0: ** DESCRIPTION: Subtract one from the referenced counter. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: The PRCounterHandle of the coutner to be michael@0: ** decremented. michael@0: ** michael@0: ** OUTPUTS: the counter is decremented. michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle) michael@0: #else michael@0: #define PR_DECREMENT_COUNTER(handle) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_DecrementCounter( michael@0: PRCounterHandle handle michael@0: ); michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_AddToCounter() -- Add a value to a counter. michael@0: ** michael@0: ** DESCRIPTION: Add value to the counter referenced by handle. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: the PRCounterHandle of the counter to be added to. michael@0: ** michael@0: ** value: the value to be added to the counter. michael@0: ** michael@0: ** OUTPUTS: new value for counter. michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_ADD_TO_COUNTER(handle,value)\ michael@0: PR_AddToCounter((handle),(value)) michael@0: #else michael@0: #define PR_ADD_TO_COUNTER(handle,value) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_AddToCounter( michael@0: PRCounterHandle handle, michael@0: PRUint32 value michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted michael@0: ** from a counter. michael@0: ** michael@0: ** DESCRIPTION: michael@0: ** Subtract a value from a counter. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: the PRCounterHandle of the counter to be subtracted michael@0: ** from. michael@0: ** michael@0: ** value: the value to be subtracted from the counter. michael@0: ** michael@0: ** OUTPUTS: new value for counter michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_SUBTRACT_FROM_COUNTER(handle,value)\ michael@0: PR_SubtractFromCounter((handle),(value)) michael@0: #else michael@0: #define PR_SUBTRACT_FROM_COUNTER(handle,value) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_SubtractFromCounter( michael@0: PRCounterHandle handle, michael@0: PRUint32 value michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_GetCounter() -- Retreive the value of a counter michael@0: ** michael@0: ** DESCRIPTION: michael@0: ** Retreive the value of a counter. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: the PR_CounterHandle of the counter to be retreived michael@0: ** michael@0: ** OUTPUTS: michael@0: ** michael@0: ** RETURNS: The value of the referenced counter michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_GET_COUNTER(counter,handle)\ michael@0: (counter) = PR_GetCounter((handle)) michael@0: #else michael@0: #define PR_GET_COUNTER(counter,handle) 0 michael@0: #endif michael@0: michael@0: NSPR_API(PRUint32) michael@0: PR_GetCounter( michael@0: PRCounterHandle handle michael@0: ); michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_SetCounter() -- Replace the content of counter michael@0: ** with value. michael@0: ** michael@0: ** DESCRIPTION: The contents of the referenced counter are michael@0: ** replaced by value. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: the PRCounterHandle of the counter whose contents michael@0: ** are to be replaced. michael@0: ** michael@0: ** value: the new value of the counter. michael@0: ** michael@0: ** OUTPUTS: michael@0: ** michael@0: ** RETURNS: void michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value)) michael@0: #else michael@0: #define PR_SET_COUNTER(handle,value) michael@0: #endif michael@0: michael@0: NSPR_API(void) michael@0: PR_SetCounter( michael@0: PRCounterHandle handle, michael@0: PRUint32 value michael@0: ); michael@0: michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter michael@0: ** handle iterator michael@0: ** michael@0: ** DESCRIPTION: michael@0: ** PR_FindNextCounterQname() retreives the first or next Qname michael@0: ** the counter data base, depending on the value of handle. When michael@0: ** handle is NULL, the function attempts to retreive the first michael@0: ** QName handle in the database. When handle is a handle previosly michael@0: ** retreived QName handle, then the function attempts to retreive michael@0: ** the next QName handle. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: PRCounterHandle or NULL. michael@0: ** michael@0: ** OUTPUTS: returned michael@0: ** michael@0: ** RETURNS: PRCounterHandle or NULL when no more QName counter michael@0: ** handles are present. michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** A concurrent PR_CreateCounter() or PR_DestroyCounter() may michael@0: ** cause unpredictable results. michael@0: ** michael@0: ** A PRCounterHandle returned from this function may only be used michael@0: ** in another PR_FindNextCounterQname() function call; other michael@0: ** operations may cause unpredictable results. michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\ michael@0: (next) = PR_FindNextCounterQname((handle)) michael@0: #else michael@0: #define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL michael@0: #endif michael@0: michael@0: NSPR_API(PRCounterHandle) michael@0: PR_FindNextCounterQname( michael@0: PRCounterHandle handle michael@0: ); michael@0: michael@0: /* ----------------------------------------------------------------------- michael@0: ** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter michael@0: ** handle iterator michael@0: ** michael@0: ** DESCRIPTION: michael@0: ** PR_FindNextCounterRname() retreives the first or next RNname michael@0: ** handle from the counter data base, depending on the michael@0: ** value of handle. When handle is NULL, the function attempts to michael@0: ** retreive the first RName handle in the database. When handle is michael@0: ** a handle previosly retreived RName handle, then the function michael@0: ** attempts to retreive the next RName handle. michael@0: ** michael@0: ** INPUTS: michael@0: ** handle: PRCounterHandle or NULL. michael@0: ** qhandle: PRCounterHandle of a previously aquired via michael@0: ** PR_FIND_NEXT_QNAME_HANDLE() michael@0: ** michael@0: ** OUTPUTS: returned michael@0: ** michael@0: ** RETURNS: PRCounterHandle or NULL when no more RName counter michael@0: ** handles are present. michael@0: ** michael@0: ** RESTRICTIONS: michael@0: ** A concurrent PR_CreateCounter() or PR_DestroyCounter() may michael@0: ** cause unpredictable results. michael@0: ** michael@0: ** A PRCounterHandle returned from this function may only be used michael@0: ** in another PR_FindNextCounterRname() function call; other michael@0: ** operations may cause unpredictable results. michael@0: ** michael@0: */ michael@0: #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS) michael@0: #define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\ michael@0: (next) = PR_FindNextCounterRname((rhandle),(qhandle)) michael@0: #else michael@0: #define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle) michael@0: #endif michael@0: michael@0: NSPR_API(PRCounterHandle) michael@0: PR_FindNextCounterRname( michael@0: PRCounterHandle rhandle, michael@0: PRCounterHandle qhandle michael@0: ); michael@0: michael@0: PR_END_EXTERN_C michael@0: michael@0: #endif /* prcountr_h___ */