Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/Firefox/nsprpub/pr/src/misc/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 10 kB image not shown  

Quelle  prcountr.c   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */


/*
** prcountr.c -- NSPR Instrumentation Counters
**
** Implement the interface defined in prcountr.h
**
** Design Notes:
**
** The Counter Facility (CF) has a single anchor: qNameList.
** The anchor is a PRCList. qNameList is a list of links in QName
** structures. From qNameList any QName structure and its
** associated RName structure can be located.
**
** For each QName, a list of RName structures is anchored at
** rnLink in the QName structure.
**
** The counter itself is embedded in the RName structure.
**
** For manipulating the counter database, single lock is used to
** protect the entire list: counterLock.
**
** A PRCounterHandle, defined in prcountr.h, is really a pointer
** to a RName structure. References by PRCounterHandle are
** dead-reconed to the RName structure. The PRCounterHandle is
** "overloaded" for traversing the QName structures; only the
** function PR_FindNextQnameHandle() uses this overloading.
**
**
** ToDo (lth): decide on how to lock or atomically update
** individual counters. Candidates are: the global lock; a lock
** per RName structure; Atomic operations (Note that there are
** not adaquate atomic operations (yet) to achieve this goal). At
** this writing (6/19/98) , the update of the counter variable in
** a QName structure is unprotected.
**
*/


#include "prcountr.h"
#include "prclist.h"
#include "prlock.h"
#include "prlog.h"
#include "prmem.h"
#include <string.h>

/*
**
*/

typedef struct QName {
  PRCList link;
  PRCList rNameList;
  char name[PRCOUNTER_NAME_MAX + 1];
} QName;

/*
**
*/

typedef struct RName {
  PRCList link;
  QName* qName;
  PRLock* lock;
  volatile PRUint32 counter;
  char name[PRCOUNTER_NAME_MAX + 1];
  char desc[PRCOUNTER_DESC_MAX + 1];
} RName;

/*
** Define the Counter Facility database
*/

static PRLock* counterLock;
static PRCList qNameList;
static PRLogModuleInfo* lm;

/*
** _PR_CounterInitialize() -- Initialize the Counter Facility
**
*/

static void _PR_CounterInitialize(void) {
  /*
  ** This function should be called only once
  */

  PR_ASSERT(counterLock == NULL);

  counterLock = PR_NewLock();
  PR_INIT_CLIST(&qNameList);
  lm = PR_NewLogModule("counters");
  PR_LOG(lm, PR_LOG_DEBUG, ("PR_Counter: Initialization complete"));

  return;
/* end _PR_CounterInitialize() */

/*
** PR_CreateCounter() -- Create a counter
**
**  ValidateArguments
**  Lock
**  if (qName not already in database)
**      NewQname
**  if (rName already in database )
**      Assert
**  else NewRname
**  NewCounter
**  link 'em up
**  Unlock
**
*/

PR_IMPLEMENT(PRCounterHandle)
PR_CreateCounter(const char* qName, const char* rName,
                 const char* description) {
  QName* qnp;
  RName* rnp;
  PRBool matchQname = PR_FALSE;

  /* Self initialize, if necessary */
  if (counterLock == NULL) {
    _PR_CounterInitialize();
  }

  /* Validate input arguments */
  PR_ASSERT(strlen(qName) <= PRCOUNTER_NAME_MAX);
  PR_ASSERT(strlen(rName) <= PRCOUNTER_NAME_MAX);
  PR_ASSERT(strlen(description) <= PRCOUNTER_DESC_MAX);

  /* Lock the Facility */
  PR_Lock(counterLock);

  /* Do we already have a matching QName? */
  if (!PR_CLIST_IS_EMPTY(&qNameList)) {
    qnp = (QName*)PR_LIST_HEAD(&qNameList);
    do {
      if (strcmp(qnp->name, qName) == 0) {
        matchQname = PR_TRUE;
        break;
      }
      qnp = (QName*)PR_NEXT_LINK(&qnp->link);
    } while (qnp != (QName*)&qNameList);
  }
  /*
  ** If we did not find a matching QName,
  **    allocate one and initialize it.
  **    link it onto the qNameList.
  **
  */

  if (matchQname != PR_TRUE) {
    qnp = PR_NEWZAP(QName);
    PR_ASSERT(qnp != NULL);
    PR_INIT_CLIST(&qnp->link);
    PR_INIT_CLIST(&qnp->rNameList);
    strcpy(qnp->name, qName);
    PR_APPEND_LINK(&qnp->link, &qNameList);
  }

  /* Do we already have a matching RName? */
  if (!PR_CLIST_IS_EMPTY(&qnp->rNameList)) {
    rnp = (RName*)PR_LIST_HEAD(&qnp->rNameList);
    do {
      /*
      ** No duplicate RNames are allowed within a QName
      **
      */

      PR_ASSERT(strcmp(rnp->name, rName));
      rnp = (RName*)PR_NEXT_LINK(&rnp->link);
    } while (rnp != (RName*)&qnp->rNameList);
  }

  /* Get a new RName structure; initialize its members */
  rnp = PR_NEWZAP(RName);
  PR_ASSERT(rnp != NULL);
  PR_INIT_CLIST(&rnp->link);
  strcpy(rnp->name, rName);
  strcpy(rnp->desc, description);
  rnp->lock = PR_NewLock();
  if (rnp->lock == NULL) {
    PR_ASSERT(0);
  }

  PR_APPEND_LINK(&rnp->link, &qnp->rNameList); /* add RName to QName's rnList */
  rnp->qName = qnp; /* point the RName to the QName */

  /* Unlock the Facility */
  PR_Unlock(counterLock);
  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: Create: QName: %s %p, RName: %s %p\n\t", qName, qnp,
          rName, rnp));

  return ((PRCounterHandle)rnp);
