//
//********************************************************************
//   Copyright (C) 2002, International Business Machines
//   Corporation and others.  All Rights Reserved.
//********************************************************************
//
// File threadtest.cpp
//

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

#include "unicode/utypes.h"
#include "unicode/uclean.h"
#include "umutex.h"
#include "threadtest.h"


//------------------------------------------------------------------------------
//
//   Factory functions for creating different test types.
//
//------------------------------------------------------------------------------
extern  AbstractThreadTest *createStringTest();
extern  AbstractThreadTest *createConvertTest();



//------------------------------------------------------------------------------
//
//   Windows specific code for starting threads
//
//------------------------------------------------------------------------------
#ifdef WIN32

#include "Windows.h"
#include "process.h"



typedef void (*ThreadFunc)(void *);

class ThreadFuncs           // This class isolates OS dependent threading
{                           //   functions from the rest of ThreadTest program.
public:
    static void            Sleep(int millis) {::Sleep(millis);};
    static void            startThread(ThreadFunc, void *param);
    static unsigned long   getCurrentMillis();
    static void            yield() {::Sleep(0);};
};

void ThreadFuncs::startThread(ThreadFunc func, void *param)
{
    unsigned long x;
    x = _beginthread(func, 0x10000, param);
    if (x == -1)
    {
        fprintf(stderr, "Error starting thread.  Errno = %d\n", errno);
        exit(-1);
    }
}

unsigned long ThreadFuncs::getCurrentMillis()
{
    return (unsigned long)::GetTickCount();
}




// #elif defined (POSIX) 
#else

//------------------------------------------------------------------------------
//
//   UNIX specific code for starting threads
//
//------------------------------------------------------------------------------
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <sched.h>
#include <sys/timeb.h>


extern "C" {


typedef void (*ThreadFunc)(void *);
typedef void *(*pthreadfunc)(void *);

class ThreadFuncs           // This class isolates OS dependent threading
{                           //   functions from the rest of ThreadTest program.
public:
    static void            Sleep(int millis);
    static void            startThread(ThreadFunc, void *param);
    static unsigned long   getCurrentMillis();
    static void            yield() {sched_yield();};
};

void ThreadFuncs::Sleep(int millis)
{
   int seconds = millis/1000;
   if (seconds <= 0) seconds = 1;
   ::sleep(seconds);
}


void ThreadFuncs::startThread(ThreadFunc func, void *param)
{
    unsigned long x;

    pthread_t tId;
    //thread_t tId;
#if defined(_HP_UX) && defined(XML_USE_DCE)
    x = pthread_create( &tId, pthread_attr_default,  (pthreadfunc)func,  param);
#else
    pthread_attr_t attr;
    pthread_attr_init(&attr);
    x = pthread_create( &tId, &attr,  (pthreadfunc)func,  param);
#endif
    if (x == -1)
    {
        fprintf(stderr, "Error starting thread.  Errno = %d\n", errno);
        exit(-1);
    }
}

unsigned long ThreadFuncs::getCurrentMillis() {
    timeb aTime;
    ftime(&aTime);
    return (unsigned long)(aTime.time*1000 + aTime.millitm);
}
}


// #else
// #error This platform is not supported
#endif



//------------------------------------------------------------------------------
//
//  struct runInfo     Holds the info extracted from the command line and data
//                     that is shared by all threads.
//                     There is only one of these, and it is static.
//                     During the test, the threads will access this info without
//                     any synchronization.
//
//------------------------------------------------------------------------------
const int MAXINFILES = 25;
struct RunInfo
{
    bool                quiet;
    bool                verbose;
    int                 numThreads;
    int                 totalTime;
    int                 checkTime;
    AbstractThreadTest *fTest;
    bool                stopFlag;
    bool                exitFlag;
    int32_t             runningThreads;
};


//------------------------------------------------------------------------------
//
//  struct threadInfo  Holds information specific to an individual thread.
//                     One of these is set up for each thread in the test.
//                     The main program monitors the threads by looking
//                     at the status stored in these structs.
//
//------------------------------------------------------------------------------
struct ThreadInfo
{
    bool    fHeartBeat;            // Set true by the thread each time it finishes
                                   //   parsing a file.
    unsigned int     fCycles;      // Number of cycles completed.
    int              fThreadNum;   // Identifying number for this thread.
    ThreadInfo() {
        fHeartBeat = false;
        fCycles = 0;
        fThreadNum = -1;
    }
};


//
//------------------------------------------------------------------------------
//
//  Global Data
//
//------------------------------------------------------------------------------
RunInfo         gRunInfo;
ThreadInfo      *gThreadInfo;
UMTX            gMutex;


