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 20 kB image not shown  

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


#include "prio.h"
#include "prprf.h"
#include "prlog.h"
#include "prmem.h"
#include "pratom.h"
#include "prlock.h"
#include "prmwait.h"
#include "prclist.h"
#include "prerror.h"
#include "prinrval.h"
#include "prnetdb.h"
#include "prthread.h"

#include "plstr.h"
#include "plerror.h"
#include "plgetopt.h"

#include <string.h>

typedef struct Shared {
  const char* title;
  PRLock* list_lock;
  PRWaitGroup* group;
  PRIntervalTime timeout;
} Shared;

typedef enum Verbosity { silent, quiet, chatty, noisy } Verbosity;

#ifdef DEBUG
#  define PORT_INC_DO +100
#else
#  define PORT_INC_DO
#endif
#ifdef IS_64
#  define PORT_INC_3264 +200
#else
#  define PORT_INC_3264
#endif

static PRFileDesc* debug = NULL;
static PRInt32 desc_allocated = 0;
static PRUint16 default_port = 12273 PORT_INC_DO PORT_INC_3264;
static enum Verbosity verbosity = quiet;
static PRInt32 ops_required = 1000, ops_done = 0;
static PRThreadScope thread_scope = PR_LOCAL_THREAD;
static PRIntn client_threads = 20, worker_threads = 2, wait_objects = 50;

