LCOV - app.info - nsprpub/pr/src/misc/prcountr.c

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-04-07 | 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