Back to index

lightning-sunbird  0.9+nobinonly
Classes | Defines | Typedefs | Functions | Variables
pollable.c File Reference
#include "prinit.h"
#include "prio.h"
#include "prthread.h"
#include "prerror.h"
#include "prmem.h"
#include "prlog.h"
#include "prprf.h"
#include "plgetopt.h"
#include <stdlib.h>

Go to the source code of this file.

Classes

struct  ThreadData

Defines

#define DEFAULT_THREADS   10
#define DEFAULT_LOOPS   100

Typedefs

typedef struct ThreadData ThreadData

Functions

void ThreadRoutine (void *arg)
static void Help (void)
int main (int argc, char **argv)
 The Xalan testcases app.

Variables

PRIntn numThreads = DEFAULT_THREADS
PRIntn numIterations = DEFAULT_LOOPS
PRIntervalTime dally = PR_INTERVAL_NO_WAIT
PRFileDescdebug_out = NULL
PRBool debug_mode = PR_FALSE
PRBool verbosity = PR_FALSE

Class Documentation

struct ThreadData

Definition at line 290 of file sqliteInt.h.

Collaboration diagram for ThreadData:
Class Members
CERTCertificate * cert
int client
int data_read
int data_sent
int data_tosend
int dummy
PRFileDesc * event
int exit_code
PRFileDesc * fd
int index
PRNetAddr na
struct ThreadData * next
BtShared * pBtree
PRPollDesc pd
struct ThreadData * peer
CERTCertificate * peercert
int peerport
PRFileDesc * r
char recvbuf
PRFileDesc * s
int secerr
int secerr_flag
char sendbuf
int state
char * status_cipher
char * status_issuer
int status_keysize
int status_on
int status_skeysize
char * status_subject
PRThread * subthread
PyThreadState * ts
u8 useSharedData
unsigned char xor_reading
unsigned char xor_writing

Define Documentation

#define DEFAULT_LOOPS   100

Definition at line 58 of file pollable.c.

Definition at line 57 of file pollable.c.


Typedef Documentation

typedef struct ThreadData ThreadData

Function Documentation

static void Help ( void  ) [static]

Definition at line 111 of file pollable.c.

{
    debug_out = PR_STDOUT;

    PR_fprintf(
            debug_out, "Usage: pollable [-c n] [-t n] [-d] [-v] [-G] [-C n] [-D n]\n");
    PR_fprintf(
            debug_out, "-c n\tloops at thread level (default: %d)\n", DEFAULT_LOOPS);
    PR_fprintf(
            debug_out, "-t n\tnumber of threads (default: %d)\n", DEFAULT_THREADS);
    PR_fprintf(debug_out, "-d\tturn on debugging output (default: FALSE)\n");
    PR_fprintf(debug_out, "-v\tturn on verbose output (default: FALSE)\n");
    PR_fprintf(debug_out, "-G\tglobal threads only (default: FALSE)\n");
    PR_fprintf(debug_out, "-C n\tconcurrency setting (default: 1)\n");
    PR_fprintf(debug_out, "-D n\tdally setting (msecs) (default: 0)\n");
}  /* Help */
int main ( int  argc,
char **  argv 
)

The Xalan testcases app.

Definition at line 128 of file pollable.c.

