]> git.saurik.com Git - apple/icu.git/blobdiff - icuSources/test/threadtest/threadtest.cpp
ICU-57131.0.1.tar.gz
[apple/icu.git] / icuSources / test / threadtest / threadtest.cpp
diff --git a/icuSources/test/threadtest/threadtest.cpp b/icuSources/test/threadtest/threadtest.cpp
deleted file mode 100644 (file)
index 85e53a5..0000000
+++ /dev/null
@@ -1,537 +0,0 @@
-//
-//********************************************************************
-//   Copyright (C) 2002-2011, 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"
-
-AbstractThreadTest::~AbstractThreadTest() {}
-
-//------------------------------------------------------------------------------
-//
-//   Factory functions for creating different test types.
-//
-//------------------------------------------------------------------------------
-extern  AbstractThreadTest *createStringTest();
-extern  AbstractThreadTest *createConvertTest();
-
-
-
-//------------------------------------------------------------------------------
-//
-//   Windows specific code for starting threads
-//
-//------------------------------------------------------------------------------
-#if U_PLATFORM_USES_ONLY_WIN32_API
-
-#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
-                                   //   a test.
-    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            gStopMutex;        // Lets main thread suspend test threads.
-UMTX            gInfoMutex;        // Synchronize access to data passed between
-                                   //  worker threads and the main thread
-
-
-//----------------------------------------------------------------------
-//
-//   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 gStopMutex
-        //     which will block us, since the main thread will be holding it already.
-        // 
-        umtx_lock(&gInfoMutex);
-        UBool stop = gRunInfo.stopFlag;  // Need mutex for processors with flakey memory models.
-        umtx_unlock(&gInfoMutex);
-
-        if (stop) {
-            if (gRunInfo.verbose) {
-                fprintf(stderr, "Thread #%d: suspending\n", thInfo->fThreadNum);
-            }
-            umtx_atomic_dec(&gRunInfo.runningThreads);
-            while (gRunInfo.stopFlag) {
-                umtx_lock(&gStopMutex);
-                umtx_unlock(&gStopMutex);
-            }
-            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();
-
-        umtx_lock(&gInfoMutex);
-        thInfo->fHeartBeat = true;
-        thInfo->fCycles++;
-        UBool exitNow = gRunInfo.exitFlag;
-        umtx_unlock(&gInfoMutex);
-
-        //
-        // If main thread says it's time to exit, break out of the loop.
-        //
-        if (exitNow) {
-            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(&gStopMutex);
-
-    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(&gStopMutex);      
-
-    //
-    //  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;
-            umtx_lock(&gInfoMutex);
-            for (threadNum=0; threadNum < gRunInfo.numThreads; threadNum++)
-            {
-                if (gThreadInfo[threadNum].fHeartBeat == false)
-                {
-                    c = '.';
-                    break;
-                };
-            }
-            umtx_unlock(&gInfoMutex);
-            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(&gStopMutex);               // Block the worker threads at the top of their loop
-            gRunInfo.stopFlag = TRUE;
-            for (;;) {
-                umtx_lock(&gInfoMutex);
-                UBool done = gRunInfo.runningThreads == 0;
-                umtx_unlock(&gInfoMutex);
-                if (done) { break;}
-                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(&gStopMutex);      
-            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;
-    for (;;) {
-        umtx_lock(&gInfoMutex);
-        UBool done = gRunInfo.runningThreads == 0;
-        umtx_unlock(&gInfoMutex);
-        if (done) { break;}
-        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(&gInfoMutex);
-    umtx_destroy(&gStopMutex);
-    u_cleanup();
-
-    return 0;
-}
-
-