#if defined(DEBUG)
#  define MW_ASSERT(_expr) \
    ((_expr) ? ((void)0) : _MW_Assert(#_expr, __FILE__, __LINE__))
static void _MW_Assert(const char* s, const char* file, PRIntn ln) {
  if (NULL != debug) {
    PL_FPrintError(debug, NULL);
  }
  PR_Assert(s, file, ln);
/* _MW_Assert */
#else
#  define MW_ASSERT(_expr)
#endif

static void PrintRecvDesc(PRRecvWait* desc, const char* msg) {
  const char* tag[] = {"PR_MW_INTERRUPT""PR_MW_TIMEOUT""PR_MW_FAILURE",
                       "PR_MW_SUCCESS""PR_MW_PENDING"};
  PR_fprintf(debug, "%s: PRRecvWait(@0x%x): {fd: 0x%x, outcome: %s, tmo: %u}\n",
             msg, desc, desc->fd, tag[desc->outcome + 3], desc->timeout);
/* PrintRecvDesc */

static Shared* MakeShared(const char* title) {
  Shared* shared = PR_NEWZAP(Shared);
  shared->group = PR_CreateWaitGroup(1);
  shared->timeout = PR_SecondsToInterval(1);
  shared->list_lock = PR_NewLock();
  shared->title = title;
  return shared;
/* MakeShared */

static void DestroyShared(Shared* shared) {
  PRStatus rv;
  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: destroying group\n", shared->title);
  }
  rv = PR_DestroyWaitGroup(shared->group);
  MW_ASSERT(PR_SUCCESS == rv);
  PR_DestroyLock(shared->list_lock);
  PR_DELETE(shared);
/* DestroyShared */

static PRRecvWait* CreateRecvWait(PRFileDesc* fd, PRIntervalTime timeout) {
  PRRecvWait* desc_out = PR_NEWZAP(PRRecvWait);
  MW_ASSERT(NULL != desc_out);

  MW_ASSERT(NULL != fd);
  desc_out->fd = fd;
  desc_out->timeout = timeout;
  desc_out->buffer.length = 120;
  desc_out->buffer.start = PR_CALLOC(120);

  PR_AtomicIncrement(&desc_allocated);

  if (verbosity > chatty) {
    PrintRecvDesc(desc_out, "Allocated");
  }
  return desc_out;
/* CreateRecvWait */

static void DestroyRecvWait(PRRecvWait* desc_out) {
  if (verbosity > chatty) {
    PrintRecvDesc(desc_out, "Destroying");
  }
  PR_Close(desc_out->fd);
  if (NULL != desc_out->buffer.start) {
    PR_DELETE(desc_out->buffer.start);
  }
  PR_Free(desc_out);
  (void)PR_AtomicDecrement(&desc_allocated);
/* DestroyRecvWait */

static void CancelGroup(Shared* shared) {
  PRRecvWait* desc_out;

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s Reclaiming wait descriptors\n", shared->title);
  }

  do {
    desc_out = PR_CancelWaitGroup(shared->group);
    if (NULL != desc_out) {
      DestroyRecvWait(desc_out);
    }
  } while (NULL != desc_out);

  MW_ASSERT(0 == desc_allocated);
  MW_ASSERT(PR_GROUP_EMPTY_ERROR == PR_GetError());
/* CancelGroup */

static void PR_CALLBACK ClientThread(void* arg) {
  PRStatus rv;
  PRInt32 bytes;
  PRIntn empty_flags = 0;
  PRNetAddr server_address;
  unsigned char buffer[100];
  Shared* shared = (Shared*)arg;
  PRFileDesc* server = PR_NewTCPSocket();
  if ((NULL == server) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) {
    return;
  }
  MW_ASSERT(NULL != server);

  if (verbosity > chatty) {
    PR_fprintf(debug, "%s: Server socket @0x%x\n", shared->title, server);
  }

  /* Initialize the buffer so that Purify won't complain */
  memset(buffer, 0, sizeof(buffer));

  rv = PR_InitializeNetAddr(PR_IpAddrLoopback, default_port, &server_address);
  MW_ASSERT(PR_SUCCESS == rv);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: Client opening connection\n", shared->title);
  }
  rv = PR_Connect(server, &server_address, PR_INTERVAL_NO_TIMEOUT);

  if (PR_FAILURE == rv) {
    if (verbosity > silent) {
      PL_FPrintError(debug, "Client connect failed");
    }
    return;
  }

  while (ops_done < ops_required) {
    bytes = PR_Send(server, buffer, sizeof(buffer), empty_flags,
                    PR_INTERVAL_NO_TIMEOUT);
    if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) {
      break;
    }
    MW_ASSERT(sizeof(buffer) == bytes);
    if (verbosity > chatty)
      PR_fprintf(debug, "%s: Client sent %d bytes\n", shared->title,
                 sizeof(buffer));
    bytes = PR_Recv(server, buffer, sizeof(buffer), empty_flags,
                    PR_INTERVAL_NO_TIMEOUT);
    if (verbosity > chatty)
      PR_fprintf(debug, "%s: Client received %d bytes\n", shared->title,
                 sizeof(buffer));
    if ((-1 == bytes) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) {
      break;
    }
    MW_ASSERT(sizeof(buffer) == bytes);
    PR_Sleep(shared->timeout);
  }
  rv = PR_Close(server);
  MW_ASSERT(PR_SUCCESS == rv);

/* ClientThread */

static void OneInThenCancelled(Shared* shared) {
  PRStatus rv;
  PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);

  shared->timeout = PR_INTERVAL_NO_TIMEOUT;

  desc_in->fd = PR_NewTCPSocket();
  desc_in->timeout = shared->timeout;

  if (verbosity > chatty) {
    PrintRecvDesc(desc_in, "Adding desc");
  }

  rv = PR_AddWaitFileDesc(shared->group, desc_in);
  MW_ASSERT(PR_SUCCESS == rv);

  if (verbosity > chatty) {
    PrintRecvDesc(desc_in, "Cancelling");
  }
  rv = PR_CancelWaitFileDesc(shared->group, desc_in);
  MW_ASSERT(PR_SUCCESS == rv);

  desc_out = PR_WaitRecvReady(shared->group);
  MW_ASSERT(desc_out == desc_in);
  MW_ASSERT(PR_MW_INTERRUPT == desc_out->outcome);
  MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
  if (verbosity > chatty) {
    PrintRecvDesc(desc_out, "Ready");
  }

  rv = PR_Close(desc_in->fd);
  MW_ASSERT(PR_SUCCESS == rv);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: destroying group\n", shared->title);
  }

  PR_DELETE(desc_in);
/* OneInThenCancelled */

static void OneOpOneThread(Shared* shared) {
  PRStatus rv;
  PRRecvWait *desc_out, *desc_in = PR_NEWZAP(PRRecvWait);

  desc_in->fd = PR_NewTCPSocket();
  desc_in->timeout = shared->timeout;

  if (verbosity > chatty) {
    PrintRecvDesc(desc_in, "Adding desc");
  }

  rv = PR_AddWaitFileDesc(shared->group, desc_in);
  MW_ASSERT(PR_SUCCESS == rv);
  desc_out = PR_WaitRecvReady(shared->group);
  MW_ASSERT(desc_out == desc_in);
  MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
  MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
  if (verbosity > chatty) {
    PrintRecvDesc(desc_out, "Ready");
  }

  rv = PR_Close(desc_in->fd);
  MW_ASSERT(PR_SUCCESS == rv);

  PR_DELETE(desc_in);
/* OneOpOneThread */

static void ManyOpOneThread(Shared* shared) {
  PRStatus rv;
  PRIntn index;
  PRRecvWait* desc_in;
  PRRecvWait* desc_out;

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: adding %d descs\n", shared->title, wait_objects);
  }

  for (index = 0; index < wait_objects; ++index) {
    desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);

    rv = PR_AddWaitFileDesc(shared->group, desc_in);
    MW_ASSERT(PR_SUCCESS == rv);
  }

  while (ops_done < ops_required) {
    desc_out = PR_WaitRecvReady(shared->group);
    MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
    MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
    if (verbosity > chatty) {
      PrintRecvDesc(desc_out, "Ready/readding");
    }
    rv = PR_AddWaitFileDesc(shared->group, desc_out);
    MW_ASSERT(PR_SUCCESS == rv);
    (void)PR_AtomicIncrement(&ops_done);
  }

  CancelGroup(shared);
/* ManyOpOneThread */

static void PR_CALLBACK SomeOpsThread(void* arg) {
  PRRecvWait* desc_out;
  PRStatus rv = PR_SUCCESS;
  Shared* shared = (Shared*)arg;
  do /* until interrupted */
  {
    desc_out = PR_WaitRecvReady(shared->group);
    if (NULL == desc_out) {
      MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
      if (verbosity > quiet) {
        PR_fprintf(debug, "Aborted\n");
      }
      break;
    }
    MW_ASSERT(PR_MW_TIMEOUT == desc_out->outcome);
    MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
    if (verbosity > chatty) {
      PrintRecvDesc(desc_out, "Ready");
    }

    if (verbosity > chatty) {
      PrintRecvDesc(desc_out, "Re-Adding");
    }
    desc_out->timeout = shared->timeout;
    rv = PR_AddWaitFileDesc(shared->group, desc_out);
    PR_AtomicIncrement(&ops_done);
    if (ops_done > ops_required) {
      break;
    }
  } while (PR_SUCCESS == rv);
  MW_ASSERT(PR_SUCCESS == rv);
/* SomeOpsThread */

static void SomeOpsSomeThreads(Shared* shared) {
  PRStatus rv;
  PRThread** thread;
  PRIntn index;
  PRRecvWait* desc_in;

  thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);

  /* Create some threads */

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: creating threads\n", shared->title);
  }
  for (index = 0; index < worker_threads; ++index) {
    thread[index] =
        PR_CreateThread(PR_USER_THREAD, SomeOpsThread, shared, PR_PRIORITY_HIGH,
                        thread_scope, PR_JOINABLE_THREAD, 16 * 1024);
  }

  /* then create some operations */
  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: creating desc\n", shared->title);
  }
  for (index = 0; index < wait_objects; ++index) {
    desc_in = CreateRecvWait(PR_NewTCPSocket(), shared->timeout);
    rv = PR_AddWaitFileDesc(shared->group, desc_in);
    MW_ASSERT(PR_SUCCESS == rv);
  }

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: sleeping\n", shared->title);
  }
  while (ops_done < ops_required) {
    PR_Sleep(shared->timeout);
  }

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: interrupting/joining threads\n", shared->title);
  }
  for (index = 0; index < worker_threads; ++index) {
    rv = PR_Interrupt(thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
    rv = PR_JoinThread(thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
  }
  PR_DELETE(thread);

  CancelGroup(shared);
/* SomeOpsSomeThreads */

static PRStatus ServiceRequest(Shared* shared, PRRecvWait* desc) {
  PRInt32 bytes_out;

  if (verbosity > chatty)
    PR_fprintf(debug, "%s: Service received %d bytes\n", shared->title,
               desc->bytesRecv);

  if (0 == desc->bytesRecv) {
    goto quitting;
  }
  if ((-1 == desc->bytesRecv) &&
      (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) {
    goto aborted;
  }

  bytes_out = PR_Send(desc->fd, desc->buffer.start, desc->bytesRecv, 0,
                      shared->timeout);
  if (verbosity > chatty)
    PR_fprintf(debug, "%s: Service sent %d bytes\n", shared->title, bytes_out);

  if ((-1 == bytes_out) && (PR_PENDING_INTERRUPT_ERROR == PR_GetError())) {
    goto aborted;
  }
  MW_ASSERT(bytes_out == desc->bytesRecv);

  return PR_SUCCESS;

aborted:
quitting:
  return PR_FAILURE;
/* ServiceRequest */

static void PR_CALLBACK ServiceThread(void* arg) {
  PRStatus rv = PR_SUCCESS;
  PRRecvWait* desc_out = NULL;
  Shared* shared = (Shared*)arg;
  do /* until interrupted */
  {
    if (NULL != desc_out) {
      desc_out->timeout = PR_INTERVAL_NO_TIMEOUT;
      if (verbosity > chatty) {
        PrintRecvDesc(desc_out, "Service re-adding");
      }
      rv = PR_AddWaitFileDesc(shared->group, desc_out);
      MW_ASSERT(PR_SUCCESS == rv);
    }

    desc_out = PR_WaitRecvReady(shared->group);
    if (NULL == desc_out) {
      MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
      break;
    }

    switch (desc_out->outcome) {
      case PR_MW_SUCCESS: {
        PR_AtomicIncrement(&ops_done);
        if (verbosity > chatty) {
          PrintRecvDesc(desc_out, "Service ready");
        }
        rv = ServiceRequest(shared, desc_out);
        break;
      }
      case PR_MW_INTERRUPT:
        MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());
        rv = PR_FAILURE; /* if interrupted, then exit */
        break;
      case PR_MW_TIMEOUT:
        MW_ASSERT(PR_IO_TIMEOUT_ERROR == PR_GetError());
      case PR_MW_FAILURE:
        if (verbosity > silent) {
          PL_FPrintError(debug, "RecvReady failure");
        }
        break;
      default:
        break;
    }
  } while (PR_SUCCESS == rv);

  if (NULL != desc_out) {
    DestroyRecvWait(desc_out);
  }

/* ServiceThread */

static void PR_CALLBACK EnumerationThread(void* arg) {
  PRStatus rv;
  PRIntn count;
  PRRecvWait* desc;
  Shared* shared = (Shared*)arg;
  PRIntervalTime five_seconds = PR_SecondsToInterval(5);
  PRMWaitEnumerator* enumerator = PR_CreateMWaitEnumerator(shared->group);
  MW_ASSERT(NULL != enumerator);

  while (PR_SUCCESS == PR_Sleep(five_seconds)) {
    count = 0;
    desc = NULL;
    while (NULL != (desc = PR_EnumerateWaitGroup(enumerator, desc))) {
      if (verbosity > chatty) {
        PrintRecvDesc(desc, shared->title);
      }
      count += 1;
    }
    if (verbosity > silent)
      PR_fprintf(debug, "%s Enumerated %d objects\n", shared->title, count);
  }

  MW_ASSERT(PR_PENDING_INTERRUPT_ERROR == PR_GetError());

  rv = PR_DestroyMWaitEnumerator(enumerator);
  MW_ASSERT(PR_SUCCESS == rv);
/* EnumerationThread */

static void PR_CALLBACK ServerThread(void* arg) {
  PRStatus rv;
  PRIntn index;
  PRRecvWait* desc_in;
  PRThread** worker_thread;
  Shared* shared = (Shared*)arg;
  PRFileDesc *listener, *service;
  PRNetAddr server_address, client_address;

  worker_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * worker_threads);
  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: Server creating worker_threads\n", shared->title);
  }
  for (index = 0; index < worker_threads; ++index) {
    worker_thread[index] =
        PR_CreateThread(PR_USER_THREAD, ServiceThread, shared, PR_PRIORITY_HIGH,
                        thread_scope, PR_JOINABLE_THREAD, 16 * 1024);
  }

  rv = PR_InitializeNetAddr(PR_IpAddrAny, default_port, &server_address);
  MW_ASSERT(PR_SUCCESS == rv);

  listener = PR_NewTCPSocket();
  MW_ASSERT(NULL != listener);
  if (verbosity > chatty)
    PR_fprintf(debug, "%s: Server listener socket @0x%x\n", shared->title,
               listener);
  rv = PR_Bind(listener, &server_address);
  MW_ASSERT(PR_SUCCESS == rv);
  rv = PR_Listen(listener, 10);
  MW_ASSERT(PR_SUCCESS == rv);
  while (ops_done < ops_required) {
    if (verbosity > quiet) {
      PR_fprintf(debug, "%s: Server accepting connection\n", shared->title);
    }
    service = PR_Accept(listener, &client_address, PR_INTERVAL_NO_TIMEOUT);
    if (NULL == service) {
      if (PR_PENDING_INTERRUPT_ERROR == PR_GetError()) {
        break;
      }
      PL_PrintError("Accept failed");
      MW_ASSERT(PR_FALSE && "Accept failed");
    } else {
      desc_in = CreateRecvWait(service, shared->timeout);
      desc_in->timeout = PR_INTERVAL_NO_TIMEOUT;
      if (verbosity > chatty) {
        PrintRecvDesc(desc_in, "Service adding");
      }
      rv = PR_AddWaitFileDesc(shared->group, desc_in);
      MW_ASSERT(PR_SUCCESS == rv);
    }
  }

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: Server interrupting worker_threads\n",
               shared->title);
  }
  for (index = 0; index < worker_threads; ++index) {
    rv = PR_Interrupt(worker_thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
    rv = PR_JoinThread(worker_thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
  }
  PR_DELETE(worker_thread);

  PR_Close(listener);

  CancelGroup(shared);

/* ServerThread */

static void RealOneGroupIO(Shared* shared) {
  /*
  ** Create a server that listens for connections and then services
  ** requests that come in over those connections. The server never
  ** deletes a connection and assumes a basic RPC model of operation.
  **
  ** Use worker_threads threads to service how every many open ports
  ** there might be.
  **
  ** Oh, ya. Almost forget. Create (some) clients as well.
  */

  PRStatus rv;
  PRIntn index;
  PRThread *server_thread, *enumeration_thread, **client_thread;

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: creating server_thread\n", shared->title);
  }

  server_thread =
      PR_CreateThread(PR_USER_THREAD, ServerThread, shared, PR_PRIORITY_HIGH,
                      thread_scope, PR_JOINABLE_THREAD, 16 * 1024);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: creating enumeration_thread\n", shared->title);
  }

  enumeration_thread = PR_CreateThread(PR_USER_THREAD, EnumerationThread,
                                       shared, PR_PRIORITY_HIGH, thread_scope,
                                       PR_JOINABLE_THREAD, 16 * 1024);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: snoozing before creating clients\n", shared->title);
  }
  PR_Sleep(5 * shared->timeout);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: creating client_threads\n", shared->title);
  }
  client_thread = (PRThread**)PR_CALLOC(sizeof(PRThread*) * client_threads);
  for (index = 0; index < client_threads; ++index) {
    client_thread[index] = PR_CreateThread(PR_USER_THREAD, ClientThread, shared,
                                           PR_PRIORITY_NORMAL, thread_scope,
                                           PR_JOINABLE_THREAD, 16 * 1024);
  }

  while (ops_done < ops_required) {
    PR_Sleep(shared->timeout);
  }

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: interrupting/joining client_threads\n",
               shared->title);
  }
  for (index = 0; index < client_threads; ++index) {
    rv = PR_Interrupt(client_thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
    rv = PR_JoinThread(client_thread[index]);
    MW_ASSERT(PR_SUCCESS == rv);
  }
  PR_DELETE(client_thread);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: interrupting/joining enumeration_thread\n",
               shared->title);
  }
  rv = PR_Interrupt(enumeration_thread);
  MW_ASSERT(PR_SUCCESS == rv);
  rv = PR_JoinThread(enumeration_thread);
  MW_ASSERT(PR_SUCCESS == rv);

  if (verbosity > quiet) {
    PR_fprintf(debug, "%s: interrupting/joining server_thread\n",
               shared->title);
  }
  rv = PR_Interrupt(server_thread);
  MW_ASSERT(PR_SUCCESS == rv);
  rv = PR_JoinThread(server_thread);
  MW_ASSERT(PR_SUCCESS == rv);
