diff options
Diffstat (limited to 'Build/source/libs/icu/icu-49.1/test/threadtest')
7 files changed, 1098 insertions, 0 deletions
diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/Makefile.in b/Build/source/libs/icu/icu-49.1/test/threadtest/Makefile.in new file mode 100644 index 00000000000..4014a7fec58 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/Makefile.in @@ -0,0 +1,90 @@ +## Makefile.in for ICU - test/threadtest +## Copyright (c) 2001-2011, International Business Machines Corporation and +## others. All Rights Reserved. + +## Source directory information +srcdir = @srcdir@ +top_srcdir = @top_srcdir@ + +top_builddir = ../.. + +include $(top_builddir)/icudefs.mk + +## Platform-specific setup +include @platform_make_fragment@ + +## Build directory information +subdir = test/threadtest + +## Extra files to remove for 'make clean' +CLEANFILES = *~ $(DEPS) + +## Target information +TARGET = threadtest + +DEFS = @DEFS@ +CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/common -I$(top_srcdir)/i18n +CFLAGS = @CFLAGS@ +CXXFLAGS = @CXXFLAGS@ +ENABLE_RPATH = @ENABLE_RPATH@ +ifeq ($(ENABLE_RPATH),YES) +RPATHLDFLAGS = $(LD_RPATH)$(LD_RPATH_PRE)$(libdir) +endif +LDFLAGS = @LDFLAGS@ $(RPATHLDFLAGS) +LIBS = $(LIBICUI18N) $(LIBICUUC) @LIBS@ @LIB_M@ + +OBJECTS = threadtest.o stringtest.o converttest.o + +DEPS = $(OBJECTS:.o=.d) + +## List of phony targets +.PHONY : all all-local install install-local clean clean-local \ +distclean distclean-local dist dist-local check check-local + +## Clear suffix list +.SUFFIXES : + +## List of standard targets +all: all-local +install: install-local +clean: clean-local +distclean : distclean-local +dist: dist-local +check: all check-local + +all-local: $(TARGET) + +install-local: + +dist-local: + +clean-local: + test -z "$(CLEANFILES)" || $(RMV) $(CLEANFILES) + $(RMV) $(OBJECTS) $(TARGET) + +distclean-local: clean-local + $(RMV) Makefile + +check-local: all-local + +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + cd $(top_builddir) \ + && CONFIG_FILES=$(subdir)/$@ CONFIG_HEADERS= $(SHELL) ./config.status + +$(TARGET) : $(OBJECTS) + $(LINK.cc) -o $@ $^ $(LIBS) + $(POST_BUILD_STEP) + +invoke: + ICU_DATA=$${ICU_DATA:-$(top_builddir)/data/} TZ=PST8PDT $(INVOKE) $(INVOCATION) + +ifeq (,$(MAKECMDGOALS)) +-include $(DEPS) +else +ifneq ($(patsubst %clean,,$(MAKECMDGOALS)),) +ifneq ($(patsubst %install,,$(MAKECMDGOALS)),) +-include $(DEPS) +endif +endif +endif + diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/converttest.cpp b/Build/source/libs/icu/icu-49.1/test/threadtest/converttest.cpp new file mode 100644 index 00000000000..8de22efa786 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/converttest.cpp @@ -0,0 +1,88 @@ +// +//******************************************************************** +// Copyright (C) 2002-2003, International Business Machines +// Corporation and others. All Rights Reserved. +//******************************************************************** +// +// File converttest.cpp +// + +#include "threadtest.h" +#include "unicode/utypes.h" +#include "unicode/ucnv.h" +#include "unicode/uclean.h" +#include "stdio.h" + +U_CAPI UBool U_EXPORT2 ucnv_cleanup(); + +class ConvertThreadTest: public AbstractThreadTest { +public: + ConvertThreadTest(); + virtual ~ConvertThreadTest(); + virtual void check(); + virtual void runOnce(); + +private: + UConverter *fCnv; +}; + + +ConvertThreadTest::ConvertThreadTest() { + UErrorCode err = U_ZERO_ERROR; + + fCnv = ucnv_open("gb18030", &err); + if (U_FAILURE(err)) { + fprintf(stderr, "ConvertTest - could not ucnv_open(\"gb18030\")\n"); + fCnv = NULL; + } +}; + + +ConvertThreadTest::~ConvertThreadTest() { + ucnv_close(fCnv); + fCnv = 0; +} + +void ConvertThreadTest::runOnce() { + UErrorCode err = U_ZERO_ERROR; + UConverter *cnv1; + UConverter *cnv2; + char buf[U_CNV_SAFECLONE_BUFFERSIZE]; + int32_t bufSize = U_CNV_SAFECLONE_BUFFERSIZE; + + cnv1 = ucnv_open("shift_jis", &err); + if (U_FAILURE(err)) { + fprintf(stderr, "ucnv_open(\"shift_jis\") failed.\n"); + } + + cnv2 = ucnv_safeClone(fCnv, // The source converter, common to all threads. + buf, + &bufSize, + &err); + if (U_FAILURE(err)) { + fprintf(stderr, "ucnv_safeClone() failed.\n"); + } + ucnv_close(cnv1); + ucnv_close(cnv2); + ucnv_flushCache(); +} + +void ConvertThreadTest::check() { + UErrorCode err = U_ZERO_ERROR; + + if (fCnv) {ucnv_close(fCnv);} + //if (ucnv_cleanup () == FALSE) { + // fprintf(stderr, "ucnv_cleanup() failed - cache was not empty.\n"); + //} + fCnv = ucnv_open("gb18030", &err); + if (U_FAILURE(err)) { + fprintf(stderr, "ConvertTest::check() - could not redo ucnv_open(\"gb18030\")\n"); + fCnv = NULL; + } +} + + +AbstractThreadTest *createConvertTest() { + return new ConvertThreadTest(); +} + diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/stringtest.cpp b/Build/source/libs/icu/icu-49.1/test/threadtest/stringtest.cpp new file mode 100644 index 00000000000..2380a3c7713 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/stringtest.cpp @@ -0,0 +1,143 @@ +// +//******************************************************************** +// Copyright (C) 2002, International Business Machines +// Corporation and others. All Rights Reserved. +//******************************************************************** +// +// File stringtest.cpp +// + +#include "threadtest.h" +#include "unicode/unistr.h" +#include "stdio.h" + +class StringThreadTest: public AbstractThreadTest { +public: + StringThreadTest(); + virtual ~StringThreadTest(); + virtual void check(); + virtual void runOnce(); + void makeStringCopies(int recursionCount); + +private: + UnicodeString *fCleanStrings; + UnicodeString *fSourceStrings; +}; + +StringThreadTest::StringThreadTest() { + // cleanStrings and sourceStrings are separately initialized to the same values. + // cleanStrings are never touched after in any remotely unsafe way. + // sourceStrings are copied during the test, which will run their buffer's reference + // counts all over the place. + fCleanStrings = new UnicodeString[5]; + fSourceStrings = new UnicodeString[5]; + + fCleanStrings[0] = "When sorrows come, they come not single spies, but in batallions."; + fSourceStrings[0] = "When sorrows come, they come not single spies, but in batallions."; + fCleanStrings[1] = "Away, you scullion! You rampallion! You fustilarion! I'll tickle your catastrophe!"; + fSourceStrings[1] = "Away, you scullion! You rampallion! You fustilarion! I'll tickle your catastrophe!"; + fCleanStrings[2] = "hot"; + fSourceStrings[2] = "hot"; + fCleanStrings[3] = ""; + fSourceStrings[3] = ""; + fCleanStrings[4] = "Tomorrow, and tomorrow, and tomorrow,\n" + "Creeps in this petty pace from day to day\n" + "To the last syllable of recorded time;\n" + "And all our yesterdays have lighted fools \n" + "The way to dusty death. Out, out brief candle!\n" + "Life's but a walking shadow, a poor player\n" + "That struts and frets his hour upon the stage\n" + "And then is heard no more. It is a tale\n" + "Told by and idiot, full of sound and fury,\n" + "Signifying nothing.\n"; + fSourceStrings[4] = "Tomorrow, and tomorrow, and tomorrow,\n" + "Creeps in this petty pace from day to day\n" + "To the last syllable of recorded time;\n" + "And all our yesterdays have lighted fools \n" + "The way to dusty death. Out, out brief candle!\n" + "Life's but a walking shadow, a poor player\n" + "That struts and frets his hour upon the stage\n" + "And then is heard no more. It is a tale\n" + "Told by and idiot, full of sound and fury,\n" + "Signifying nothing.\n"; +}; + + +StringThreadTest::~StringThreadTest() { + delete [] fCleanStrings; + delete [] fSourceStrings; +} + + +void StringThreadTest::runOnce() { + makeStringCopies(25); +} + +void StringThreadTest::makeStringCopies(int recursionCount) { + UnicodeString firstGeneration[5]; + UnicodeString secondGeneration[5]; + UnicodeString thirdGeneration[5]; + UnicodeString fourthGeneration[5]; + + // Make four generations of copies of the source strings, in slightly variant ways. + // + int i; + for (i=0; i<5; i++) { + firstGeneration[i] = fSourceStrings[i]; + secondGeneration[i] = firstGeneration[i]; + thirdGeneration[i] = UnicodeString(secondGeneration[i]); + // fourthGeneration[i] = UnicodeString("Lay on, MacDuff, And damn'd be him that first cries, \"Hold, enough!\""); + fourthGeneration[i] = UnicodeString(); + fourthGeneration[i] = thirdGeneration[i]; + } + + + // Recurse to make even more copies of the strings/ + // + if (recursionCount > 0) { + makeStringCopies(recursionCount-1); + } + + + // Verify that all four generations are equal. + for (i=0; i<5; i++) { + if (firstGeneration[i] != fSourceStrings[i] || + firstGeneration[i] != secondGeneration[i] || + firstGeneration[i] != thirdGeneration[i] || + firstGeneration[i] != fourthGeneration[i]) + { + fprintf(stderr, "Error, strings don't compare equal.\n"); + } + } + +}; + + +void StringThreadTest::check() { + // + // Check that the reference counts on the buffers for all of the source strings + // are one. The ref counts will have run way up while the test threads + // make numerous copies of the strings, but at the top of the loop all + // of the copies should be gone. + // + int i; + + for (i=0; i<5; i++) { + if (fSourceStrings[i].fFlags & UnicodeString::kRefCounted) { + const UChar *buf = fSourceStrings[i].getBuffer(); + uint32_t refCount = fSourceStrings[i].refCount(); + if (refCount != 1) { + fprintf(stderr, "\nFailure. SourceString Ref Count was %d, should be 1.\n", refCount); + } + } + } +}; + + +// +// Factory functoin for StringThreadTest. +// C function lets ThreadTest create StringTests without needing StringThreadTest header. +// +AbstractThreadTest *createStringTest() { + return new StringThreadTest(); +}; diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.cpp b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.cpp new file mode 100644 index 00000000000..85e53a552a4 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.cpp @@ -0,0 +1,537 @@ +// +//******************************************************************** +// 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; +} + + diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsp b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsp new file mode 100644 index 00000000000..63bfe223da3 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsp @@ -0,0 +1,166 @@ +# Microsoft Developer Studio Project File - Name="threadtest" - Package Owner=<4> +# Microsoft Developer Studio Generated Build File, Format Version 6.00 +# ** DO NOT EDIT ** + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + +CFG=threadtest - Win32 Debug +!MESSAGE This is not a valid makefile. To build this project using NMAKE, +!MESSAGE use the Export Makefile command and run +!MESSAGE +!MESSAGE NMAKE /f "threadtest.mak". +!MESSAGE +!MESSAGE You can specify a configuration when running NMAKE +!MESSAGE by defining the macro CFG on the command line. For example: +!MESSAGE +!MESSAGE NMAKE /f "threadtest.mak" CFG="threadtest - Win32 Debug" +!MESSAGE +!MESSAGE Possible choices for configuration are: +!MESSAGE +!MESSAGE "threadtest - Win32 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "threadtest - Win32 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE "threadtest - Win64 Release" (based on "Win32 (x86) Console Application") +!MESSAGE "threadtest - Win64 Debug" (based on "Win32 (x86) Console Application") +!MESSAGE + +# Begin Project +# PROP AllowPerConfigDependencies 0 +# PROP Scc_ProjName "" +# PROP Scc_LocalPath "" +CPP=cl.exe +RSC=rc.exe + +!IF "$(CFG)" == "threadtest - Win32 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /G6 /MD /W3 /GX /O2 /Ob2 /I "..\..\..\include" /I "..\..\..\source\common" /I "..\..\..\source\i18n" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 +# ADD LINK32 kernel32.lib user32.lib shell32.lib icuuc.lib icuin.lib icutu.lib /nologo /subsystem:console /machine:I386 /libpath:"..\..\..\lib\\" + +!ELSEIF "$(CFG)" == "threadtest - Win32 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# ADD CPP /nologo /G6 /MDd /W3 /Gm /GX /ZI /Od /I "..\..\..\include" /I "..\..\..\source\common" /I "..\..\..\source\i18n" /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FR /FD /GZ /c +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib shell32.lib icuucd.lib icuind.lib icutud.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept /libpath:"..\..\..\lib\\" + +!ELSEIF "$(CFG)" == "threadtest - Win64 Release" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 0 +# PROP BASE Output_Dir "Release" +# PROP BASE Intermediate_Dir "Release" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 0 +# PROP Output_Dir "Release" +# PROP Intermediate_Dir "Release" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN64" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /FD /c +# ADD CPP /nologo /MD /W3 /I "..\..\..\include" /I "..\..\..\source\common" /I "..\..\..\source\i18n" /D"WIN64" /D"NDEBUG" /D"_CONSOLE" /D"_MBCS" /FD /c /O2 /GX /Op /D"_IA64_" /Zi /D"WIN64" /D"WIN32" /D"_AFX_NO_DAO_SUPPORT" /Zm600 +# ADD BASE RSC /l 0x409 /d "NDEBUG" +# ADD RSC /l 0x409 /d "NDEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:IA64 +# ADD LINK32 kernel32.lib user32.lib shell32.lib icuuc.lib icuin.lib icutu.lib /nologo /subsystem:console /machine:IA64 /libpath:"..\..\..\lib\\" /incremental:no + +!ELSEIF "$(CFG)" == "threadtest - Win64 Debug" + +# PROP BASE Use_MFC 0 +# PROP BASE Use_Debug_Libraries 1 +# PROP BASE Output_Dir "Debug" +# PROP BASE Intermediate_Dir "Debug" +# PROP BASE Target_Dir "" +# PROP Use_MFC 0 +# PROP Use_Debug_Libraries 1 +# PROP Output_Dir "Debug" +# PROP Intermediate_Dir "Debug" +# PROP Ignore_Export_Lib 0 +# PROP Target_Dir "" +# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN64" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /FD /GZ /c +# ADD CPP /nologo /MDd /W3 /Gm /I "..\..\..\include" /I "..\..\..\source\common" /I "..\..\..\source\i18n" /D"WIN64" /D"_DEBUG" /D"_CONSOLE" /D"_MBCS" /FR /FD /GZ /c /Od /GX /Op /D"_IA64_" /Zi /D"WIN64" /D"WIN32" /D"_AFX_NO_DAO_SUPPORT" /Zm600 +# ADD BASE RSC /l 0x409 /d "_DEBUG" +# ADD RSC /l 0x409 /d "_DEBUG" +BSC32=bscmake.exe +# ADD BASE BSC32 /nologo +# ADD BSC32 /nologo +LINK32=link.exe +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:IA64 /pdbtype:sept +# ADD LINK32 kernel32.lib user32.lib shell32.lib icuucd.lib icuind.lib icutud.lib /nologo /subsystem:console /debug /machine:IA64 /pdbtype:sept /libpath:"..\..\..\lib\\" /incremental:no + +!ENDIF + +# Begin Target + +# Name "threadtest - Win32 Release" +# Name "threadtest - Win32 Debug" +# Name "threadtest - Win64 Release" +# Name "threadtest - Win64 Debug" +# Begin Group "Source Files" + +# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat" +# Begin Source File + +SOURCE=.\converttest.cpp +# End Source File +# Begin Source File + +SOURCE=.\stringtest.cpp +# End Source File +# Begin Source File + +SOURCE=.\threadtest.cpp +# End Source File +# End Group +# Begin Group "Header Files" + +# PROP Default_Filter "h;hpp;hxx;hm;inl" +# Begin Source File + +SOURCE=.\threadtest.h +# End Source File +# End Group +# Begin Group "Resource Files" + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" +# End Group +# End Target +# End Project diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsw b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsw new file mode 100644 index 00000000000..0e853c88796 --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.dsw @@ -0,0 +1,29 @@ +Microsoft Developer Studio Workspace File, Format Version 6.00 +# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE! + +############################################################################### + +Project: "threadtest"=.\threadtest.dsp - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ +}}} + +############################################################################### + +Global: + +Package=<5> +{{{ +}}} + +Package=<3> +{{{ +}}} + +############################################################################### + diff --git a/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.h b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.h new file mode 100644 index 00000000000..1ad74cfe4ac --- /dev/null +++ b/Build/source/libs/icu/icu-49.1/test/threadtest/threadtest.h @@ -0,0 +1,45 @@ +// +//******************************************************************** +// Copyright (C) 2002-2011, International Business Machines +// Corporation and others. All Rights Reserved. +//******************************************************************** +// +// File threadtest.h +// +#ifndef ABSTRACTTHREADTEST_H +#define ABSTRACTTHREADTEST_H +//------------------------------------------------------------------------------ +// +// class AbstractThreadTest Base class for threading tests. +// Use of this abstract base isolates the part of the +// program that nows how to spin up and control threads +// from the specific stuff being tested, and (hopefully) +// simplifies adding new threading tests for different parts +// of ICU. +// +// Derived classes: A running test will have exactly one instance of a +// derived class, which will persist for the duration of the +// test and be shared among all of the threads involved in +// the test. +// +// The constructor will be called in a single-threaded environment, +// and should set up any data that will need to persist for the +// duration. +// +// runOnce() will be called repeatedly by the working threads of +// the test in the full multi-threaded environment. +// +// check() will be called periodically in a single threaded +// environment, with the worker threads temporarily suspended between +// between calls to runOnce(). Do consistency checks here. +// +//------------------------------------------------------------------------------ +class AbstractThreadTest { +public: + AbstractThreadTest() {}; + virtual ~AbstractThreadTest(); + virtual void check() = 0; + virtual void runOnce() = 0; +}; + +#endif // ABSTRACTTHREADTEST_H |