comparison nspr/pr/src/misc/prcountr.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
comparison
equal deleted inserted replaced
-1:000000000000 0:1e5118fa0cb1
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 /*
7 ** prcountr.c -- NSPR Instrumentation Counters
8 **
9 ** Implement the interface defined in prcountr.h
10 **
11 ** Design Notes:
12 **
13 ** The Counter Facility (CF) has a single anchor: qNameList.
14 ** The anchor is a PRCList. qNameList is a list of links in QName
15 ** structures. From qNameList any QName structure and its
16 ** associated RName structure can be located.
17 **
18 ** For each QName, a list of RName structures is anchored at
19 ** rnLink in the QName structure.
20 **
21 ** The counter itself is embedded in the RName structure.
22 **
23 ** For manipulating the counter database, single lock is used to
24 ** protect the entire list: counterLock.
25 **
26 ** A PRCounterHandle, defined in prcountr.h, is really a pointer
27 ** to a RName structure. References by PRCounterHandle are
28 ** dead-reconed to the RName structure. The PRCounterHandle is
29 ** "overloaded" for traversing the QName structures; only the
30 ** function PR_FindNextQnameHandle() uses this overloading.
31 **
32 **
33 ** ToDo (lth): decide on how to lock or atomically update
34 ** individual counters. Candidates are: the global lock; a lock
35 ** per RName structure; Atomic operations (Note that there are
36 ** not adaquate atomic operations (yet) to achieve this goal). At
37 ** this writing (6/19/98) , the update of the counter variable in
38 ** a QName structure is unprotected.
39 **
40 */
41
42 #include "prcountr.h"
43 #include "prclist.h"
44 #include "prlock.h"
45 #include "prlog.h"
46 #include "prmem.h"
47 #include <string.h>
48
49 /*
50 **
51 */
52 typedef struct QName
53 {
54 PRCList link;
55 PRCList rNameList;
56 char name[PRCOUNTER_NAME_MAX+1];
57 } QName;
58
59 /*
60 **
61 */
62 typedef struct RName
63 {
64 PRCList link;
65 QName *qName;
66 PRLock *lock;
67 volatile PRUint32 counter;
68 char name[PRCOUNTER_NAME_MAX+1];
69 char desc[PRCOUNTER_DESC_MAX+1];
70 } RName;
71
72
73 /*
74 ** Define the Counter Facility database
75 */
76 static PRLock *counterLock;
77 static PRCList qNameList;
78 static PRLogModuleInfo *lm;
79
80 /*
81 ** _PR_CounterInitialize() -- Initialize the Counter Facility
82 **
83 */
84 static void _PR_CounterInitialize( void )
85 {
86 /*
87 ** This function should be called only once
88 */
89 PR_ASSERT( counterLock == NULL );
90
91 counterLock = PR_NewLock();
92 PR_INIT_CLIST( &qNameList );
93 lm = PR_NewLogModule("counters");
94 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));
95
96 return;
97 } /* end _PR_CounterInitialize() */
98
99 /*
100 ** PR_CreateCounter() -- Create a counter
101 **
102 ** ValidateArguments
103 ** Lock
104 ** if (qName not already in database)
105 ** NewQname
106 ** if (rName already in database )
107 ** Assert
108 ** else NewRname
109 ** NewCounter
110 ** link 'em up
111 ** Unlock
112 **
113 */
114 PR_IMPLEMENT(PRCounterHandle)
115 PR_CreateCounter(
116 const char *qName,
117 const char *rName,
118 const char *description
119 )
120 {
121 QName *qnp;
122 RName *rnp;
123 PRBool matchQname = PR_FALSE;
124
125 /* Self initialize, if necessary */
126 if ( counterLock == NULL )
127 _PR_CounterInitialize();
128
129 /* Validate input arguments */
130 PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX );
131 PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX );
132 PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX );
133
134 /* Lock the Facility */
135 PR_Lock( counterLock );
136
137 /* Do we already have a matching QName? */
138 if (!PR_CLIST_IS_EMPTY( &qNameList ))
139 {
140 qnp = (QName *) PR_LIST_HEAD( &qNameList );
141 do {
142 if ( strcmp(qnp->name, qName) == 0)
143 {
144 matchQname = PR_TRUE;
145 break;
146 }
147 qnp = (QName *)PR_NEXT_LINK( &qnp->link );
148 } while( qnp != (QName *)&qNameList );
149 }
150 /*
151 ** If we did not find a matching QName,
152 ** allocate one and initialize it.
153 ** link it onto the qNameList.
154 **
155 */
156 if ( matchQname != PR_TRUE )
157 {
158 qnp = PR_NEWZAP( QName );
159 PR_ASSERT( qnp != NULL );
160 PR_INIT_CLIST( &qnp->link );
161 PR_INIT_CLIST( &qnp->rNameList );
162 strcpy( qnp->name, qName );
163 PR_APPEND_LINK( &qnp->link, &qNameList );
164 }
165
166 /* Do we already have a matching RName? */
167 if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
168 {
169 rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
170 do {
171 /*
172 ** No duplicate RNames are allowed within a QName
173 **
174 */
175 PR_ASSERT( strcmp(rnp->name, rName));
176 rnp = (RName *)PR_NEXT_LINK( &rnp->link );
177 } while( rnp != (RName *)&qnp->rNameList );
178 }
179
180 /* Get a new RName structure; initialize its members */
181 rnp = PR_NEWZAP( RName );
182 PR_ASSERT( rnp != NULL );
183 PR_INIT_CLIST( &rnp->link );
184 strcpy( rnp->name, rName );
185 strcpy( rnp->desc, description );
186 rnp->lock = PR_NewLock();
187 if ( rnp->lock == NULL )
188 {
189 PR_ASSERT(0);
190 }
191
192 PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */
193 rnp->qName = qnp; /* point the RName to the QName */
194
195 /* Unlock the Facility */
196 PR_Unlock( counterLock );
197 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t",
198 qName, qnp, rName, rnp ));
199
200 return((PRCounterHandle)rnp);
201 } /* end PR_CreateCounter() */
202
203
204 /*
205 **
206 */
207 PR_IMPLEMENT(void)
208 PR_DestroyCounter(
209 PRCounterHandle handle
210 )
211 {
212 RName *rnp = (RName *)handle;
213 QName *qnp = rnp->qName;
214
215 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s",
216 qnp->name, rnp->name));
217
218 /* Lock the Facility */
219 PR_Lock( counterLock );
220
221 /*
222 ** Remove RName from the list of RNames in QName
223 ** and free RName
224 */
225 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p",
226 rnp->name, rnp));
227 PR_REMOVE_LINK( &rnp->link );
228 PR_Free( rnp->lock );
229 PR_DELETE( rnp );
230
231 /*
232 ** If this is the last RName within QName
233 ** remove QName from the qNameList and free it
234 */
235 if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
236 {
237 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p",
238 qnp->name, qnp));
239 PR_REMOVE_LINK( &qnp->link );
240 PR_DELETE( qnp );
241 }
242
243 /* Unlock the Facility */
244 PR_Unlock( counterLock );
245 return;
246 } /* end PR_DestroyCounter() */
247
248 /*
249 **
250 */
251 PR_IMPLEMENT(PRCounterHandle)
252 PR_GetCounterHandleFromName(
253 const char *qName,
254 const char *rName
255 )
256 {
257 const char *qn, *rn, *desc;
258 PRCounterHandle qh, rh = NULL;
259 RName *rnp = NULL;
260
261 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t"
262 "QName: %s, RName: %s", qName, rName ));
263
264 qh = PR_FindNextCounterQname( NULL );
265 while (qh != NULL)
266 {
267 rh = PR_FindNextCounterRname( NULL, qh );
268 while ( rh != NULL )
269 {
270 PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc );
271 if ( (strcmp( qName, qn ) == 0)
272 && (strcmp( rName, rn ) == 0 ))
273 {
274 rnp = (RName *)rh;
275 goto foundIt;
276 }
277 rh = PR_FindNextCounterRname( rh, qh );
278 }
279 qh = PR_FindNextCounterQname( NULL );
280 }
281
282 foundIt:
283 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
284 return(rh);
285 } /* end PR_GetCounterHandleFromName() */
286
287 /*
288 **
289 */
290 PR_IMPLEMENT(void)
291 PR_GetCounterNameFromHandle(
292 PRCounterHandle handle,
293 const char **qName,
294 const char **rName,
295 const char **description
296 )
297 {
298 RName *rnp = (RName *)handle;
299 QName *qnp = rnp->qName;
300
301 *qName = qnp->name;
302 *rName = rnp->name;
303 *description = rnp->desc;
304
305 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: "
306 "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s",
307 qnp, rnp, qnp->name, rnp->name, rnp->desc ));
308
309 return;
310 } /* end PR_GetCounterNameFromHandle() */
311
312
313 /*
314 **
315 */
316 PR_IMPLEMENT(void)
317 PR_IncrementCounter(
318 PRCounterHandle handle
319 )
320 {
321 PR_Lock(((RName *)handle)->lock);
322 ((RName *)handle)->counter++;
323 PR_Unlock(((RName *)handle)->lock);
324
325 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld",
326 handle, ((RName *)handle)->counter ));
327
328 return;
329 } /* end PR_IncrementCounter() */
330
331
332
333 /*
334 **
335 */
336 PR_IMPLEMENT(void)
337 PR_DecrementCounter(
338 PRCounterHandle handle
339 )
340 {
341 PR_Lock(((RName *)handle)->lock);
342 ((RName *)handle)->counter--;
343 PR_Unlock(((RName *)handle)->lock);
344
345 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld",
346 handle, ((RName *)handle)->counter ));
347
348 return;
349 } /* end PR_DecrementCounter() */
350
351
352 /*
353 **
354 */
355 PR_IMPLEMENT(void)
356 PR_AddToCounter(
357 PRCounterHandle handle,
358 PRUint32 value
359 )
360 {
361 PR_Lock(((RName *)handle)->lock);
362 ((RName *)handle)->counter += value;
363 PR_Unlock(((RName *)handle)->lock);
364
365 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld",
366 handle, ((RName *)handle)->counter ));
367
368 return;
369 } /* end PR_AddToCounter() */
370
371
372 /*
373 **
374 */
375 PR_IMPLEMENT(void)
376 PR_SubtractFromCounter(
377 PRCounterHandle handle,
378 PRUint32 value
379 )
380 {
381 PR_Lock(((RName *)handle)->lock);
382 ((RName *)handle)->counter -= value;
383 PR_Unlock(((RName *)handle)->lock);
384
385 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld",
386 handle, ((RName *)handle)->counter ));
387
388 return;
389 } /* end PR_SubtractFromCounter() */
390
391 /*
392 **
393 */
394 PR_IMPLEMENT(PRUint32)
395 PR_GetCounter(
396 PRCounterHandle handle
397 )
398 {
399 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld",
400 handle, ((RName *)handle)->counter ));
401
402 return(((RName *)handle)->counter);
403 } /* end PR_GetCounter() */
404
405 /*
406 **
407 */
408 PR_IMPLEMENT(void)
409 PR_SetCounter(
410 PRCounterHandle handle,
411 PRUint32 value
412 )
413 {
414 ((RName *)handle)->counter = value;
415
416 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld",
417 handle, ((RName *)handle)->counter ));
418
419 return;
420 } /* end PR_SetCounter() */
421
422 /*
423 **
424 */
425 PR_IMPLEMENT(PRCounterHandle)
426 PR_FindNextCounterQname(
427 PRCounterHandle handle
428 )
429 {
430 QName *qnp = (QName *)handle;
431
432 if ( PR_CLIST_IS_EMPTY( &qNameList ))
433 qnp = NULL;
434 else if ( qnp == NULL )
435 qnp = (QName *)PR_LIST_HEAD( &qNameList );
436 else if ( PR_NEXT_LINK( &qnp->link ) == &qNameList )
437 qnp = NULL;
438 else
439 qnp = (QName *)PR_NEXT_LINK( &qnp->link );
440
441 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p",
442 handle, qnp ));
443
444 return((PRCounterHandle)qnp);
445 } /* end PR_FindNextCounterQname() */
446
447
448 /*
449 **
450 */
451 PR_IMPLEMENT(PRCounterHandle)
452 PR_FindNextCounterRname(
453 PRCounterHandle rhandle,
454 PRCounterHandle qhandle
455 )
456 {
457 RName *rnp = (RName *)rhandle;
458 QName *qnp = (QName *)qhandle;
459
460
461 if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
462 rnp = NULL;
463 else if ( rnp == NULL )
464 rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
465 else if ( PR_NEXT_LINK( &rnp->link ) == &qnp->rNameList )
466 rnp = NULL;
467 else
468 rnp = (RName *)PR_NEXT_LINK( &rnp->link );
469
470 PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p",
471 rhandle, qhandle, rnp ));
472
473 return((PRCounterHandle)rnp);
474 } /* end PR_FindNextCounterRname() */
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)