/* RealOneGroupIO */

static void RunThisOne(void (*func)(Shared*), const char* name,
                       const char* test_name) {
  Shared* shared;
  if ((NULL == test_name) || (0 == PL_strcmp(name, test_name))) {
    if (verbosity > silent) {
      PR_fprintf(debug, "%s()\n", name);
    }
    shared = MakeShared(name);
    ops_done = 0;
    func(shared); /* run the test */
    MW_ASSERT(0 == desc_allocated);
    DestroyShared(shared);
  }
/* RunThisOne */

static Verbosity ChangeVerbosity(Verbosity verbosity, PRIntn delta) {
  return (Verbosity)(((PRIntn)verbosity) + delta);
/* ChangeVerbosity */

int main(int argc, char** argv) {
  PLOptStatus os;
  const char* test_name = NULL;
  PLOptState* opt = PL_CreateOptState(argc, argv, "dqGc:o:p:t:w:");

  while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
    if (PL_OPT_BAD == os) {
      continue;
    }
    switch (opt->option) {
      case 0:
        test_name = opt->value;
        break;
      case 'd'/* debug mode */
        if (verbosity < noisy) {
          verbosity = ChangeVerbosity(verbosity, 1);
        }
        break;
      case 'q'/* debug mode */
        if (verbosity > silent) {
          verbosity = ChangeVerbosity(verbosity, -1);
        }
        break;
      case 'G'/* use global threads */
        thread_scope = PR_GLOBAL_THREAD;
        break;
      case 'c'/* number of client threads */
        client_threads = atoi(opt->value);
        break;
      case 'o'/* operations to compelete */
        ops_required = atoi(opt->value);
        break;
      case 'p'/* default port */
        default_port = atoi(opt->value);
        break;
      case 't'/* number of threads waiting */
        worker_threads = atoi(opt->value);
        break;
      case 'w'/* number of wait objects */
        wait_objects = atoi(opt->value);
        break;
      default:
        break;
    }
  }
  PL_DestroyOptState(opt);

  if (verbosity > 0) {
    debug = PR_GetSpecialFD(PR_StandardError);
  }

  RunThisOne(OneInThenCancelled, "OneInThenCancelled", test_name);
  RunThisOne(OneOpOneThread, "OneOpOneThread", test_name);
  RunThisOne(ManyOpOneThread, "ManyOpOneThread", test_name);
  RunThisOne(SomeOpsSomeThreads, "SomeOpsSomeThreads", test_name);
  RunThisOne(RealOneGroupIO, "RealOneGroupIO", test_name);
  return 0;
/* main */

/* multwait.c */

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

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