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

Quelle  instrumt.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/. */


/*
** File:    instrumt.c
** Description: This test is for the NSPR debug aids defined in
** prcountr.h, prtrace.h, prolock.h
**
** The test case tests the three debug aids in NSPR:
**
** Diagnostic messages can be enabled using "instrumt -v 6"
** This sets the msgLevel to something that PR_LOG() likes.
** Also define in the environment "NSPR_LOG_MODULES=Test:6"
**
** CounterTest() tests the counter facility. This test
** creates 4 threads. Each thread either increments, decrements,
** adds to or subtracts from a counter, depending on an argument
** passed to the thread at thread-create time. Each of these threads
** does COUNT_LIMIT iterations doing its thing. When all 4 threads
** are done, the result of the counter is evaluated. If all was atomic,
** the the value of the counter should be zero.
**
** TraceTest():
** This test mingles with the counter test. Counters trace.
** A thread to extract trace entries on the fly is started.
** A thread to dump trace entries to a file is started.
**
** OrderedLockTest():
**
**
**
**
**
*/


#include <stdio.h>
#include <plstr.h>
#include <prclist.h>
#include <prmem.h>
#include <plgetopt.h>
#include <prlog.h>
#include <prmon.h>
#include <pratom.h>
#include <prtrace.h>
#include <prcountr.h>
#include <prolock.h>

#define COUNT_LIMIT (10 * (1024))

#define SMALL_TRACE_BUFSIZE (60 * 1024)

typedef enum { CountLoop = 1, TraceLoop = 2, TraceFlow = 3 } TraceTypes;

PRLogModuleLevel msgLevel = PR_LOG_ALWAYS;

PRBool help = PR_FALSE;
PRBool failed = PR_FALSE;

PRLogModuleInfo* lm;
PRMonitor* mon;
PRInt32 activeThreads = 0;
PR_DEFINE_COUNTER(hCounter);
PR_DEFINE_TRACE(hTrace);

static void Help(void) { printf("Help? ... Ha!\n"); }

static void ListCounters(void) {
  PR_DEFINE_COUNTER(qh);
  PR_DEFINE_COUNTER(rh);
  const char *qn, *rn, *dn;
  const char **qname = &qn, **rname = &rn, **desc = &dn;
  PRUint32 tCtr;

  PR_INIT_COUNTER_HANDLE(qh, NULL);
  PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
  while (qh != NULL) {
    PR_INIT_COUNTER_HANDLE(rh, NULL);
    PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh);
    while (rh != NULL) {
      PR_GET_COUNTER_NAME_FROM_HANDLE(rh, qname, rname, desc);
      PR_GET_COUNTER(tCtr, rh);
      PR_LOG(
          lm, msgLevel,
          ("QName: %s RName: %s Desc: %s Value: %ld\n", qn, rn, dn, tCtr));
      PR_FIND_NEXT_COUNTER_RNAME(rh, rh, qh);
    }
    PR_FIND_NEXT_COUNTER_QNAME(qh, qh);
  }
  return;
/* end ListCounters() */

static void ListTraces(void) {
  PR_DEFINE_TRACE(qh);
  PR_DEFINE_TRACE(rh);
  const char *qn, *rn, *dn;
  const char **qname = &qn, **rname = &rn, **desc = &dn;

  PR_INIT_TRACE_HANDLE(qh, NULL);
  PR_FIND_NEXT_TRACE_QNAME(qh, qh);
  while (qh != NULL) {
    PR_INIT_TRACE_HANDLE(rh, NULL);
    PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh);
    while (rh != NULL) {
      PR_GET_TRACE_NAME_FROM_HANDLE(rh, qname, rname, desc);
      PR_LOG(lm, msgLevel, ("QName: %s RName: %s Desc: %s", qn, rn, dn));
      PR_FIND_NEXT_TRACE_RNAME(rh, rh, qh);
    }
    PR_FIND_NEXT_TRACE_QNAME(qh, qh);
  }
  return;
/* end ListCounters() */

static PRInt32 one = 1;
static PRInt32 two = 2;
static PRInt32 three = 3;
static PRInt32 four = 4;

/*
** Thread to iteratively count something.
*/