//----------------------------------------------------------------------
//
//   parseCommandLine   Read through the command line, and save all
//                      of the options in the gRunInfo struct.
//
//                      Display the usage message if the command line
//                      is no good.
//
//                      Probably ought to be a member function of RunInfo.
//
//----------------------------------------------------------------------

void parseCommandLine(int argc, char **argv)
{
    gRunInfo.quiet = false;               // Set up defaults for run.
    gRunInfo.verbose = false;
    gRunInfo.numThreads = 2;
    gRunInfo.totalTime = 0;
    gRunInfo.checkTime = 10;

    try             // Use exceptions for command line syntax errors.
    {
        int argnum = 1;
        while (argnum < argc)
        {
            if      (strcmp(argv[argnum], "-quiet") == 0)
                gRunInfo.quiet = true;
            else if (strcmp(argv[argnum], "-verbose") == 0)
                gRunInfo.verbose = true;
            else if (strcmp(argv[argnum], "--help") == 0 ||
                    (strcmp(argv[argnum],     "?")      == 0)) {throw 1; }
                
            else if (strcmp(argv[argnum], "-threads") == 0)
            {
                ++argnum;
                if (argnum >= argc)
                    throw 1;
                gRunInfo.numThreads = atoi(argv[argnum]);
                if (gRunInfo.numThreads < 0)
                    throw 1;
            }
            else if (strcmp(argv[argnum], "-time") == 0)
            {
                ++argnum;
                if (argnum >= argc)
                    throw 1;
                gRunInfo.totalTime = atoi(argv[argnum]);
                if (gRunInfo.totalTime < 1)
                    throw 1;
            }
            else if (strcmp(argv[argnum], "-ctime") == 0)
            {
                ++argnum;
                if (argnum >= argc)
                    throw 1;
                gRunInfo.checkTime = atoi(argv[argnum]);
                if (gRunInfo.checkTime < 1)
                    throw 1;
            }
            else if (strcmp(argv[argnum], "string") == 0)
            {
                gRunInfo.fTest = createStringTest();
            }
            else if (strcmp(argv[argnum], "convert") == 0)
            {
                gRunInfo.fTest = createConvertTest();
            }
           else  
            {
                fprintf(stderr, "Unrecognized command line option.  Scanning \"%s\"\n",
                    argv[argnum]);
                throw 1;
            }
            argnum++;
        }
        // We've reached the end of the command line parameters.
        // Fail if no test name was specified.
        if (gRunInfo.fTest == NULL) {
            fprintf(stderr, "No test specified.\n");
            throw 1;
        }

    }
    catch (int)
    {
        fprintf(stderr, "usage:  threadtest [-threads nnn] [-time nnn] [-quiet] [-verbose] test-name\n"
            "     -quiet         Suppress periodic status display. \n"
            "     -verbose       Display extra messages. \n"
            "     -threads nnn   Number of threads.  Default is 2. \n"
            "     -time nnn      Total time to run, in seconds.  Default is forever.\n"
            "     -ctime nnn     Time between extra consistency checks, in seconds.  Default 10\n"
            "     testname       string | convert\n"
            );
        exit(1);
    }
}





//----------------------------------------------------------------------
//
//  threadMain   The main function for each of the swarm of test threads.
//               Run in a loop, executing the runOnce() test function each time.
//
//
//----------------------------------------------------------------------

extern "C" {

void threadMain (void *param)
{
    ThreadInfo   *thInfo = (ThreadInfo *)param;

    if (gRunInfo.verbose)
        printf("Thread #%d: starting\n", thInfo->fThreadNum);
    umtx_atomic_inc(&gRunInfo.runningThreads);

    //
    //
    while (true)
    {
        if (gRunInfo.verbose )
            printf("Thread #%d: starting loop\n", thInfo->fThreadNum);

        //
        //  If the main thread is asking us to wait, do so by locking gMutex
        //     which will block us, since the main thread will be holding it already.
        // 
        if (gRunInfo.stopFlag) {
            if (gRunInfo.verbose) {
                fprintf(stderr, "Thread #%d: suspending\n", thInfo->fThreadNum);
            }
            umtx_atomic_dec(&gRunInfo.runningThreads);
            while (gRunInfo.stopFlag) {
                umtx_lock(&gMutex);
                umtx_unlock(&gMutex);
            }
            umtx_atomic_inc(&gRunInfo.runningThreads);
            if (gRunInfo.verbose) {
                fprintf(stderr, "Thread #%d: restarting\n", thInfo->fThreadNum);
            }
        }

        //
        // The real work of the test happens here.
        //
        gRunInfo.fTest->runOnce();

        thInfo->fHeartBeat = true;
        thInfo->fCycles++;

        //
        // If main thread says it's time to exit, break out of the loop.
        //
        if (gRunInfo.exitFlag) {
            break;
        }
    }
            
    umtx_atomic_dec(&gRunInfo.runningThreads);

    // Returning will kill the thread.
    return;
}

}




