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

Quelle  arena.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:        arena.c
** Description: Testing arenas
**
*/


#include <string.h>
#include <time.h>
#include <stdlib.h>
#include "nspr.h"
#include "plarena.h"
#include "plgetopt.h"

PRLogModuleInfo* tLM;
PRIntn threadCount = 0;
PRMonitor* tMon;
PRBool failed_already = PR_FALSE;

/* Arguments from the command line with default values */
PRIntn debug_mode = 0;
PRIntn poolMin = 4096;
PRIntn poolMax = (100 * 4096);
PRIntn arenaMin = 40;
PRIntn arenaMax = (100 * 40);
PRIntn stressIterations = 15;
PRIntn maxAlloc = (1024 * 1024);
PRIntn stressThreads = 4;

void DumpAll(void) { return; }

/*
** Test Arena allocation.
*/

static void ArenaAllocate(void) {
  PLArenaPool ap;
  void* ptr;
  PRInt32 i;

  PL_InitArenaPool(&ap, "AllocArena", 2048, sizeof(double));
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("AA, InitPool -- Pool: %p. first: %p, current: %p, size: %d", &ap,
          ap.first, ap.current, ap.arenasize));

  for (i = 0; i < 150; i++) {
    PL_ARENA_ALLOCATE(ptr, &ap, 512);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d",
            &ap, ap.first, ap.current, ap.arenasize));
    PR_LOG(tLM, PR_LOG_DEBUG, ("AA -- Pool: %p. alloc: %p ", &ap, ptr));
  }

  PL_FreeArenaPool(&ap);

  for (i = 0; i < 221; i++) {
    PL_ARENA_ALLOCATE(ptr, &ap, 512);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("AA, after alloc -- Pool: %p. first: %p, current: %p, size: %d",
            &ap, ap.first, ap.current, ap.arenasize));
    PR_LOG(tLM, PR_LOG_DEBUG, ("AA -- Pool: %p. alloc: %p ", &ap, ptr));
  }

  PL_FreeArenaPool(&ap);

  return;
/* end ArenaGrow() */
/*
** Test Arena grow.
*/

static void ArenaGrow(void) {
  PLArenaPool ap;
  void* ptr;
  PRInt32 i;

  PL_InitArenaPool(&ap, "TheArena", 4096, sizeof(double));
  PL_ARENA_ALLOCATE(ptr, &ap, 512);

  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Before growth -- Pool: %p. alloc: %p ", &ap, ptr));

  for (i = 0; i < 10; i++) {
    PL_ARENA_GROW(ptr, &ap, 512, 7000);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("After growth -- Pool: %p. alloc: %p ", &ap, ptr));
  }

  return;
/* end ArenaGrow() */

/*
** Test arena Mark and Release.
*/

static void MarkAndRelease(void) {
  PLArenaPool ap;
  void* ptr = NULL;
  void *mark0, *mark1;
  PRIntn i;

  PL_InitArenaPool(&ap, "TheArena", 4096, sizeof(double));
  mark0 = PL_ARENA_MARK(&ap);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("mark0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m0: %p",
          &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark0));

  for (i = 0; i < 201; i++) {
    PL_ARENA_ALLOCATE(ptr, &ap, 512);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
            ap.first.next, ap.current, ap.arenasize, ptr));
  }

  mark1 = PL_ARENA_MARK(&ap);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("mark1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p, m1: %p",
          &ap, ap.first.next, ap.current, ap.arenasize, ptr, mark1));

  for (i = 0; i < 225; i++) {
    PL_ARENA_ALLOCATE(ptr, &ap, 512);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
            ap.first.next, ap.current, ap.arenasize, ptr));
  }

  PL_ARENA_RELEASE(&ap, mark1);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Release-1: %p -- Pool: %p. first: %p, current: %p, size: %d", mark1,
          &ap, ap.first, ap.current, ap.arenasize));

  for (i = 0; i < 20; i++) {
    PL_ARENA_ALLOCATE(ptr, &ap, 512);
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("mr. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
            ap.first.next, ap.current, ap.arenasize, ptr));
  }

  PL_ARENA_RELEASE(&ap, mark1);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Release-1. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
          ap.first.next, ap.current, ap.arenasize, ptr));

  PL_ARENA_RELEASE(&ap, mark0);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Release-0. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
          ap.first.next, ap.current, ap.arenasize, ptr));

  PL_FreeArenaPool(&ap);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Free. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
          ap.first.next, ap.current, ap.arenasize, ptr));

  PL_FinishArenaPool(&ap);
  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Finish. ap: %p, ap.f: %p, ap.c: %p, ap.siz: %d, alloc: %p", &ap,
          ap.first.next, ap.current, ap.arenasize, ptr));

  return;
/* end MarkAndRelease() */

/*
** RandSize() returns a random number in the range
** min..max, rounded to the next doubleword
**
*/

static PRIntn RandSize(PRIntn min, PRIntn max) {
  PRIntn sz = (rand() % (max - min)) + min + sizeof(double);

  sz &= ~sizeof(double) - 1;

  return (sz);
}

/*
** StressThread()
** A bunch of these beat on individual arenas
** This tests the free_list protection.
**
*/