{
    ThreadData selfData;
    ThreadData *data;
    PRThread **thread;
    void *block;
    PRIntn i;
    PRIntervalTime timeStart, timeEnd;
    PRPollDesc pd;
    PRInt32 rv;
    PRThreadScope thread_scope = PR_LOCAL_THREAD;
    PRBool help = PR_FALSE;
    PRUintn concurrency = 1;
    PRUintn average;
    PLOptStatus os;
    PLOptState *opt;

    PR_STDIO_INIT();

    opt = PL_CreateOptState(argc, argv, "hdvc:t:C:GD:");
    while (PL_OPT_EOL != (os = PL_GetNextOpt(opt))) {
        if (PL_OPT_BAD == os) {
            continue;
        }
        switch (opt->option) {
            case 'v':  /* verbose mode */
                verbosity = PR_TRUE;
            case 'd':  /* debug mode */
                debug_mode = PR_TRUE;
                break;
            case 'c':  /* loop counter */
                numIterations = atoi(opt->value);
                break;
            case 't':  /* thread limit */
                numThreads = atoi(opt->value);
                break;
            case 'C':  /* Concurrency limit */
                concurrency = atoi(opt->value);
                break;
            case 'G':  /* global threads only */
                thread_scope = PR_GLOBAL_THREAD;
                break;
            case 'D':  /* dally */
                dally = PR_MillisecondsToInterval(atoi(opt->value));
                break;
            case 'h':  /* help message */
                Help();
                help = PR_TRUE;
                break;
            default:
                break;
        }
    }
    PL_DestroyOptState(opt);

    if (help) {
        return 1;
    }

    if (concurrency > 1) {
        PR_SetConcurrency(concurrency);
    }

    if (PR_TRUE == debug_mode) {
        debug_out = PR_STDOUT;
       PR_fprintf(debug_out, "Test parameters\n");
        PR_fprintf(debug_out, "\tThreads involved: %d\n", numThreads);
        PR_fprintf(debug_out, "\tIteration limit: %d\n", numIterations);
        PR_fprintf(debug_out, "\tConcurrency: %d\n", concurrency);
        PR_fprintf(debug_out, "\tThread type: %s\n",
                (PR_GLOBAL_THREAD == thread_scope) ? "GLOBAL" : "LOCAL");
    }

    /*
     * Malloc a block of memory and divide it into data and thread.
     */
    block = PR_MALLOC(numThreads * (sizeof(ThreadData) + sizeof(PRThread *)));
    if (block == NULL) {
        PR_fprintf(PR_STDERR, "cannot malloc, failed\n");
        exit(1);
    }
    data = (ThreadData *) block;
    thread = (PRThread **) &data[numThreads];

    /* Pollable event */
    selfData.event = PR_NewPollableEvent();
    if (selfData.event == NULL) {
        PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
                PR_GetError(), PR_GetOSError());
        exit(1);
    }
    selfData.next = &data[0];
    for (i = 0; i < numThreads; i++) {
        data[i].event = PR_NewPollableEvent();
        if (data[i].event == NULL) {
            PR_fprintf(PR_STDERR, "cannot create event: (%ld, %ld)\n",
                    PR_GetError(), PR_GetOSError());
            exit(1);
        }
        data[i].index = i;
        if (i != numThreads - 1) {
            data[i].next = &data[i + 1];
        } else {
            data[i].next = &selfData;
        }

        thread[i] = PR_CreateThread(PR_USER_THREAD,
                ThreadRoutine, &data[i], PR_PRIORITY_NORMAL,
                thread_scope, PR_JOINABLE_THREAD, 0);
        if (thread[i] == NULL) {
            PR_fprintf(PR_STDERR, "cannot create thread\n");
            exit(1);
        }
    }

    timeStart = PR_IntervalNow();
    pd.fd = selfData.event;
    pd.in_flags = PR_POLL_READ;
    for (i = 0; i < numIterations; i++) {
        if (dally != PR_INTERVAL_NO_WAIT) {
            PR_Sleep(dally);
        }
        if (verbosity) {
            PR_fprintf(debug_out, "main thread posting event\n");
        }
        if (PR_SetPollableEvent(selfData.next->event) == PR_FAILURE) {
            PR_fprintf(PR_STDERR, "set event failed\n");
            exit(1);
        }
        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
        if (rv == -1) {
            PR_fprintf(PR_STDERR, "wait failed\n");
            exit(1);
        }
        PR_ASSERT(rv != 0);
        PR_ASSERT(pd.out_flags & PR_POLL_READ);
        if (verbosity) {
            PR_fprintf(debug_out, "main thread awakened\n");
        }
       if (PR_WaitForPollableEvent(selfData.event) == PR_FAILURE) {
            PR_fprintf(PR_STDERR, "consume event failed\n");
            exit(1);
        }
    }
    timeEnd = PR_IntervalNow();

    if (debug_mode) {
        average = PR_IntervalToMicroseconds(timeEnd - timeStart)
                / (numIterations * numThreads);
        PR_fprintf(debug_out, "Average switch times %d usecs for %d threads\n",
                average, numThreads);
    }

    for (i = 0; i < numThreads; i++) {
        if (PR_JoinThread(thread[i]) == PR_FAILURE) {
            PR_fprintf(PR_STDERR, "join thread failed\n");
            exit(1);
        }
        PR_DestroyPollableEvent(data[i].event);
    }
    PR_DELETE(block);
       PR_DestroyPollableEvent(selfData.event);

    PR_fprintf(PR_STDOUT, "PASSED\n");
    return 0;
}

Here is the call graph for this function:

void ThreadRoutine ( void arg)

Definition at line 73 of file pollable.c.

{
    ThreadData *data = (ThreadData *) arg;
    PRIntn i;
    PRPollDesc pd;
    PRInt32 rv;

    pd.fd = data->event;
    pd.in_flags = PR_POLL_READ;

    for (i = 0; i < numIterations; i++) {
        rv = PR_Poll(&pd, 1, PR_INTERVAL_NO_TIMEOUT);
        if (rv == -1) {
            PR_fprintf(PR_STDERR, "PR_Poll failed\n");
            exit(1);
        }
        if (verbosity) {
            PR_fprintf(debug_out, "thread %d awakened\n", data->index);
        }
        PR_ASSERT(rv != 0);
        PR_ASSERT(pd.out_flags & PR_POLL_READ);
        if (PR_WaitForPollableEvent(data->event) == PR_FAILURE) {
            PR_fprintf(PR_STDERR, "consume event failed\n");
            exit(1);
        }
        if (dally != PR_INTERVAL_NO_WAIT) {
            PR_Sleep(dally);
        }
        if (verbosity) {
            PR_fprintf(debug_out, "thread %d posting event\n", data->index);
        }
        if (PR_SetPollableEvent(data->next->event) == PR_FAILURE) {
            PR_fprintf(PR_STDERR, "post event failed\n");
            exit(1);
        }
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 62 of file pollable.c.

Definition at line 64 of file pollable.c.

Definition at line 63 of file pollable.c.

Definition at line 61 of file pollable.c.

Definition at line 60 of file pollable.c.

Definition at line 65 of file pollable.c.