LCOV - code coverage report
Current view: directory - nsprpub/pr/src/misc - prcountr.c (source / functions) Found Hit Coverage
Test: app.info Lines: 133 0 0.0 %
Date: 2012-06-02 Functions: 13 0 0.0 %

       1                 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
       2                 : /* ***** BEGIN LICENSE BLOCK *****
       3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
       4                 :  *
       5                 :  * The contents of this file are subject to the Mozilla Public License Version
       6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
       7                 :  * the License. You may obtain a copy of the License at
       8                 :  * http://www.mozilla.org/MPL/
       9                 :  *
      10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
      11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
      12                 :  * for the specific language governing rights and limitations under the
      13                 :  * License.
      14                 :  *
      15                 :  * The Original Code is the Netscape Portable Runtime (NSPR).
      16                 :  *
      17                 :  * The Initial Developer of the Original Code is
      18                 :  * Netscape Communications Corporation.
      19                 :  * Portions created by the Initial Developer are Copyright (C) 1998-2000
      20                 :  * the Initial Developer. All Rights Reserved.
      21                 :  *
      22                 :  * Contributor(s):
      23                 :  *
      24                 :  * Alternatively, the contents of this file may be used under the terms of
      25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      28                 :  * of those above. If you wish to allow use of your version of this file only
      29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      30                 :  * use your version of this file under the terms of the MPL, indicate your
      31                 :  * decision by deleting the provisions above and replace them with the notice
      32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      33                 :  * the provisions above, a recipient may use your version of this file under
      34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      35                 :  *
      36                 :  * ***** END LICENSE BLOCK ***** */
      37                 : 
      38                 : /*
      39                 : ** prcountr.c -- NSPR Instrumentation Counters
      40                 : **
      41                 : ** Implement the interface defined in prcountr.h
      42                 : **
      43                 : ** Design Notes:
      44                 : **
      45                 : ** The Counter Facility (CF) has a single anchor: qNameList.      
      46                 : ** The anchor is a PRCList. qNameList is a list of links in QName
      47                 : ** structures. From qNameList any QName structure and its
      48                 : ** associated RName structure can be located. 
      49                 : ** 
      50                 : ** For each QName, a list of RName structures is anchored at
      51                 : ** rnLink in the QName structure.
      52                 : ** 
      53                 : ** The counter itself is embedded in the RName structure.
      54                 : ** 
      55                 : ** For manipulating the counter database, single lock is used to
      56                 : ** protect the entire list: counterLock.
      57                 : **
      58                 : ** A PRCounterHandle, defined in prcountr.h, is really a pointer
      59                 : ** to a RName structure. References by PRCounterHandle are
      60                 : ** dead-reconed to the RName structure. The PRCounterHandle is
      61                 : ** "overloaded" for traversing the QName structures; only the
      62                 : ** function PR_FindNextQnameHandle() uses this overloading.
      63                 : **
      64                 : ** 
      65                 : ** ToDo (lth): decide on how to lock or atomically update
      66                 : ** individual counters. Candidates are: the global lock; a lock
      67                 : ** per RName structure; Atomic operations (Note that there are
      68                 : ** not adaquate atomic operations (yet) to achieve this goal). At
      69                 : ** this writing (6/19/98) , the update of the counter variable in
      70                 : ** a QName structure is unprotected.
      71                 : **
      72                 : */
      73                 : 
      74                 : #include "prcountr.h"
      75                 : #include "prclist.h"
      76                 : #include "prlock.h"
      77                 : #include "prlog.h"
      78                 : #include "prmem.h"
      79                 : #include <string.h>
      80                 : 
      81                 : /*
      82                 : **
      83                 : */
      84                 : typedef struct QName
      85                 : {
      86                 :     PRCList link;
      87                 :     PRCList rNameList;
      88                 :     char    name[PRCOUNTER_NAME_MAX+1];
      89                 : } QName;
      90                 : 
      91                 : /*
      92                 : **
      93                 : */
      94                 : typedef struct RName
      95                 : {
      96                 :     PRCList link;
      97                 :     QName   *qName;
      98                 :     PRLock  *lock;
      99                 :     volatile PRUint32   counter;    
     100                 :     char    name[PRCOUNTER_NAME_MAX+1]; 
     101                 :     char    desc[PRCOUNTER_DESC_MAX+1]; 
     102                 : } RName;
     103                 : 
     104                 : 
     105                 : /*
     106                 : ** Define the Counter Facility database
     107                 : */
     108                 : static PRLock  *counterLock;
     109                 : static PRCList qNameList;
     110                 : static PRLogModuleInfo *lm;
     111                 : 
     112                 : /*
     113                 : ** _PR_CounterInitialize() -- Initialize the Counter Facility
     114                 : **
     115                 : */
     116               0 : static void _PR_CounterInitialize( void )
     117                 : {
     118                 :     /*
     119                 :     ** This function should be called only once
     120                 :     */
     121               0 :     PR_ASSERT( counterLock == NULL );
     122                 :     
     123               0 :     counterLock = PR_NewLock();
     124               0 :     PR_INIT_CLIST( &qNameList );
     125               0 :     lm = PR_NewLogModule("counters");
     126               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));
     127                 : 
     128                 :     return;
     129                 : } /* end _PR_CounterInitialize() */
     130                 : 
     131                 : /*
     132                 : ** PR_CreateCounter() -- Create a counter
     133                 : **
     134                 : **  ValidateArguments
     135                 : **  Lock
     136                 : **  if (qName not already in database)
     137                 : **      NewQname
     138                 : **  if (rName already in database )
     139                 : **      Assert
     140                 : **  else NewRname
     141                 : **  NewCounter
     142                 : **  link 'em up
     143                 : **  Unlock
     144                 : **
     145                 : */
     146                 : PR_IMPLEMENT(PRCounterHandle) 
     147               0 :         PR_CreateCounter( 
     148                 :                 const char *qName, 
     149                 :         const char *rName, 
     150                 :         const char *description 
     151                 : ) 
     152                 : {
     153                 :     QName   *qnp;
     154                 :     RName   *rnp;
     155               0 :     PRBool  matchQname = PR_FALSE;
     156                 : 
     157                 :     /* Self initialize, if necessary */
     158               0 :     if ( counterLock == NULL )
     159               0 :         _PR_CounterInitialize();
     160                 : 
     161                 :     /* Validate input arguments */
     162               0 :     PR_ASSERT( strlen(qName) <= PRCOUNTER_NAME_MAX );
     163               0 :     PR_ASSERT( strlen(rName) <= PRCOUNTER_NAME_MAX );
     164               0 :     PR_ASSERT( strlen(description) <= PRCOUNTER_DESC_MAX );
     165                 : 
     166                 :     /* Lock the Facility */
     167               0 :     PR_Lock( counterLock );
     168                 : 
     169                 :     /* Do we already have a matching QName? */
     170               0 :     if (!PR_CLIST_IS_EMPTY( &qNameList ))
     171                 :     {
     172               0 :         qnp = (QName *) PR_LIST_HEAD( &qNameList );
     173                 :         do {
     174               0 :             if ( strcmp(qnp->name, qName) == 0)
     175                 :             {
     176               0 :                 matchQname = PR_TRUE;
     177               0 :                 break;
     178                 :             }
     179               0 :             qnp = (QName *)PR_NEXT_LINK( &qnp->link );
     180               0 :         } while( qnp != (QName *)PR_LIST_HEAD( &qNameList ));
     181                 :     }
     182                 :     /*
     183                 :     ** If we did not find a matching QName,
     184                 :     **    allocate one and initialize it.
     185                 :     **    link it onto the qNameList.
     186                 :     **
     187                 :     */
     188               0 :     if ( matchQname != PR_TRUE )
     189                 :     {
     190               0 :         qnp = PR_NEWZAP( QName );
     191               0 :         PR_ASSERT( qnp != NULL );
     192               0 :         PR_INIT_CLIST( &qnp->link ); 
     193               0 :         PR_INIT_CLIST( &qnp->rNameList ); 
     194               0 :         strcpy( qnp->name, qName );
     195               0 :         PR_APPEND_LINK( &qnp->link, &qNameList ); 
     196                 :     }
     197                 : 
     198                 :     /* Do we already have a matching RName? */
     199               0 :     if (!PR_CLIST_IS_EMPTY( &qnp->rNameList ))
     200                 :     {
     201               0 :         rnp = (RName *) PR_LIST_HEAD( &qnp->rNameList );
     202                 :         do {
     203                 :             /*
     204                 :             ** No duplicate RNames are allowed within a QName
     205                 :             **
     206                 :             */
     207               0 :             PR_ASSERT( strcmp(rnp->name, rName));
     208               0 :             rnp = (RName *)PR_NEXT_LINK( &rnp->link );
     209               0 :         } while( rnp != (RName *)PR_LIST_HEAD( &qnp->rNameList ));
     210                 :     }
     211                 : 
     212                 :     /* Get a new RName structure; initialize its members */
     213               0 :     rnp = PR_NEWZAP( RName );
     214               0 :     PR_ASSERT( rnp != NULL );
     215               0 :     PR_INIT_CLIST( &rnp->link );
     216               0 :     strcpy( rnp->name, rName );
     217               0 :     strcpy( rnp->desc, description );
     218               0 :     rnp->lock = PR_NewLock();
     219               0 :     if ( rnp->lock == NULL )
     220                 :     {
     221               0 :         PR_ASSERT(0);
     222                 :     }
     223                 : 
     224               0 :     PR_APPEND_LINK( &rnp->link, &qnp->rNameList ); /* add RName to QName's rnList */    
     225               0 :     rnp->qName = qnp;                       /* point the RName to the QName */
     226                 : 
     227                 :     /* Unlock the Facility */
     228               0 :     PR_Unlock( counterLock );
     229               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t",
     230                 :         qName, qnp, rName, rnp ));
     231                 : 
     232               0 :     return((PRCounterHandle)rnp);
     233                 : } /*  end PR_CreateCounter() */
     234                 :   
     235                 : 
     236                 : /*
     237                 : **
     238                 : */
     239                 : PR_IMPLEMENT(void) 
     240               0 :         PR_DestroyCounter( 
     241                 :                 PRCounterHandle handle 
     242                 : )
     243                 : {
     244               0 :     RName   *rnp = (RName *)handle;
     245               0 :     QName   *qnp = rnp->qName;
     246                 : 
     247               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting: QName: %s, RName: %s", 
     248                 :         qnp->name, rnp->name));
     249                 : 
     250                 :     /* Lock the Facility */
     251               0 :     PR_Lock( counterLock );
     252                 : 
     253                 :     /*
     254                 :     ** Remove RName from the list of RNames in QName
     255                 :     ** and free RName
     256                 :     */
     257               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting RName: %s, %p", 
     258                 :         rnp->name, rnp));
     259               0 :     PR_REMOVE_LINK( &rnp->link );
     260               0 :     PR_Free( rnp->lock );
     261               0 :     PR_DELETE( rnp );
     262                 : 
     263                 :     /*
     264                 :     ** If this is the last RName within QName
     265                 :     **   remove QName from the qNameList and free it
     266                 :     */
     267               0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ) )
     268                 :     {
     269               0 :         PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Deleting unused QName: %s, %p", 
     270                 :             qnp->name, qnp));
     271               0 :         PR_REMOVE_LINK( &qnp->link );
     272               0 :         PR_DELETE( qnp );
     273                 :     } 
     274                 : 
     275                 :     /* Unlock the Facility */
     276               0 :     PR_Unlock( counterLock );
     277                 :     return;
     278                 : } /*  end PR_DestroyCounter() */
     279                 : 
     280                 : /*
     281                 : **
     282                 : */
     283                 : PR_IMPLEMENT(PRCounterHandle) 
     284               0 :         PR_GetCounterHandleFromName( 
     285                 :         const char *qName, 
     286                 :         const char *rName 
     287                 : )
     288                 : {
     289                 :     const char    *qn, *rn, *desc;
     290               0 :     PRCounterHandle     qh, rh = NULL;
     291               0 :     RName   *rnp = NULL;
     292                 : 
     293               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounterHandleFromName:\n\t"
     294                 :         "QName: %s, RName: %s", qName, rName ));
     295                 : 
     296               0 :     qh = PR_FindNextCounterQname( NULL );
     297               0 :     while (qh != NULL)
     298                 :     {
     299               0 :         rh = PR_FindNextCounterRname( NULL, qh );
     300               0 :         while ( rh != NULL )
     301                 :         {
     302               0 :             PR_GetCounterNameFromHandle( rh, &qn, &rn, &desc );
     303               0 :             if ( (strcmp( qName, qn ) == 0)
     304               0 :                 && (strcmp( rName, rn ) == 0 ))
     305                 :             {
     306               0 :                 rnp = (RName *)rh;
     307               0 :                 goto foundIt;
     308                 :             }
     309               0 :             rh = PR_FindNextCounterRname( rh, qh );
     310                 :         }
     311               0 :         qh = PR_FindNextCounterQname( NULL );
     312                 :     }
     313                 : 
     314                 : foundIt:
     315               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp ));
     316               0 :     return(rh);
     317                 : } /*  end PR_GetCounterHandleFromName() */
     318                 : 
     319                 : /*
     320                 : **
     321                 : */
     322                 : PR_IMPLEMENT(void) 
     323               0 :         PR_GetCounterNameFromHandle( 
     324                 :         PRCounterHandle handle,  
     325                 :             const char **qName, 
     326                 :             const char **rName, 
     327                 :                 const char **description 
     328                 : )
     329                 : {
     330               0 :     RName   *rnp = (RName *)handle;
     331               0 :     QName   *qnp = rnp->qName;
     332                 : 
     333               0 :     *qName = qnp->name;
     334               0 :     *rName = rnp->name;
     335               0 :     *description = rnp->desc;
     336                 : 
     337               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetConterNameFromHandle: "
     338                 :         "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s", 
     339                 :         qnp, rnp, qnp->name, rnp->name, rnp->desc ));
     340                 : 
     341                 :     return;
     342                 : } /*  end PR_GetCounterNameFromHandle() */
     343                 : 
     344                 : 
     345                 : /*
     346                 : **
     347                 : */
     348                 : PR_IMPLEMENT(void) 
     349               0 :         PR_IncrementCounter( 
     350                 :                 PRCounterHandle handle
     351                 : )
     352                 : {
     353               0 :     PR_Lock(((RName *)handle)->lock);
     354               0 :     ((RName *)handle)->counter++;
     355               0 :     PR_Unlock(((RName *)handle)->lock);
     356                 : 
     357               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Increment: %p, %ld", 
     358                 :         handle, ((RName *)handle)->counter ));
     359                 : 
     360                 :     return;
     361                 : } /*  end PR_IncrementCounter() */
     362                 : 
     363                 : 
     364                 : 
     365                 : /*
     366                 : **
     367                 : */
     368                 : PR_IMPLEMENT(void) 
     369               0 :         PR_DecrementCounter( 
     370                 :                 PRCounterHandle handle
     371                 : )
     372                 : {
     373               0 :     PR_Lock(((RName *)handle)->lock);
     374               0 :     ((RName *)handle)->counter--;
     375               0 :     PR_Unlock(((RName *)handle)->lock);
     376                 : 
     377               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: Decrement: %p, %ld", 
     378                 :         handle, ((RName *)handle)->counter ));
     379                 : 
     380                 :     return;
     381                 : } /*  end PR_DecrementCounter()  */
     382                 : 
     383                 : 
     384                 : /*
     385                 : **
     386                 : */
     387                 : PR_IMPLEMENT(void) 
     388               0 :         PR_AddToCounter( 
     389                 :         PRCounterHandle handle, 
     390                 :             PRUint32 value 
     391                 : )
     392                 : {
     393               0 :     PR_Lock(((RName *)handle)->lock);
     394               0 :     ((RName *)handle)->counter += value;
     395               0 :     PR_Unlock(((RName *)handle)->lock);
     396                 : 
     397               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: AddToCounter: %p, %ld", 
     398                 :         handle, ((RName *)handle)->counter ));
     399                 : 
     400                 :     return;
     401                 : } /*  end PR_AddToCounter() */
     402                 : 
     403                 : 
     404                 : /*
     405                 : **
     406                 : */
     407                 : PR_IMPLEMENT(void) 
     408               0 :         PR_SubtractFromCounter( 
     409                 :         PRCounterHandle handle, 
     410                 :             PRUint32 value 
     411                 : )
     412                 : {
     413               0 :     PR_Lock(((RName *)handle)->lock);
     414               0 :     ((RName *)handle)->counter -= value;
     415               0 :     PR_Unlock(((RName *)handle)->lock);
     416                 :     
     417               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SubtractFromCounter: %p, %ld", 
     418                 :         handle, ((RName *)handle)->counter ));
     419                 : 
     420                 :     return;
     421                 : } /*  end  PR_SubtractFromCounter() */
     422                 : 
     423                 : /*
     424                 : **
     425                 : */
     426                 : PR_IMPLEMENT(PRUint32) 
     427               0 :         PR_GetCounter( 
     428                 :                 PRCounterHandle handle 
     429                 : )
     430                 : {
     431               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: GetCounter: %p, %ld", 
     432                 :         handle, ((RName *)handle)->counter ));
     433                 : 
     434               0 :     return(((RName *)handle)->counter);
     435                 : } /*  end  PR_GetCounter() */
     436                 : 
     437                 : /*
     438                 : **
     439                 : */
     440                 : PR_IMPLEMENT(void) 
     441               0 :         PR_SetCounter( 
     442                 :                 PRCounterHandle handle, 
     443                 :                 PRUint32 value 
     444                 : )
     445                 : {
     446               0 :     ((RName *)handle)->counter = value;
     447                 : 
     448               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: SetCounter: %p, %ld", 
     449                 :         handle, ((RName *)handle)->counter ));
     450                 : 
     451                 :     return;
     452                 : } /*  end  PR_SetCounter() */
     453                 : 
     454                 : /*
     455                 : **
     456                 : */
     457                 : PR_IMPLEMENT(PRCounterHandle) 
     458               0 :         PR_FindNextCounterQname( 
     459                 :         PRCounterHandle handle
     460                 : )
     461                 : {
     462               0 :     QName *qnp = (QName *)handle;
     463                 : 
     464               0 :     if ( PR_CLIST_IS_EMPTY( &qNameList ))
     465               0 :             qnp = NULL;
     466               0 :     else if ( qnp == NULL )
     467               0 :         qnp = (QName *)PR_LIST_HEAD( &qNameList );
     468               0 :     else if ( PR_NEXT_LINK( &qnp->link ) ==  &qNameList )
     469               0 :         qnp = NULL;
     470                 :     else  
     471               0 :         qnp = (QName *)PR_NEXT_LINK( &qnp->link );
     472                 : 
     473               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", 
     474                 :         handle, qnp ));
     475                 : 
     476               0 :     return((PRCounterHandle)qnp);
     477                 : } /*  end  PR_FindNextCounterQname() */
     478                 : 
     479                 : 
     480                 : /*
     481                 : **
     482                 : */
     483                 : PR_IMPLEMENT(PRCounterHandle) 
     484               0 :         PR_FindNextCounterRname( 
     485                 :         PRCounterHandle rhandle, 
     486                 :         PRCounterHandle qhandle 
     487                 : )
     488                 : {
     489               0 :     RName *rnp = (RName *)rhandle;
     490               0 :     QName *qnp = (QName *)qhandle;
     491                 : 
     492                 : 
     493               0 :     if ( PR_CLIST_IS_EMPTY( &qnp->rNameList ))
     494               0 :         rnp = NULL;
     495               0 :     else if ( rnp == NULL )
     496               0 :         rnp = (RName *)PR_LIST_HEAD( &qnp->rNameList );
     497               0 :     else if ( PR_NEXT_LINK( &rnp->link ) ==  &qnp->rNameList )
     498               0 :         rnp = NULL;
     499                 :     else
     500               0 :         rnp = (RName *)PR_NEXT_LINK( &rnp->link );
     501                 : 
     502               0 :     PR_LOG( lm, PR_LOG_DEBUG, ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p", 
     503                 :         rhandle, qhandle, rnp ));
     504                 : 
     505               0 :     return((PRCounterHandle)rnp);
     506                 : } /*  end PR_FindNextCounterRname() */

Generated by: LCOV version 1.7