static void PR_CALLBACK CountSomething(void* arg) {
  PRInt32 switchVar = *((PRInt32*)arg);
  PRInt32 i;

  PR_LOG(lm, msgLevel, ("CountSomething: begin thread %ld", switchVar));

  for (i = 0; i < COUNT_LIMIT; i++) {
    switch (switchVar) {
      case 1:
        PR_INCREMENT_COUNTER(hCounter);
        break;
      case 2:
        PR_DECREMENT_COUNTER(hCounter);
        break;
      case 3:
        PR_ADD_TO_COUNTER(hCounter, 1);
        break;
      case 4:
        PR_SUBTRACT_FROM_COUNTER(hCounter, 1);
        break;
      default:
        PR_ASSERT(0);
        break;
    }
    PR_TRACE(hTrace, CountLoop, switchVar, i, 0, 0, 0, 0, 0);
  } /* end for() */

  PR_LOG(lm, msgLevel, ("CounterSomething: end thread %ld", switchVar));

  PR_EnterMonitor(mon);
  --activeThreads;
  PR_Notify(mon);
  PR_ExitMonitor(mon);

  return;
/* end CountSomething() */

/*
** Create the counter threads.
*/

static void CounterTest(void) {
  PRThread *t1, *t2, *t3, *t4;
  PRIntn i = 0;
  PR_DEFINE_COUNTER(tc);
  PR_DEFINE_COUNTER(zCounter);

  PR_LOG(lm, msgLevel, ("Begin CounterTest"));

  /*
  ** Test Get and Set of a counter.
  **
  */

  PR_CREATE_COUNTER(zCounter, "Atomic""get/set test",
                    "test get and set of counter");
  PR_SET_COUNTER(zCounter, 9);
  PR_GET_COUNTER(i, zCounter);
  if (i != 9) {
    failed = PR_TRUE;
    PR_LOG(lm, msgLevel, ("Counter set/get failed"));
  }

  activeThreads += 4;
  PR_CREATE_COUNTER(hCounter, "Atomic""SMP Tests",
                    "test atomic nature of counter");

  PR_GET_COUNTER_HANDLE_FROM_NAME(tc, "Atomic""SMP Tests");
  PR_ASSERT(tc == hCounter);

  t1 = PR_CreateThread(PR_USER_THREAD, CountSomething, &one, PR_PRIORITY_NORMAL,
                       PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t1);

  t2 = PR_CreateThread(PR_USER_THREAD, CountSomething, &two, PR_PRIORITY_NORMAL,
                       PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t2);

  t3 = PR_CreateThread(PR_USER_THREAD, CountSomething, &three,
                       PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
                       PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t3);

  t4 =
      PR_CreateThread(PR_USER_THREAD, CountSomething, &four, PR_PRIORITY_NORMAL,
                      PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t4);

  PR_LOG(lm, msgLevel, ("Counter Threads started"));

  ListCounters();
  return;
/* end CounterTest() */

/*
** Thread to dump trace buffer to a file.
*/

static void PR_CALLBACK RecordTrace(void* arg) {
  PR_RECORD_TRACE_ENTRIES();

  PR_EnterMonitor(mon);
  --activeThreads;
  PR_Notify(mon);
  PR_ExitMonitor(mon);

  return;
/* end RecordTrace() */

#define NUM_TRACE_RECORDS (10000)
/*
** Thread to extract and print trace entries from the buffer.
*/

static void PR_CALLBACK SampleTrace(void* arg) {
#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
  PRInt32 found, rc;
  PRTraceEntry* foundEntries;
  PRInt32 i;

  foundEntries =
      (PRTraceEntry*)PR_Malloc(NUM_TRACE_RECORDS * sizeof(PRTraceEntry));
  PR_ASSERT(foundEntries != NULL);

  do {
    rc = PR_GetTraceEntries(foundEntries, NUM_TRACE_RECORDS, &found);
    PR_LOG(lm, msgLevel, ("SampleTrace: Lost Data: %ld found: %ld", rc, found));

    if (found != 0) {
      for (i = 0; i < found; i++) {
        PR_LOG(
            lm, msgLevel,
            ("SampleTrace, detail: Thread: %p, Time: %llX, UD0: %ld, UD1: %ld, "
             "UD2: %8.8ld",
             (foundEntries + i)->thread, (foundEntries + i)->time,
             (foundEntries + i)->userData[0], (foundEntries + i)->userData[1],
             (foundEntries + i)->userData[2]));
      }
    }
    PR_Sleep(PR_MillisecondsToInterval(50));
  } while (found != 0 && activeThreads >= 1);

  PR_Free(foundEntries);

  PR_EnterMonitor(mon);
  --activeThreads;
  PR_Notify(mon);
  PR_ExitMonitor(mon);

  PR_LOG(lm, msgLevel, ("SampleTrace(): exiting"));

#endif
  return;
/* end RecordTrace() */

/*
** Basic trace test.
*/

static void TraceTest(void) {
  PRInt32 i;
  PRInt32 size;
  PR_DEFINE_TRACE(th);
  PRThread *t1, *t2;

  PR_LOG(lm, msgLevel, ("Begin TraceTest"));

  size = SMALL_TRACE_BUFSIZE;
  PR_SET_TRACE_OPTION(PRTraceBufSize, &size);
  PR_GET_TRACE_OPTION(PRTraceBufSize, &i);

  PR_CREATE_TRACE(th, "TraceTest""tt2""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt3""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt4""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt5""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt6""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt7""A description for the trace test");
  PR_CREATE_TRACE(th, "TraceTest""tt8""A description for the trace test");

  PR_CREATE_TRACE(th, "Trace Test""tt0",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt1",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt2",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt3",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt4",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt5",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt6",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt7",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt8",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt9",
                  "QName is Trace Test, not TraceTest");
  PR_CREATE_TRACE(th, "Trace Test""tt10",
                  "QName is Trace Test, not TraceTest");

  activeThreads += 2;
  t1 = PR_CreateThread(PR_USER_THREAD, RecordTrace, NULL, PR_PRIORITY_NORMAL,
                       PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t1);

  t2 = PR_CreateThread(PR_USER_THREAD, SampleTrace, 0, PR_PRIORITY_NORMAL,
                       PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
  PR_ASSERT(t2);

  ListTraces();

  PR_GET_TRACE_HANDLE_FROM_NAME(th, "TraceTest""tt1");
  PR_ASSERT(th == hTrace);

  PR_LOG(lm, msgLevel, ("End TraceTest"));
  return;
/* end TraceTest() */

/*
** Ordered lock test.
*/

static void OrderedLockTest(void) {
  PR_LOG(lm, msgLevel, ("Begin OrderedLockTest"));

/* end OrderedLockTest() */

int main(int argc, char** argv) {
#if defined(DEBUG) || defined(FORCE_NSPR_TRACE)
  PRUint32 counter;
  PLOptStatus os;
  PLOptState* opt = PL_CreateOptState(argc, argv, "hdv:");
  lm = PR_NewLogModule("Test");

  while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
    if (PL_OPT_BAD == os) {
      continue;
    }
    switch (opt->option) {
      case 'v'/* verbose mode */
        msgLevel = (PRLogModuleLevel)atol(opt->value);
        break;
      case 'h'/* help message */
        Help();
        help = PR_TRUE;
        break;
      default:
        break;
    }
  }
  PL_DestroyOptState(opt);

  PR_CREATE_TRACE(hTrace, "TraceTest""tt1",
                  "A description for the trace test");
  mon = PR_NewMonitor();
  PR_EnterMonitor(mon);

  TraceTest();
  CounterTest();
  OrderedLockTest();

  /* Wait for all threads to exit */
  while (activeThreads > 0) {
    if (activeThreads == 1) {
      PR_SET_TRACE_OPTION(PRTraceStopRecording, NULL);
    }
    PR_Wait(mon, PR_INTERVAL_NO_TIMEOUT);
    PR_GET_COUNTER(counter, hCounter);
  }
  PR_ExitMonitor(mon);

  /*
  ** Evaluate results
  */

  PR_GET_COUNTER(counter, hCounter);
  if (counter != 0) {
    failed = PR_TRUE;
    PR_LOG(lm, msgLevel, ("Expected counter == 0, found: %ld", counter));
    printf("FAIL\n");
  } else {
    printf("PASS\n");
  }

  PR_DESTROY_COUNTER(hCounter);

  PR_DestroyMonitor(mon);

  PR_TRACE(hTrace, TraceFlow, 0xfff, 0, 0, 0, 0, 0, 0);
  PR_DESTROY_TRACE(hTrace);
#else
  printf("Test not defined\n");
#endif
  return 0;
/* main() */
/* end instrumt.c */

Messung V0.5
C=95 H=79 G=87

¤ Dauer der Verarbeitung: 0.11 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.