//----------------------------------------------------------------------
//
//   main
//
//----------------------------------------------------------------------

int main (int argc, char **argv)
{
    //
    //  Parse the command line options, and create the specified kind of test.
    //
    parseCommandLine(argc, argv);


    //
    //  Fire off the requested number of parallel threads
    //

    if (gRunInfo.numThreads == 0)
        exit(0);

    gRunInfo.exitFlag = FALSE;
    gRunInfo.stopFlag = TRUE;      // Will cause the new threads to block 
    umtx_lock(&gMutex);

    gThreadInfo = new ThreadInfo[gRunInfo.numThreads];
    int threadNum;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
    {
        gThreadInfo[threadNum].fThreadNum = threadNum;
        ThreadFuncs::startThread(threadMain, &gThreadInfo[threadNum]);
    }


    unsigned long startTime = ThreadFuncs::getCurrentMillis();
    int elapsedSeconds = 0;
    int timeSinceCheck = 0;

    //
    // Unblock the threads.
    //
    gRunInfo.stopFlag = FALSE;       // Unblocks the worker threads.
    umtx_unlock(&gMutex);      

    //
    //  Loop, watching the heartbeat of the worker threads.
    //    Each second,
    //            display "+" if all threads have completed at least one loop
    //            display "." if some thread hasn't since previous "+"
    //    Each "ctime" seconds,
    //            Stop all the worker threads at the top of their loop, then
    //            call the test's check function.
    //
    while (gRunInfo.totalTime == 0 || gRunInfo.totalTime > elapsedSeconds)
    {
        ThreadFuncs::Sleep(1000);      // We sleep while threads do their work ...

        if (gRunInfo.quiet == false && gRunInfo.verbose == false)
        {
            char c = '+';
            int threadNum;
            for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
            {
                if (gThreadInfo[threadNum].fHeartBeat == false)
                {
                    c = '.';
                    break;
                };
            }
            fputc(c, stdout);
            fflush(stdout);
            if (c == '+')
                for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
                    gThreadInfo[threadNum].fHeartBeat = false;
        }

        //
        // Update running times.
        //
        timeSinceCheck -= elapsedSeconds;
        elapsedSeconds = (ThreadFuncs::getCurrentMillis() - startTime) / 1000;
        timeSinceCheck += elapsedSeconds;

        //
        //  Call back to the test to let it check its internal validity
        //
        if (timeSinceCheck >= gRunInfo.checkTime) {
            if (gRunInfo.verbose) {
                fprintf(stderr, "Main: suspending all threads\n");
            }
            umtx_lock(&gMutex);               // Block the worker threads at the top of their loop
            gRunInfo.stopFlag = TRUE;
            while (gRunInfo.runningThreads > 0) { ThreadFuncs::yield(); }
            
            gRunInfo.fTest->check();
            if (gRunInfo.quiet == false && gRunInfo.verbose == false) {
                fputc('C', stdout);
            }

            if (gRunInfo.verbose) {
                fprintf(stderr, "Main: starting all threads.\n");
            }
            gRunInfo.stopFlag = FALSE;       // Unblock the worker threads.
            umtx_unlock(&gMutex);      
            timeSinceCheck = 0;
        }
    };

    //
    //  Time's up, we are done.  (We only get here if this was a timed run)
    //  Tell the threads to exit.
    //
    gRunInfo.exitFlag = true;
    while (gRunInfo.runningThreads > 0) { ThreadFuncs::yield(); }

    //
    //  Tally up the total number of cycles completed by each of the threads.
    //
    double totalCyclesCompleted = 0;
    for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++) {
        totalCyclesCompleted += gThreadInfo[threadNum].fCycles;
    }

    double cyclesPerMinute = totalCyclesCompleted / (double(gRunInfo.totalTime) / double(60));
    printf("\n%8.1f cycles per minute.", cyclesPerMinute);

    //
    //  Memory should be clean coming out
    //
    delete gRunInfo.fTest;
    delete [] gThreadInfo;
    umtx_destroy(&gMutex);
    u_cleanup();

    return 0;
}