static void PR_CALLBACK StressThread(void* arg) {
  PLArenaPool ap;
  PRIntn i;
  PRIntn sz;
  void* ptr;
  PRThread* tp = PR_GetCurrentThread();

  PR_LOG(tLM, PR_LOG_DEBUG,
         ("Stress Thread %p started\n", PR_GetCurrentThread()));
  PL_InitArenaPool(&ap, "TheArena", RandSize(poolMin, poolMax), sizeof(double));

  for (i = 0; i < stressIterations; i++) {
    PRIntn allocated = 0;

    while (allocated < maxAlloc) {
      sz = RandSize(arenaMin, arenaMax);
      PL_ARENA_ALLOCATE(ptr, &ap, sz);
      if (ptr == NULL) {
        PR_LOG(
            tLM, PR_LOG_ERROR,
            ("ARENA_ALLOCATE() returned NULL\n\tAllocated: %d\n", allocated));
        break;
      }
      allocated += sz;
    }
    PR_LOG(tLM, PR_LOG_DEBUG,
           ("Stress thread %p finished one iteration\n", tp));
    PL_FreeArenaPool(&ap);
  }
  PR_LOG(tLM, PR_LOG_DEBUG, ("Stress thread %p finished all iteration\n", tp));
  PL_FinishArenaPool(&ap);
  PR_LOG(tLM, PR_LOG_DEBUG, ("Stress thread %p after FinishArenaPool()\n", tp));

  /* That's all folks! let's quit */
  PR_EnterMonitor(tMon);
  threadCount--;
  PR_Notify(tMon);
  PR_ExitMonitor(tMon);
  return;
}

/*
** Stress()
** Flog the hell out of arenas multi-threaded.
** Do NOT pass an individual arena to another thread.
**
*/

static void Stress(void) {
  PRThread* tt;
  PRIntn i;

  tMon = PR_NewMonitor();

  for (i = 0; i < stressThreads; i++) {
    PR_EnterMonitor(tMon);
    tt = PR_CreateThread(PR_USER_THREAD, StressThread, NULL, PR_PRIORITY_NORMAL,
                         PR_GLOBAL_THREAD, PR_UNJOINABLE_THREAD, 0);
    threadCount++;
    PR_ExitMonitor(tMon);
  }

  /* Wait for all threads to exit */
  PR_EnterMonitor(tMon);
  while (threadCount != 0) {
    PR_Wait(tMon, PR_INTERVAL_NO_TIMEOUT);
  }
  PR_ExitMonitor(tMon);
  PR_DestroyMonitor(tMon);

  return;
/* end Stress() */

/*
** EvaluateResults()
** uses failed_already to display results and set program
** exit code.
*/

static PRIntn EvaluateResults(void) {
  PRIntn rc = 0;

  if (failed_already == PR_TRUE) {
    PR_LOG(tLM, PR_LOG_DEBUG, ("FAIL\n"));
    rc = 1;
  } else {
    PR_LOG(tLM, PR_LOG_DEBUG, ("PASS\n"));
  }
  return (rc);
/* EvaluateResults() */

void Help(void) {
  printf("arena [options]\n");
  printf("where options are:\n");
  printf("-p minimum size of an arena pool. Default(%d)\n", poolMin);
  printf("-P maximum size of an arena pool. Default(%d)\n", poolMax);
  printf("-a minimum size of an arena allocation. Default(%d)\n",
         arenaMin);
  printf("-A maximum size of an arena allocation. Default(%d)\n",
         arenaMax);
  printf("-i number of iterations in a stress thread. Default(%d)\n",
         stressIterations);
  printf(
      "-s maximum allocation for a single stress thread. Default(%d)\n",
      maxAlloc);
  printf("-t number of stress threads. Default(%d)\n", stressThreads);
  printf("-d enable debug mode\n");
  printf("\n");
  exit(1);
}

PRIntn main(PRIntn argc, char* argv[]) {
  PLOptStatus os;
  PLOptState* opt = PL_CreateOptState(argc, argv, "dhp:P:a:A:i:s:t:");
  while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
    if (PL_OPT_BAD == os) {
      continue;
    }
    switch (opt->option) {
      case 'a'/* arena Min size */
        arenaMin = atol(opt->value);
        break;
      case 'A'/* arena Max size  */
        arenaMax = atol(opt->value);
        break;
      case 'p'/* pool Min size */
        poolMin = atol(opt->value);
        break;
      case 'P'/* pool Max size */
        poolMax = atol(opt->value);
        break;
      case 'i'/* Iterations in stress tests */
        stressIterations = atol(opt->value);
        break;
      case 's'/* storage to get per iteration */
        maxAlloc = atol(opt->value);
        break;
      case 't'/* Number of stress threads to create */
        stressThreads = atol(opt->value);
        break;
      case 'd'/* debug mode */
        debug_mode = 1;
        break;
      case 'h'/* help */
      default:
        Help();
    } /* end switch() */
  } /* end while() */
  PL_DestroyOptState(opt);

  srand((unsigned)time(NULL)); /* seed random number generator */
  tLM = PR_NewLogModule("testcase");

#if 0
    ArenaAllocate();
    ArenaGrow();
#endif

  MarkAndRelease();

  Stress();

  return (EvaluateResults());
/* end main() */

/* arena.c */

Messung V0.5
C=90 H=95 G=92

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