LCOV - code coverage report
Current view: top level - nsprpub/pr/src/misc - prcountr.c (source / functions) Hit Total Coverage
Test: output.info Lines: 0 129 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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           0 : static void _PR_CounterInitialize( void )
      85             : {
      86             :     /*
      87             :     ** This function should be called only once
      88             :     */
      89           0 :     PR_ASSERT( counterLock == NULL );
      90             :     
      91           0 :     counterLock = PR_NewLock();
      92           0 :     PR_INIT_CLIST( &qNameList );
      93           0 :     lm = PR_NewLogModule("counters");
      94           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));
      95             : 
      96           0 :     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           0 :     PRBool  matchQname = PR_FALSE;
     124             : 
     125             :     /* Self initialize, if necessary */
     126           0 :     if ( counterLock == NULL )
     127           0 :         _PR_CounterInitialize();
     128             : 
     129             :     /* Validate input arguments */
     130           0 :     PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX );
     131           0 :     PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX );
     132           0 :     PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX );
     133             : 
     134             :     /* Lock the Facility */
     135           0 :     PR_Lock( counterLock );
     136             : 
     137             :     /* Do we already have a matching QName? */
     138           0 :     if (!PR_CLIST_IS_EMPTY( &qNameList ))
     139             :     {
     140           0 :         qnp = (QName *) PR_LIST_HEAD( &qNameList );
     141             :         do {
     142           0 :             if ( strcmp(qnp->name, qName) == 0)
     143             :             {
     144           0 :                 matchQname = PR_TRUE;
     145           0 :                 break;
     146             :             }
     147           0 :             qnp = (QName *)PR_NEXT_LINK( &qnp->link );
     148           0 :         } 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           0 :     if ( matchQname != PR_TRUE )
     157             :     {
     158           0 :         qnp = PR_NEWZAP( QName );
     159           0 :         PR_ASSERT( qnp != NULL );
     160           0 :         PR_INIT_CLIST( &qnp->link ); 
     161           0 :         PR_INIT_CLIST( &qnp->rNameList ); 
     162           0 :         strcpy( qnp->name, qName );
     163           0 :         PR_APPEND_LINK( &qnp->link, &qNameList ); 
     164             :     }
     165             : 
     166             :     /* Do we already have a matching RName? */
     167           0 :     if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
     168             :     {
     169           0 :         rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
     170             :         do {
     171             :             /*
     172             :             ** No duplicate RNames are allowed within a QName
     173             :             **
     174             :             */
     175           0 :             PR_ASSERT( strcmp(rnp->name, rName));
     176           0 :             rnp = (RName *)PR_NEXT_LINK( &rnp->link );
     177           0 :         } while( rnp != (RName *)&qnp->rNameList );
     178             :     }
     179             : 
     180             :     /* Get a new RName structure; initialize its members */
     181           0 :     rnp = PR_NEWZAP( RName );
     182           0 :     PR_ASSERT( rnp != NULL );
     183           0 :     PR_INIT_CLIST( &rnp->link );
     184           0 :     strcpy( rnp->name, rName );
     185           0 :     strcpy( rnp->desc, description );
     186           0 :     rnp->lock = PR_NewLock();
     187           0 :     if ( rnp->lock == NULL )
     188             :     {
     189           0 :         PR_ASSERT(0);
     190             :     }
     191             : 
     192           0 :     PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
     193           0 :     rnp->qName = qnp;                       /* point the RName to the QName */
     194             : 
     195             :     /* Unlock the Facility */
     196           0 :     PR_Unlock( counterLock );
     197           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t",
     198             :         qName, qnp, rName, rnp ));
     199             : 
     200           0 :     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           0 :     RName   *rnp = (RName *)handle;
     213           0 :     QName   *qnp = rnp->qName;
     214             : 
     215           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", 
     216             :         qnp->name, rnp->name));
     217             : 
     218             :     /* Lock the Facility */
     219           0 :     PR_Lock( counterLock );
     220             : 
     221             :     /*
     222             :     ** Remove RName from the list of RNames in QName
     223             :     ** and free RName
     224             :     */
     225           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", 
     226             :         rnp->name, rnp));
     227           0 :     PR_REMOVE_LINK( &rnp->link );
     228           0 :     PR_Free( rnp->lock );
     229           0 :     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           0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
     236             :     {
     237           0 :         PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", 
     238             :             qnp->name, qnp));
     239           0 :         PR_REMOVE_LINK( &qnp->link );
     240           0 :         PR_DELETE( qnp );
     241             :     } 
     242             : 
     243             :     /* Unlock the Facility */
     244           0 :     PR_Unlock( counterLock );
     245           0 :     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           0 :     PRCounterHandle     qh, rh = NULL;
     259           0 :     RName   *rnp = NULL;
     260             : 
     261           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t"
     262             :         "QName: %s, RName: %s", qName, rName ));
     263             : 
     264           0 :     qh = PR_FindNextCounterQname( NULL );
     265           0 :     while (qh != NULL)
     266             :     {
     267           0 :         rh = PR_FindNextCounterRname( NULL, qh );
     268           0 :         while ( rh != NULL )
     269             :         {
     270           0 :             PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc );
     271           0 :             if ( (strcmp( qName, qn ) == 0)
     272           0 :                 && (strcmp( rName, rn ) == 0 ))
     273             :             {
     274           0 :                 rnp = (RName *)rh;
     275           0 :                 goto foundIt;
     276             :             }
     277           0 :             rh = PR_FindNextCounterRname( rh, qh );
     278             :         }
     279           0 :         qh = PR_FindNextCounterQname( NULL );
     280             :     }
     281             : 
     282             : foundIt:
     283           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
     284           0 :     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           0 :     RName   *rnp = (RName *)handle;
     299           0 :     QName   *qnp = rnp->qName;
     300             : 
     301           0 :     *qName = qnp->name;
     302           0 :     *rName = rnp->name;
     303           0 :     *description = rnp->desc;
     304             : 
     305           0 :     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           0 :     return;
     310             : } /*  end PR_GetCounterNameFromHandle() */
     311             : 
     312             : 
     313             : /*
     314             : **
     315             : */
     316             : PR_IMPLEMENT(void) 
     317             :         PR_IncrementCounter( 
     318             :                 PRCounterHandle handle
     319             : )
     320             : {
     321           0 :     PR_Lock(((RName *)handle)->lock);
     322           0 :     ((RName *)handle)->counter++;
     323           0 :     PR_Unlock(((RName *)handle)->lock);
     324             : 
     325           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", 
     326             :         handle, ((RName *)handle)->counter ));
     327             : 
     328           0 :     return;
     329             : } /*  end PR_IncrementCounter() */
     330             : 
     331             : 
     332             : 
     333             : /*
     334             : **
     335             : */
     336             : PR_IMPLEMENT(void) 
     337             :         PR_DecrementCounter( 
     338             :                 PRCounterHandle handle
     339             : )
     340             : {
     341           0 :     PR_Lock(((RName *)handle)->lock);
     342           0 :     ((RName *)handle)->counter--;
     343           0 :     PR_Unlock(((RName *)handle)->lock);
     344             : 
     345           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", 
     346             :         handle, ((RName *)handle)->counter ));
     347             : 
     348           0 :     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           0 :     PR_Lock(((RName *)handle)->lock);
     362           0 :     ((RName *)handle)->counter += value;
     363           0 :     PR_Unlock(((RName *)handle)->lock);
     364             : 
     365           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", 
     366             :         handle, ((RName *)handle)->counter ));
     367             : 
     368           0 :     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           0 :     PR_Lock(((RName *)handle)->lock);
     382           0 :     ((RName *)handle)->counter -= value;
     383           0 :     PR_Unlock(((RName *)handle)->lock);
     384             :     
     385           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", 
     386             :         handle, ((RName *)handle)->counter ));
     387             : 
     388           0 :     return;
     389             : } /*  end  PR_SubtractFromCounter() */
     390             : 
     391             : /*
     392             : **
     393             : */
     394             : PR_IMPLEMENT(PRUint32) 
     395             :         PR_GetCounter( 
     396             :                 PRCounterHandle handle 
     397             : )
     398             : {
     399           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", 
     400             :         handle, ((RName *)handle)->counter ));
     401             : 
     402           0 :     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           0 :     ((RName *)handle)->counter = value;
     415             : 
     416           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", 
     417             :         handle, ((RName *)handle)->counter ));
     418             : 
     419           0 :     return;
     420             : } /*  end  PR_SetCounter() */
     421             : 
     422             : /*
     423             : **
     424             : */
     425             : PR_IMPLEMENT(PRCounterHandle) 
     426             :         PR_FindNextCounterQname( 
     427             :         PRCounterHandle handle
     428             : )
     429             : {
     430           0 :     QName *qnp = (QName *)handle;
     431             : 
     432           0 :     if ( PR_CLIST_IS_EMPTY( &qNameList ))
     433           0 :             qnp = NULL;
     434           0 :     else if ( qnp == NULL )
     435           0 :         qnp = (QName *)PR_LIST_HEAD( &qNameList );
     436           0 :     else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
     437           0 :         qnp = NULL;
     438             :     else  
     439           0 :         qnp = (QName *)PR_NEXT_LINK( &qnp->link );
     440             : 
     441           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", 
     442             :         handle, qnp ));
     443             : 
     444           0 :     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           0 :     RName *rnp = (RName *)rhandle;
     458           0 :     QName *qnp = (QName *)qhandle;
     459             : 
     460             : 
     461           0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
     462           0 :         rnp = NULL;
     463           0 :     else if ( rnp == NULL )
     464           0 :         rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
     465           0 :     else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
     466           0 :         rnp = NULL;
     467             :     else
     468           0 :         rnp = (RName *)PR_NEXT_LINK( &rnp->link );
     469             : 
     470           0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
     471             :         rhandle, qhandle, rnp ));
     472             : 
     473           0 :     return((PRCounterHandle)rnp);
     474             : } /*  end PR_FindNextCounterRname() */

Generated by: LCOV version 1.13