1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3  * License, v. 2.0. If a copy of the MPL was not distributed with this
4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
5 
6 #ifndef prcountr_h___
7 #define prcountr_h___
8 
9 /*----------------------------------------------------------------------------
10 ** prcountr.h -- NSPR Instrumentation counters
11 **
12 ** The NSPR Counter Feature provides a means to "count
13 ** something." Counters can be dynamically defined, incremented,
14 ** decremented, set, and deleted under application program
15 ** control.
16 **
17 ** The Counter Feature is intended to be used as instrumentation,
18 ** not as operational data. If you need a counter for operational
19 ** data, use native integral types.
20 **
21 ** Counters are 32bit unsigned intergers. On overflow, a counter
22 ** will wrap. No exception is recognized or reported.
23 **
24 ** A counter can be dynamically created using a two level naming
25 ** convention. A "handle" is returned when the counter is
26 ** created. The counter can subsequently be addressed by its
27 ** handle. An API is provided to get an existing counter's handle
28 ** given the names with  which it was originally created.
29 ** Similarly, a counter's name can be retrieved given its handle.
30 **
31 ** The counter naming convention is a two-level hierarchy. The
32 ** QName is the higher level of the hierarchy; RName is the
33 ** lower level. RNames can be thought of as existing within a
34 ** QName. The same RName can exist within multiple QNames. QNames
35 ** are unique. The NSPR Counter is not a near-zero overhead
36 ** feature. Application designers should be aware of
37 ** serialization issues when using the Counter API. Creating a
38 ** counter locks a large asset, potentially causing a stall. This
39 ** suggest that applications should create counters at component
40 ** initialization, for example, and not create and destroy them
41 ** willy-nilly. ... You have been warned.
42 **
43 ** Incrementing and Adding to counters uses atomic operations.
44 ** The performance of these operations will vary from platform
45 ** to platform. On platforms where atomic operations are not
46 ** supported the overhead may be substantial.
47 **
48 ** When traversing the counter database with FindNext functions,
49 ** the instantaneous values of any given counter is that at the
50 ** moment of extraction. The state of the entire counter database
51 ** may not be viewed as atomic.
52 **
53 ** The counter interface may be disabled (No-Op'd) at compile
54 ** time. When DEBUG is defined at compile time, the Counter
55 ** Feature is compiled into NSPR and applications invoking it.
56 ** When DEBUG is not defined, the counter macros compile to
57 ** nothing. To force the Counter Feature to be compiled into an
58 ** optimized build, define FORCE_NSPR_COUNTERS at compile time
59 ** for both NSPR and the application intending to use it.
60 **
61 ** Application designers should use the macro form of the Counter
62 ** Feature methods to minimize performance impact in optimized
63 ** builds. The macros normally compile to nothing on optimized
64 ** builds.
65 **
66 ** Application designers should be aware of the effects of
67 ** debug and optimized build differences when using result of the
68 ** Counter Feature macros in expressions.
69 **
70 ** The Counter Feature is thread-safe and SMP safe.
71 **
72 ** /lth. 09-Jun-1998.
73 */
74 
75 #include "prtypes.h"
76 
77 PR_BEGIN_EXTERN_C
78 
79 /*
80 ** Opaque counter handle type.
81 ** ... don't even think of looking in here.
82 **
83 */
84 typedef void *  PRCounterHandle;
85 
86 #define PRCOUNTER_NAME_MAX 31
87 #define PRCOUNTER_DESC_MAX 255
88 
89 
90 
91 /* -----------------------------------------------------------------------
92 ** FUNCTION: PR_DEFINE_COUNTER() -- Define a PRCounterHandle
93 **
94 ** DESCRIPTION: PR_DEFINE_COUNTER() is used to define a counter
95 ** handle.
96 **
97 */
98 #define PR_DEFINE_COUNTER(name) PRCounterHandle name
99 
100 /* -----------------------------------------------------------------------
101 ** FUNCTION: PR_INIT_COUNTER_HANDLE() -- Set the value of a PRCounterHandle
102 **
103 ** DESCRIPTION:
104 ** PR_INIT_COUNTER_HANDLE() sets the value of a PRCounterHandle
105 ** to value.
106 **
107 */
108 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
109 #define PR_INIT_COUNTER_HANDLE(handle,value)\
110     (handle) = (PRCounterHandle)(value)
111 #else
112 #define PR_INIT_COUNTER_HANDLE(handle,value)
113 #endif
114 
115 /* -----------------------------------------------------------------------
116 ** FUNCTION: PR_CreateCounter() -- Create a counter
117 **
118 ** DESCRIPTION: PR_CreateCounter() creates a counter object and
119 ** initializes it to zero.
120 **
121 ** The macro form takes as its first argument the name of the
122 ** PRCounterHandle to receive the handle returned from
123 ** PR_CreateCounter().
124 **
125 ** INPUTS:
126 **  qName: The QName for the counter object. The maximum length
127 ** of qName is defined by PRCOUNTER_NAME_MAX
128 **
129 **  rName: The RName for the counter object. The maximum length
130 ** of qName is defined by PRCOUNTER_NAME_MAX
131 **
132 **  descrioption: The description of the counter object. The
133 ** maximum length of description is defined by
134 ** PRCOUNTER_DESC_MAX.
135 **
136 ** OUTPUTS:
137 **
138 ** RETURNS:
139 **  PRCounterHandle.
140 **
141 ** RESTRICTIONS:
142 **
143 */
144 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
145 #define PR_CREATE_COUNTER(handle,qName,rName,description)\
146    (handle) = PR_CreateCounter((qName),(rName),(description))
147 #else
148 #define PR_CREATE_COUNTER(handle,qName,rName,description)
149 #endif
150 
151 NSPR_API(PRCounterHandle)
152 PR_CreateCounter(
153     const char *qName,
154     const char *rName,
155     const char *description
156 );
157 
158 /* -----------------------------------------------------------------------
159 ** FUNCTION: PR_DestroyCounter() -- Destroy a counter object.
160 **
161 ** DESCRIPTION: PR_DestroyCounter() removes a counter and
162 ** unregisters its handle from the counter database.
163 **
164 ** INPUTS:
165 **  handle: the PRCounterHandle of the counter to be destroyed.
166 **
167 ** OUTPUTS:
168 **  The counter is destroyed.
169 **
170 ** RETURNS: void
171 **
172 ** RESTRICTIONS:
173 **
174 */
175 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
176 #define PR_DESTROY_COUNTER(handle) PR_DestroyCounter((handle))
177 #else
178 #define PR_DESTROY_COUNTER(handle)
179 #endif
180 
181 NSPR_API(void)
182 PR_DestroyCounter(
183     PRCounterHandle handle
184 );
185 
186 
187 /* -----------------------------------------------------------------------
188 ** FUNCTION: PR_GetCounterHandleFromName() -- Retreive a
189 ** counter's handle give its name.
190 **
191 ** DESCRIPTION: PR_GetCounterHandleFromName() retreives a
192 ** counter's handle from the counter database, given the name
193 ** the counter was originally created with.
194 **
195 ** INPUTS:
196 **  qName: Counter's original QName.
197 **  rName: Counter's original RName.
198 **
199 ** OUTPUTS:
200 **
201 ** RETURNS:
202 **  PRCounterHandle or PRCounterError.
203 **
204 ** RESTRICTIONS:
205 **
206 */
207 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
208 #define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)\
209     (handle) = PR_GetCounterHandleFromName((qName),(rName))
210 #else
211 #define PR_GET_COUNTER_HANDLE_FROM_NAME(handle,qName,rName)
212 #endif
213 
214 NSPR_API(PRCounterHandle)
215 PR_GetCounterHandleFromName(
216     const char *qName,
217     const char *rName
218 );
219 
220 /* -----------------------------------------------------------------------
221 ** FUNCTION: PR_GetCounterNameFromHandle() -- Retreive a
222 ** counter's name, given its handle.
223 **
224 ** DESCRIPTION: PR_GetCounterNameFromHandle() retreives a
225 ** counter's name given its handle.
226 **
227 ** INPUTS:
228 **  qName: Where to store a pointer to qName.
229 **  rName: Where to store a pointer to rName.
230 **  description: Where to store a pointer to description.
231 **
232 ** OUTPUTS: Pointers to the Counter Feature's copies of the names
233 ** used when the counters were created.
234 **
235 ** RETURNS: void
236 **
237 ** RESTRICTIONS:
238 **
239 */
240 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
241 #define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description)\
242     PR_GetCounterNameFromHandle((handle),(qName),(rName),(description))
243 #else
244 #define PR_GET_COUNTER_NAME_FROM_HANDLE(handle,qName,rName,description )
245 #endif
246 
247 NSPR_API(void)
248 PR_GetCounterNameFromHandle(
249     PRCounterHandle handle,
250     const char **qName,
251     const char **rName,
252     const char **description
253 );
254 
255 
256 /* -----------------------------------------------------------------------
257 ** FUNCTION: PR_IncrementCounter() -- Add one to the referenced
258 ** counter.
259 **
260 ** DESCRIPTION: Add one to the referenced counter.
261 **
262 ** INPUTS:
263 **  handle: The PRCounterHandle of the counter to be incremented
264 **
265 ** OUTPUTS: The counter is incrementd.
266 **
267 ** RETURNS: void
268 **
269 ** RESTRICTIONS:
270 **
271 */
272 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
273 #define PR_INCREMENT_COUNTER(handle) PR_IncrementCounter(handle)
274 #else
275 #define PR_INCREMENT_COUNTER(handle)
276 #endif
277 
278 NSPR_API(void)
279 PR_IncrementCounter(
280     PRCounterHandle handle
281 );
282 
283 
284 /* -----------------------------------------------------------------------
285 ** FUNCTION: PR_DecrementCounter() -- Subtract one from the
286 ** referenced counter
287 **
288 ** DESCRIPTION: Subtract one from the referenced counter.
289 **
290 ** INPUTS:
291 **  handle: The PRCounterHandle of the coutner to be
292 ** decremented.
293 **
294 ** OUTPUTS: the counter is decremented.
295 **
296 ** RETURNS: void
297 **
298 ** RESTRICTIONS:
299 **
300 */
301 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
302 #define PR_DECREMENT_COUNTER(handle) PR_DecrementCounter(handle)
303 #else
304 #define PR_DECREMENT_COUNTER(handle)
305 #endif
306 
307 NSPR_API(void)
308 PR_DecrementCounter(
309     PRCounterHandle handle
310 );
311 
312 /* -----------------------------------------------------------------------
313 ** FUNCTION: PR_AddToCounter() -- Add a value to a counter.
314 **
315 ** DESCRIPTION: Add value to the counter referenced by handle.
316 **
317 ** INPUTS:
318 **  handle: the PRCounterHandle of the counter to be added to.
319 **
320 **  value: the value to be added to the counter.
321 **
322 ** OUTPUTS: new value for counter.
323 **
324 ** RETURNS: void
325 **
326 ** RESTRICTIONS:
327 **
328 */
329 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
330 #define PR_ADD_TO_COUNTER(handle,value)\
331     PR_AddToCounter((handle),(value))
332 #else
333 #define PR_ADD_TO_COUNTER(handle,value)
334 #endif
335 
336 NSPR_API(void)
337 PR_AddToCounter(
338     PRCounterHandle handle,
339     PRUint32 value
340 );
341 
342 
343 /* -----------------------------------------------------------------------
344 ** FUNCTION: PR_SubtractFromCounter() -- A value is subtracted
345 ** from a counter.
346 **
347 ** DESCRIPTION:
348 ** Subtract a value from a counter.
349 **
350 ** INPUTS:
351 **  handle: the PRCounterHandle of the counter to be subtracted
352 ** from.
353 **
354 **  value: the value to be subtracted from the counter.
355 **
356 ** OUTPUTS: new value for counter
357 **
358 ** RETURNS: void
359 **
360 ** RESTRICTIONS:
361 **
362 */
363 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
364 #define PR_SUBTRACT_FROM_COUNTER(handle,value)\
365     PR_SubtractFromCounter((handle),(value))
366 #else
367 #define PR_SUBTRACT_FROM_COUNTER(handle,value)
368 #endif
369 
370 NSPR_API(void)
371 PR_SubtractFromCounter(
372     PRCounterHandle handle,
373     PRUint32 value
374 );
375 
376 
377 /* -----------------------------------------------------------------------
378 ** FUNCTION: PR_GetCounter() -- Retreive the value of a counter
379 **
380 ** DESCRIPTION:
381 ** Retreive the value of a counter.
382 **
383 ** INPUTS:
384 **  handle: the PR_CounterHandle of the counter to be retreived
385 **
386 ** OUTPUTS:
387 **
388 ** RETURNS: The value of the referenced counter
389 **
390 ** RESTRICTIONS:
391 **
392 */
393 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
394 #define PR_GET_COUNTER(counter,handle)\
395     (counter) = PR_GetCounter((handle))
396 #else
397 #define PR_GET_COUNTER(counter,handle) 0
398 #endif
399 
400 NSPR_API(PRUint32)
401 PR_GetCounter(
402     PRCounterHandle handle
403 );
404 
405 /* -----------------------------------------------------------------------
406 ** FUNCTION: PR_SetCounter() -- Replace the content of counter
407 ** with value.
408 **
409 ** DESCRIPTION: The contents of the referenced counter are
410 ** replaced by value.
411 **
412 ** INPUTS:
413 **  handle: the PRCounterHandle of the counter whose contents
414 ** are to be replaced.
415 **
416 **  value: the new value of the counter.
417 **
418 ** OUTPUTS:
419 **
420 ** RETURNS: void
421 **
422 ** RESTRICTIONS:
423 **
424 */
425 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
426 #define PR_SET_COUNTER(handle,value) PR_SetCounter((handle),(value))
427 #else
428 #define PR_SET_COUNTER(handle,value)
429 #endif
430 
431 NSPR_API(void)
432 PR_SetCounter(
433     PRCounterHandle handle,
434     PRUint32 value
435 );
436 
437 
438 /* -----------------------------------------------------------------------
439 ** FUNCTION: PR_FindNextCounterQname() -- Retreive the next QName counter
440 ** handle iterator
441 **
442 ** DESCRIPTION:
443 ** PR_FindNextCounterQname() retreives the first or next Qname
444 ** the counter data base, depending on the value of handle. When
445 ** handle is NULL, the function attempts to retreive the first
446 ** QName handle in the database. When handle is a handle previosly
447 ** retreived QName handle, then the function attempts to retreive
448 ** the next QName handle.
449 **
450 ** INPUTS:
451 **  handle: PRCounterHandle or NULL.
452 **
453 ** OUTPUTS: returned
454 **
455 ** RETURNS: PRCounterHandle or NULL when no more QName counter
456 ** handles are present.
457 **
458 ** RESTRICTIONS:
459 **  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
460 ** cause unpredictable results.
461 **
462 ** A PRCounterHandle returned from this function may only be used
463 ** in another PR_FindNextCounterQname() function call; other
464 ** operations may cause unpredictable results.
465 **
466 */
467 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
468 #define PR_FIND_NEXT_COUNTER_QNAME(next,handle)\
469     (next) = PR_FindNextCounterQname((handle))
470 #else
471 #define PR_FIND_NEXT_COUNTER_QNAME(next,handle) NULL
472 #endif
473 
474 NSPR_API(PRCounterHandle)
475 PR_FindNextCounterQname(
476     PRCounterHandle handle
477 );
478 
479 /* -----------------------------------------------------------------------
480 ** FUNCTION: PR_FindNextCounterRname() -- Retreive the next RName counter
481 ** handle iterator
482 **
483 ** DESCRIPTION:
484 ** PR_FindNextCounterRname() retreives the first or next RNname
485 ** handle from the counter data base, depending on the
486 ** value of handle. When handle is NULL, the function attempts to
487 ** retreive the first RName handle in the database. When handle is
488 ** a handle previosly retreived RName handle, then the function
489 ** attempts to retreive the next RName handle.
490 **
491 ** INPUTS:
492 **  handle: PRCounterHandle or NULL.
493 **  qhandle: PRCounterHandle of a previously aquired via
494 ** PR_FIND_NEXT_QNAME_HANDLE()
495 **
496 ** OUTPUTS: returned
497 **
498 ** RETURNS: PRCounterHandle or NULL when no more RName counter
499 ** handles are present.
500 **
501 ** RESTRICTIONS:
502 **  A concurrent PR_CreateCounter() or PR_DestroyCounter() may
503 ** cause unpredictable results.
504 **
505 ** A PRCounterHandle returned from this function may only be used
506 ** in another PR_FindNextCounterRname() function call; other
507 ** operations may cause unpredictable results.
508 **
509 */
510 #if defined(DEBUG) || defined(FORCE_NSPR_COUNTERS)
511 #define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)\
512     (next) = PR_FindNextCounterRname((rhandle),(qhandle))
513 #else
514 #define PR_FIND_NEXT_COUNTER_RNAME(next,rhandle,qhandle)
515 #endif
516 
517 NSPR_API(PRCounterHandle)
518 PR_FindNextCounterRname(
519     PRCounterHandle rhandle,
520     PRCounterHandle qhandle
521 );
522 
523 PR_END_EXTERN_C
524 
525 #endif /* prcountr_h___ */
526