/*  end PR_CreateCounter() */

/*
**
*/

PR_IMPLEMENT(void)
PR_DestroyCounter(PRCounterHandle handle) {
  RName* rnp = (RName*)handle;
  QName* qnp = rnp->qName;

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: Deleting: QName: %s, RName: %s", qnp->name, rnp->name));

  /* Lock the Facility */
  PR_Lock(counterLock);

  /*
  ** Remove RName from the list of RNames in QName
  ** and free RName
  */

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: Deleting RName: %s, %p", rnp->name, rnp));
  PR_REMOVE_LINK(&rnp->link);
  PR_Free(rnp->lock);
  PR_DELETE(rnp);

  /*
  ** If this is the last RName within QName
  **   remove QName from the qNameList and free it
  */

  if (PR_CLIST_IS_EMPTY(&qnp->rNameList)) {
    PR_LOG(lm, PR_LOG_DEBUG,
           ("PR_Counter: Deleting unused QName: %s, %p", qnp->name, qnp));
    PR_REMOVE_LINK(&qnp->link);
    PR_DELETE(qnp);
  }

  /* Unlock the Facility */
  PR_Unlock(counterLock);
  return;
/*  end PR_DestroyCounter() */

/*
**
*/

PR_IMPLEMENT(PRCounterHandle)
PR_GetCounterHandleFromName(const char* qName, const char* rName) {
  const char *qn, *rn, *desc;
  PRCounterHandle qh, rh = NULL;
  RName* rnp = NULL;

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: GetCounterHandleFromName:\n\t"
          "QName: %s, RName: %s",
          qName, rName));

  qh = PR_FindNextCounterQname(NULL);
  while (qh != NULL) {
    rh = PR_FindNextCounterRname(NULL, qh);
    while (rh != NULL) {
      PR_GetCounterNameFromHandle(rh, &qn, &rn, &desc);
      if ((strcmp(qName, qn) == 0) && (strcmp(rName, rn) == 0)) {
        rnp = (RName*)rh;
        goto foundIt;
      }
      rh = PR_FindNextCounterRname(rh, qh);
    }
    qh = PR_FindNextCounterQname(NULL);
  }

foundIt:
  PR_LOG(lm, PR_LOG_DEBUG, ("PR_Counter: GetConterHandleFromName: %p", rnp));
  return (rh);
/*  end PR_GetCounterHandleFromName() */

/*
**
*/

PR_IMPLEMENT(void)
PR_GetCounterNameFromHandle(PRCounterHandle handle, const char** qName,
                            const char** rName, const char** description) {
  RName* rnp = (RName*)handle;
  QName* qnp = rnp->qName;

  *qName = qnp->name;
  *rName = rnp->name;
  *description = rnp->desc;

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: GetConterNameFromHandle: "
          "QNp: %p, RNp: %p,\n\tQName: %s, RName: %s, Desc: %s",
          qnp, rnp, qnp->name, rnp->name, rnp->desc));

  return;
/*  end PR_GetCounterNameFromHandle() */

