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