/*
**
*/

PR_IMPLEMENT(void)
PR_IncrementCounter(PRCounterHandle handle) {
  PR_Lock(((RName*)handle)->lock);
  ((RName*)handle)->counter++;
  PR_Unlock(((RName*)handle)->lock);

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: Increment: %p, %ld", handle, ((RName*)handle)->counter));

  return;
/*  end PR_IncrementCounter() */

/*
**
*/

PR_IMPLEMENT(void)
PR_DecrementCounter(PRCounterHandle handle) {
  PR_Lock(((RName*)handle)->lock);
  ((RName*)handle)->counter--;
  PR_Unlock(((RName*)handle)->lock);

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: Decrement: %p, %ld", handle, ((RName*)handle)->counter));

  return;
/*  end PR_DecrementCounter()  */

/*
**
*/

PR_IMPLEMENT(void)
PR_AddToCounter(PRCounterHandle handle, PRUint32 value) {
  PR_Lock(((RName*)handle)->lock);
  ((RName*)handle)->counter += value;
  PR_Unlock(((RName*)handle)->lock);

  PR_LOG(
      lm, PR_LOG_DEBUG,
      ("PR_Counter: AddToCounter: %p, %ld", handle, ((RName*)handle)->counter));

  return;
/*  end PR_AddToCounter() */

/*
**
*/

PR_IMPLEMENT(void)
PR_SubtractFromCounter(PRCounterHandle handle, PRUint32 value) {
  PR_Lock(((RName*)handle)->lock);
  ((RName*)handle)->counter -= value;
  PR_Unlock(((RName*)handle)->lock);

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: SubtractFromCounter: %p, %ld", handle,
          ((RName*)handle)->counter));

  return;
/*  end  PR_SubtractFromCounter() */

/*
**
*/

PR_IMPLEMENT(PRUint32)
PR_GetCounter(PRCounterHandle handle) {
  PR_LOG(
      lm, PR_LOG_DEBUG,
      ("PR_Counter: GetCounter: %p, %ld", handle, ((RName*)handle)->counter));

  return (((RName*)handle)->counter);
/*  end  PR_GetCounter() */

/*
**
*/

PR_IMPLEMENT(void)
PR_SetCounter(PRCounterHandle handle, PRUint32 value) {
  ((RName*)handle)->counter = value;

  PR_LOG(
      lm, PR_LOG_DEBUG,
      ("PR_Counter: SetCounter: %p, %ld", handle, ((RName*)handle)->counter));

  return;
/*  end  PR_SetCounter() */

/*
**
*/

PR_IMPLEMENT(PRCounterHandle)
PR_FindNextCounterQname(PRCounterHandle handle) {
  QName* qnp = (QName*)handle;

  if (PR_CLIST_IS_EMPTY(&qNameList)) {
    qnp = NULL;
  } else if (qnp == NULL) {
    qnp = (QName*)PR_LIST_HEAD(&qNameList);
  } else if (PR_NEXT_LINK(&qnp->link) == &qNameList) {
    qnp = NULL;
  } else {
    qnp = (QName*)PR_NEXT_LINK(&qnp->link);
  }

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: FindNextQname: Handle: %p, Returns: %p", handle, qnp));

  return ((PRCounterHandle)qnp);
/*  end  PR_FindNextCounterQname() */

/*
**
*/

PR_IMPLEMENT(PRCounterHandle)
PR_FindNextCounterRname(PRCounterHandle rhandle, PRCounterHandle qhandle) {
  RName* rnp = (RName*)rhandle;
  QName* qnp = (QName*)qhandle;

  if (PR_CLIST_IS_EMPTY(&qnp->rNameList)) {
    rnp = NULL;
  } else if (rnp == NULL) {
    rnp = (RName*)PR_LIST_HEAD(&qnp->rNameList);
  } else if (PR_NEXT_LINK(&rnp->link) == &qnp->rNameList) {
    rnp = NULL;
  } else {
    rnp = (RName*)PR_NEXT_LINK(&rnp->link);
  }

  PR_LOG(lm, PR_LOG_DEBUG,
         ("PR_Counter: FindNextRname: Rhandle: %p, QHandle: %p, Returns: %p",
          rhandle, qhandle, rnp));

  return ((PRCounterHandle)rnp);
/*  end PR_FindNextCounterRname() */

Messung V0.5
C=88 H=99 G=93

¤ Dauer der Verarbeitung: 0.13 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.