1b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/******************************************************************** 21b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * COPYRIGHT: 3fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius * Copyright (c) 1999-2014, International Business Machines Corporation and 4b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru * others. All Rights Reserved. 5b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ********************************************************************/ 6b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 7b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(hpux) 8b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# ifndef _INCLUDE_POSIX_SOURCE 9b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# define _INCLUDE_POSIX_SOURCE 10b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 11b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 12b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "simplethread.h" 14b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 15b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/utypes.h" 16b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/ustring.h" 17b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "umutex.h" 18b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cmemory.h" 19b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "cstring.h" 20b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "uparse.h" 2150294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho#include "unicode/localpointer.h" 22b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/resbund.h" 23b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/udata.h" 24b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/uloc.h" 25b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h" 26b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "putilimp.h" 2754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "intltest.h" 2854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "tsmthred.h" 2954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "unicode/ushape.h" 30fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#include "unicode/translit.h" 31f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "sharedobject.h" 32f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "unifiedcache.h" 33f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius#include "uassert.h" 34103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius 35103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM_USES_ONLY_WIN32_API 36103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */ 37103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# undef POSIX 38103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#elif U_PLATFORM_IMPLEMENTS_POSIX 39103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# define POSIX 40103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#else 41103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius# undef POSIX 42b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 43b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 44b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru/* Needed by z/OS to get usleep */ 45103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS390 46b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define __DOT1 1 47b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define __UU 48b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#ifndef _XPG4_2 49b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#define _XPG4_2 50b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 51b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <unistd.h> 52b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 53103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if defined(POSIX) 54b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 55b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define HAVE_IMP 56b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 57b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (ICU_USE_THREADS == 1) 58b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <pthread.h> 59b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 60b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 61b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if defined(__hpux) && defined(HPUX_CMA) 62b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# if defined(read) // read being defined as cma_read causes trouble with iostream::read 63b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# undef read 64b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru# endif 65b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 66b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 67b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */ 68b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef __EXTENSIONS__ 69b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define __EXTENSIONS__ 70b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 71b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 72103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM == U_PF_OS390 73b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#include <sys/types.h> 74b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 75b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru 76103e9ffba2cba345d0078eb8b8db33249f81840aCraig Cornelius#if U_PLATFORM != U_PF_OS390 77b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <signal.h> 78b0ac937921a2c196d8b9da665135bf6ba01a1ccfJean-Baptiste Queru#endif 79b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 80b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Define _XPG4_2 for Solaris and friends. */ 81b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef _XPG4_2 82b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _XPG4_2 83b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 84b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 85b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Define __USE_XOPEN_EXTENDED for Linux and glibc. */ 86b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef __USE_XOPEN_EXTENDED 871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert#define __USE_XOPEN_EXTENDED 88b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 89b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 90b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */ 91b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED 92b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define _INCLUDE_XOPEN_SOURCE_EXTENDED 93b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 94b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 95b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <unistd.h> 96b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 97b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 98b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru/* HPUX */ 99b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#ifdef sleep 100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#undef sleep 101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TSMTHREAD_FAIL(msg) errln("%s at file %s, line %d", msg, __FILE__, __LINE__) 104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define TSMTHREAD_ASSERT(expr) {if (!(expr)) {TSMTHREAD_FAIL("Fail");}} 105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMultithreadTest::MultithreadTest() 107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 108b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruMultithreadTest::~MultithreadTest() 111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if (ICU_USE_THREADS==0) 1171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertvoid MultithreadTest::runIndexedTest( int32_t index, UBool exec, 118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* &name, char* /*par*/ ) { 119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) logln("TestSuite MultithreadTest: "); 120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(index == 0) 122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = "NO_THREADED_TESTS"; 123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = ""; 125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(exec) { logln("MultithreadTest - test DISABLED. ICU_USE_THREADS set to 0, check your configuration if this is a problem.."); 127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#else 130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 131b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <stdio.h> 132b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <string.h> 133b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include <ctype.h> // tolower, toupper 134b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 135b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/putil.h" 136b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 13750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho// for mthreadtest 138b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/numfmt.h" 139b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/choicfmt.h" 140b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/msgfmt.h" 141b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/locid.h" 14254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#include "unicode/coll.h" 143b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "unicode/calendar.h" 144b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#include "ucaconf.h" 145b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid SimpleThread::errorFunc() { 147b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // *(char *)0 = 3; // Force entry into a debugger via a crash; 148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertvoid MultithreadTest::runIndexedTest( int32_t index, UBool exec, 151b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* &name, char* /*par*/ ) { 152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) 153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("TestSuite MultithreadTest: "); 154b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch (index) { 155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = "TestThreads"; 157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) 158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestThreads(); 159b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 160b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: 162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = "TestMutex"; 163b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) 164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestMutex(); 165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 2: 168b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = "TestThreadedIntl"; 169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) { 171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestThreadedIntl(); 172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 173b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 174b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 176b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 3: 177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = "TestCollators"; 178b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 179b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) { 180b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestCollators(); 181b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 182b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */ 183b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 185b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 4: 1861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert name = "TestString"; 187b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (exec) { 188b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestString(); 189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 190b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 192fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 5: 1931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert name = "TestArabicShapingThreads"; 19454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (exec) { 19554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius TestArabicShapingThreads(); 19654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 19754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius break; 19854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 199fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius case 6: 200fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius name = "TestAnyTranslit"; 201fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (exec) { 202fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius TestAnyTranslit(); 203fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 204fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 2051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 206f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case 7: 207f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name = "TestConditionVariables"; 208f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (exec) { 209f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TestConditionVariables(); 210f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 211f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 212f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius case 8: 213f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius name = "TestUnifiedCache"; 214f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (exec) { 215f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius TestUnifiedCache(); 216f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 217f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius break; 218b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru name = ""; 220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; //needed to end loop 221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//----------------------------------------------------------------------------------- 226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// TestThreads -- see if threads really work at all. 228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Set up N threads pointing at N chars. When they are started, they will 230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// each sleep 1 second and then set their chars. At the end we make sure they 231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// are all set. 232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//----------------------------------------------------------------------------------- 234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define THREADTEST_NRTHREADS 8 23554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius#define ARABICSHAPE_THREADTEST 30 236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass TestThreadsThread : public SimpleThread 238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestThreadsThread(char* whatToChange) { fWhatToChange = whatToChange; } 2411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert virtual void run() { SimpleThread::sleep(1000); 242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Mutex m; 2431b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert *fWhatToChange = '*'; 244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate: 246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char *fWhatToChange; 247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 24854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//----------------------------------------------------------------------------------- 24954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// 25054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// TestArabicShapeThreads -- see if calls to u_shapeArabic in many threads works successfully 25154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// 25254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// Set up N threads pointing at N chars. When they are started, they will make calls to doTailTest which tests 2531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// u_shapeArabic, if the calls are successful it will the set * chars. 25454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// At the end we make sure all threads managed to run u_shapeArabic successfully. 25554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// This is a unit test for ticket 9473 25654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius// 25754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius//----------------------------------------------------------------------------------- 2581b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertclass TestArabicShapeThreads : public SimpleThread 25954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 26054dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliuspublic: 26154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius TestArabicShapeThreads(char* whatToChange) { fWhatToChange = whatToChange;} 2621b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert virtual void run() { 26354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(doTailTest()==TRUE) 2641b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert *fWhatToChange = '*'; 26554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 26654dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusprivate: 26754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius char *fWhatToChange; 26854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 26954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UBool doTailTest(void) { 27054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius static const UChar src[] = { 0x0020, 0x0633, 0 }; 27154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius static const UChar dst_old[] = { 0xFEB1, 0x200B,0 }; 27254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius static const UChar dst_new[] = { 0xFEB1, 0xFE73,0 }; 27354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UChar dst[3] = { 0x0000, 0x0000,0 }; 27454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t length; 27554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UErrorCode status; 27654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius IntlTest inteltst = IntlTest(); 2771b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 27854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius status = U_ZERO_ERROR; 279f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst), 28054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR, &status); 28154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(U_FAILURE(status)) { 2821b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert inteltst.errln("Fail: status %s\n", u_errorName(status)); 28354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 28454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else if(length!=2) { 28554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius inteltst.errln("Fail: len %d expected 3\n", length); 28654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 287f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if(u_strncmp(dst,dst_old,UPRV_LENGTHOF(dst))) { 28854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius inteltst.errln("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n", 28954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius dst[0],dst[1],dst_old[0],dst_old[1]); 29054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 29154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 29254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 29354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 29454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius //"Trying new tail 29554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius status = U_ZERO_ERROR; 296f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius length = u_shapeArabic(src, -1, dst, UPRV_LENGTHOF(dst), 29754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius U_SHAPE_LETTERS_SHAPE|U_SHAPE_SEEN_TWOCELL_NEAR|U_SHAPE_TAIL_NEW_UNICODE, &status); 29854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(U_FAILURE(status)) { 2991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert inteltst.errln("Fail: status %s\n", u_errorName(status)); 30054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 30154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else if(length!=2) { 30254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius inteltst.errln("Fail: len %d expected 3\n", length); 30354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 304f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } else if(u_strncmp(dst,dst_new,UPRV_LENGTHOF(dst))) { 30554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius inteltst.errln("Fail: got U+%04X U+%04X expected U+%04X U+%04X\n", 30654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius dst[0],dst[1],dst_new[0],dst_new[1]); 30754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 3081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 3091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 3101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 31154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return TRUE; 3121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 31354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 31454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 31554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 31654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius}; 317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MultithreadTest::TestThreads() 319b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 320b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char threadTestChars[THREADTEST_NRTHREADS + 1]; 321b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread *threads[THREADTEST_NRTHREADS]; 322b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t numThreadsStarted = 0; 323b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<THREADTEST_NRTHREADS;i++) 326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 327b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru threadTestChars[i] = ' '; 328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru threads[i] = new TestThreadsThread(&threadTestChars[i]); 329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru threadTestChars[THREADTEST_NRTHREADS] = '\0'; 331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("->" + UnicodeString(threadTestChars) + "<- Firing off threads.. "); 333b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<THREADTEST_NRTHREADS;i++) 334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (threads[i]->start() != 0) { 336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("Error starting thread %d", i); 337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru numThreadsStarted++; 340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(100); 342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(" Subthread started."); 343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Waiting for threads to be set.."); 346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (numThreadsStarted == 0) { 347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("No threads could be started for testing!"); 348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t patience = 40; // seconds to wait 352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while(patience--) 354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t count = 0; 356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(NULL); 357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<THREADTEST_NRTHREADS;i++) 358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(threadTestChars[i] == '*') 360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru count++; 362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(NULL); 3651b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(count == THREADTEST_NRTHREADS) 367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("->" + UnicodeString(threadTestChars) + "<- Got all threads! cya"); 369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<THREADTEST_NRTHREADS;i++) 370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete threads[i]; 372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("->" + UnicodeString(threadTestChars) + "<- Waiting.."); 377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(500); 378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("->" + UnicodeString(threadTestChars) + "<- PATIENCE EXCEEDED!! Still missing some."); 381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<THREADTEST_NRTHREADS;i++) 382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete threads[i]; 384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 38854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusvoid MultithreadTest::TestArabicShapingThreads() 38954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius{ 39054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius char threadTestChars[ARABICSHAPE_THREADTEST + 1]; 39154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius SimpleThread *threads[ARABICSHAPE_THREADTEST]; 39254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t numThreadsStarted = 0; 39354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 39454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t i; 3951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 39654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for(i=0;i<ARABICSHAPE_THREADTEST;i++) 39754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 39854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius threadTestChars[i] = ' '; 39954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius threads[i] = new TestArabicShapeThreads(&threadTestChars[i]); 40054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 40154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius threadTestChars[ARABICSHAPE_THREADTEST] = '\0'; 40254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 40354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius logln("-> do TestArabicShapingThreads <- Firing off threads.. "); 40454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for(i=0;i<ARABICSHAPE_THREADTEST;i++) 40554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 40654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (threads[i]->start() != 0) { 40754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius errln("Error starting thread %d", i); 40854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 40954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius else { 41054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius numThreadsStarted++; 41154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 41254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius //SimpleThread::sleep(100); 41354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius logln(" Subthread started."); 41454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 41554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 41654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius logln("Waiting for threads to be set.."); 41754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if (numThreadsStarted == 0) { 41854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius errln("No threads could be started for testing!"); 41954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return; 42054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 42154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 42254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t patience = 100; // seconds to wait 42354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 42454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius while(patience--) 42554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 42654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t count = 0; 42754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_lock(NULL); 42854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for(i=0;i<ARABICSHAPE_THREADTEST;i++) 42954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 43054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(threadTestChars[i] == '*') 43154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 43254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius count++; 43354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 43454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 43554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius umtx_unlock(NULL); 4361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 43754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(count == ARABICSHAPE_THREADTEST) 43854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 43954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius logln("->TestArabicShapingThreads <- Got all threads! cya"); 44054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for(i=0;i<ARABICSHAPE_THREADTEST;i++) 44154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 44254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius delete threads[i]; 44354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 44454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return; 44554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 44654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 44754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius logln("-> TestArabicShapingThreads <- Waiting.."); 44854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius SimpleThread::sleep(500); 44954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 45054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 45154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius errln("-> TestArabicShapingThreads <- PATIENCE EXCEEDED!! Still missing some."); 45254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius for(i=0;i<ARABICSHAPE_THREADTEST;i++) 45354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius { 45454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius delete threads[i]; 45554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 45654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 45754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 45854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 4591b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//----------------------------------------------------------------------- 461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 462b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// TestMutex - a simple (non-stress) test to verify that ICU mutexes 463b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// are actually mutexing. Does not test the use of 464b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// mutexes within ICU services, but rather that the 465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// platform's mutex support is at least superficially there. 466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//---------------------------------------------------------------------- 46854dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gTestMutexA = U_MUTEX_INITIALIZER; 46954dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UMutex gTestMutexB = U_MUTEX_INITIALIZER; 470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 4711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic int gThreadsStarted = 0; 472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int gThreadsInMiddle = 0; 473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int gThreadsDone = 0; 474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 475b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic const int TESTMUTEX_THREAD_COUNT = 4; 476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustatic int safeIncr(int &var, int amt) { 478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Thread safe (using global mutex) increment of a variable. 479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Return the updated value. 480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Can also be used as a safe load of a variable by incrementing it by 0. 481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Mutex m; 482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru var += amt; 483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return var; 484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass TestMutexThread : public SimpleThread 487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual void run() 490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // This is the code that each of the spawned threads runs. 492b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // All of the spawned threads bunch up together at each of the two mutexes 493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // because the main holds the mutexes until they do. 494b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru safeIncr(gThreadsStarted, 1); 496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gTestMutexA); 497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gTestMutexA); 498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru safeIncr(gThreadsInMiddle, 1); 499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gTestMutexB); 500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gTestMutexB); 501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru safeIncr(gThreadsDone, 1); 502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 504b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MultithreadTest::TestMutex() 506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Start up the test threads. They should all pile up waiting on 508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // gTestMutexA, which we (the main thread) hold until the test threads 509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // all get there. 510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gThreadsStarted = 0; 511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gThreadsInMiddle = 0; 512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru gThreadsDone = 0; 513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gTestMutexA); 514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TestMutexThread *threads[TESTMUTEX_THREAD_COUNT]; 515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t numThreadsStarted = 0; 517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) { 518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru threads[i] = new TestMutexThread; 519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (threads[i]->start() != 0) { 520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("Error starting thread %d", i); 521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else { 523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru numThreadsStarted++; 524b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (numThreadsStarted == 0) { 527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("No threads could be started for testing!"); 528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int patience = 0; 532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (safeIncr(gThreadsStarted, 0) != TESTMUTEX_THREAD_COUNT) { 533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (patience++ > 24) { 534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_FAIL("Patience Exceeded"); 535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(500); 538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // None of the test threads should have advanced past the first mutex. 540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_ASSERT(gThreadsInMiddle==0); 541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_ASSERT(gThreadsDone==0); 542b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 543b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // All of the test threads have made it to the first mutex. 544b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // We (the main thread) now let them advance to the second mutex, 545b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // where they should all pile up again. 546b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_lock(&gTestMutexB); 547b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru umtx_unlock(&gTestMutexA); 548b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 549b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru patience = 0; 550b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (safeIncr(gThreadsInMiddle, 0) != TESTMUTEX_THREAD_COUNT) { 551b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (patience++ > 24) { 552b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_FAIL("Patience Exceeded"); 553b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 554b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 555b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(500); 556b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 557b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_ASSERT(gThreadsDone==0); 558b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 559b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // All test threads made it to the second mutex. 560b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now let them proceed from there. They will all terminate. 5611b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert umtx_unlock(&gTestMutexB); 562b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru patience = 0; 563b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (safeIncr(gThreadsDone, 0) != TESTMUTEX_THREAD_COUNT) { 564b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (patience++ > 24) { 565b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru TSMTHREAD_FAIL("Patience Exceeded"); 566b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 567b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 568b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(500); 569b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 570b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 571b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // All threads made it by both mutexes. 572b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 573b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) { 574b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete threads[i]; 575b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 576b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 577b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 578b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 579b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 580b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 581b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 582b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// class ThreadWithStatus - a thread that we can check the status and error condition of 583b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 584b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 585b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass ThreadWithStatus : public SimpleThread 586b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 587b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 5881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UBool getError() { return (fErrors > 0); } 5891b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UBool getError(UnicodeString& fillinError) { fillinError = fErrorString; return (fErrors > 0); } 590b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual ~ThreadWithStatus(){} 591b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprotected: 592b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ThreadWithStatus() : fErrors(0) {} 5931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert void error(const UnicodeString &error) { 5941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fErrors++; fErrorString = error; 5951b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert SimpleThread::errorFunc(); 596b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 597b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru void error() { error("An error occured."); } 598b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate: 599b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fErrors; 600b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString fErrorString; 601b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 602b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 603b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 604b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 605b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 606b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 6071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// TestMultithreadedIntl. Test ICU Formatting n a multi-threaded environment 608b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 609b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 610b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 611b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 612b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// * Show exactly where the string's differences lie. 613b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUnicodeString showDifference(const UnicodeString& expected, const UnicodeString& result) 614b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 615b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString res; 616b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = expected + "<Expected\n"; 617b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(expected.length() != result.length()) 618b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += " [ Different lengths ] \n"; 619b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 620b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 621b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t i=0;i<expected.length();i++) 622b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 623b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(expected[i] == result[i]) 624b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 625b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += " "; 626b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 627b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru else 628b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 629b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += "|"; 630b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 631b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 632b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += "<Differences"; 633b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += "\n"; 634b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 635b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res += result + "<Result\n"; 636b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 637b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return res; 638b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 639b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 640b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 641b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 642b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 643b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 644b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 645b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// FormatThreadTest - a thread that tests performing a number of numberformats. 646b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 647b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 648b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 64959d709d503bab6e2b61931737e662dd293b40578ccorneliusconst int kFormatThreadIterations = 100; // # of iterations per thread 6501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertconst int kFormatThreadThreads = 10; // # of threads to spawn 651b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 652b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_FORMATTING 653b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 654b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 655b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 656b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct FormatThreadTestData 657b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 658b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double number; 659b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString string; 660b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData(double a, const UnicodeString& b) : number(a),string(b) {} 661b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} ; 662b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 663b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 664b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// "Someone from {2} is receiving a #{0} error - {1}. Their telephone call is costing {3 number,currency}." 665b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 66659d709d503bab6e2b61931737e662dd293b40578ccorneliusstatic void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale, 667b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments. 668b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString &result) 669b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 670b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(realStatus)) 671b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; // you messed up 672b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 673b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString errString1(u_errorName(inStatus0)); 674b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 675b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString countryName2; 676b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru inCountry2.getDisplayCountry(theLocale,countryName2); 677b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 678b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Formattable myArgs[] = { 679b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Formattable((int32_t)inStatus0), // inStatus0 {0} 680b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Formattable(errString1), // statusString1 {1} 681b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Formattable(countryName2), // inCountry2 {2} 682b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Formattable(currency3)// currency3 {3,number,currency} 683b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 684b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 685b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru MessageFormat *fmt = new MessageFormat("MessageFormat's API is broken!!!!!!!!!!!",realStatus); 686b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fmt->setLocale(theLocale); 687b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fmt->applyPattern(pattern, realStatus); 6881b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 689b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(realStatus)) { 690b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fmt; 691b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 692b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 693b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 6941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert FieldPosition ignore = 0; 695b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fmt->format(myArgs,4,result,ignore,realStatus); 696b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 697b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete fmt; 698b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 699b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 70059d709d503bab6e2b61931737e662dd293b40578ccornelius/** 7011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Shared formatters & data used by instances of ThreadSafeFormat. 7021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Exactly one instance of this class is created, and it is then shared concurrently 7031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * by the multiple instances of ThreadSafeFormat. 7041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert */ 7051b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertclass ThreadSafeFormatSharedData { 7061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert public: 7071b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert ThreadSafeFormatSharedData(UErrorCode &status); 7081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert ~ThreadSafeFormatSharedData(); 7091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert LocalPointer<NumberFormat> fFormat; 7101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert Formattable fYDDThing; 7111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert Formattable fBBDThing; 7121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UnicodeString fYDDStr; 7131b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UnicodeString fBBDStr; 7141b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert}; 7151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 7161b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertconst ThreadSafeFormatSharedData *gSharedData = NULL; 7171b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 7181b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertThreadSafeFormatSharedData::ThreadSafeFormatSharedData(UErrorCode &status) { 7191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fFormat.adoptInstead(NumberFormat::createCurrencyInstance(Locale::getUS(), status)); 7201b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert static const UChar kYDD[] = { 0x59, 0x44, 0x44, 0x00 }; 7211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert static const UChar kBBD[] = { 0x42, 0x42, 0x44, 0x00 }; 7221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fYDDThing.adoptObject(new CurrencyAmount(123.456, kYDD, status)); 7231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fBBDThing.adoptObject(new CurrencyAmount(987.654, kBBD, status)); 7241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if (U_FAILURE(status)) { 7251b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert return; 7261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert } 7271b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fFormat->format(fYDDThing, fYDDStr, NULL, status); 7281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fFormat->format(fBBDThing, fBBDStr, NULL, status); 7291b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert gSharedData = this; 7301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert} 7311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 7321b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertThreadSafeFormatSharedData::~ThreadSafeFormatSharedData() { 7331b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert gSharedData = NULL; 7341b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert} 7351b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 7361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert/** 7371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Class for thread-safe testing of format. 7381b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Instances of this class appear as members of class FormatThreadTest. 7391b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * Multiple instances of FormatThreadTest coexist. 7401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * ThreadSafeFormat::doStuff() is called concurrently to test the thread safety of 7411b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert * various shared format operations. 74259d709d503bab6e2b61931737e662dd293b40578ccornelius */ 74359d709d503bab6e2b61931737e662dd293b40578ccorneliusclass ThreadSafeFormat { 74459d709d503bab6e2b61931737e662dd293b40578ccorneliuspublic: 74559d709d503bab6e2b61931737e662dd293b40578ccornelius /* give a unique offset to each thread */ 7461b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert ThreadSafeFormat(UErrorCode &status); 7471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UBool doStuff(int32_t offset, UnicodeString &appendErr, UErrorCode &status) const; 74859d709d503bab6e2b61931737e662dd293b40578ccorneliusprivate: 7491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert LocalPointer<NumberFormat> fFormat; // formatter - en_US constructed currency 75059d709d503bab6e2b61931737e662dd293b40578ccornelius}; 75159d709d503bab6e2b61931737e662dd293b40578ccornelius 75259d709d503bab6e2b61931737e662dd293b40578ccornelius 7531b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertThreadSafeFormat::ThreadSafeFormat(UErrorCode &status) { 7541b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fFormat.adoptInstead(NumberFormat::createCurrencyInstance(Locale::getUS(), status)); 75559d709d503bab6e2b61931737e662dd293b40578ccornelius} 75659d709d503bab6e2b61931737e662dd293b40578ccornelius 7571b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertstatic const UChar kUSD[] = { 0x55, 0x53, 0x44, 0x00 }; 75859d709d503bab6e2b61931737e662dd293b40578ccornelius 7591b7d32f919554dda9c193b32188251337bc756f1Fredrik RoubertUBool ThreadSafeFormat::doStuff(int32_t offset, UnicodeString &appendErr, UErrorCode &status) const { 76059d709d503bab6e2b61931737e662dd293b40578ccornelius UBool okay = TRUE; 76159d709d503bab6e2b61931737e662dd293b40578ccornelius 76259d709d503bab6e2b61931737e662dd293b40578ccornelius if(u_strcmp(fFormat->getCurrency(), kUSD)) { 76359d709d503bab6e2b61931737e662dd293b40578ccornelius appendErr.append("fFormat currency != ") 76459d709d503bab6e2b61931737e662dd293b40578ccornelius .append(kUSD) 76559d709d503bab6e2b61931737e662dd293b40578ccornelius .append(", =") 76659d709d503bab6e2b61931737e662dd293b40578ccornelius .append(fFormat->getCurrency()) 76759d709d503bab6e2b61931737e662dd293b40578ccornelius .append("! "); 76859d709d503bab6e2b61931737e662dd293b40578ccornelius okay = FALSE; 76959d709d503bab6e2b61931737e662dd293b40578ccornelius } 77059d709d503bab6e2b61931737e662dd293b40578ccornelius 7711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(u_strcmp(gSharedData->fFormat->getCurrency(), kUSD)) { 77259d709d503bab6e2b61931737e662dd293b40578ccornelius appendErr.append("gFormat currency != ") 77359d709d503bab6e2b61931737e662dd293b40578ccornelius .append(kUSD) 77459d709d503bab6e2b61931737e662dd293b40578ccornelius .append(", =") 7751b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert .append(gSharedData->fFormat->getCurrency()) 77659d709d503bab6e2b61931737e662dd293b40578ccornelius .append("! "); 77759d709d503bab6e2b61931737e662dd293b40578ccornelius okay = FALSE; 77859d709d503bab6e2b61931737e662dd293b40578ccornelius } 77959d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString str; 78059d709d503bab6e2b61931737e662dd293b40578ccornelius const UnicodeString *o=NULL; 78159d709d503bab6e2b61931737e662dd293b40578ccornelius Formattable f; 78259d709d503bab6e2b61931737e662dd293b40578ccornelius const NumberFormat *nf = NULL; // only operate on it as const. 78359d709d503bab6e2b61931737e662dd293b40578ccornelius switch(offset%4) { 7841b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert case 0: f = gSharedData->fYDDThing; o = &gSharedData->fYDDStr; nf = gSharedData->fFormat.getAlias(); break; 7851b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert case 1: f = gSharedData->fBBDThing; o = &gSharedData->fBBDStr; nf = gSharedData->fFormat.getAlias(); break; 7861b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert case 2: f = gSharedData->fYDDThing; o = &gSharedData->fYDDStr; nf = fFormat.getAlias(); break; 7871b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert case 3: f = gSharedData->fBBDThing; o = &gSharedData->fBBDStr; nf = fFormat.getAlias(); break; 78859d709d503bab6e2b61931737e662dd293b40578ccornelius } 78959d709d503bab6e2b61931737e662dd293b40578ccornelius nf->format(f, str, NULL, status); 79059d709d503bab6e2b61931737e662dd293b40578ccornelius 79159d709d503bab6e2b61931737e662dd293b40578ccornelius if(*o != str) { 79259d709d503bab6e2b61931737e662dd293b40578ccornelius appendErr.append(showDifference(*o, str)); 79359d709d503bab6e2b61931737e662dd293b40578ccornelius okay = FALSE; 79459d709d503bab6e2b61931737e662dd293b40578ccornelius } 79559d709d503bab6e2b61931737e662dd293b40578ccornelius return okay; 79659d709d503bab6e2b61931737e662dd293b40578ccornelius} 797b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 798b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QueruUBool U_CALLCONV isAcceptable(void *, const char *, const char *, const UDataInfo *) { 799b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return TRUE; 800b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 801b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 802b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//static UMTX debugMutex = NULL; 803b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//static UMTX gDebugMutex; 804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 805b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 806b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass FormatThreadTest : public ThreadWithStatus 807b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 808b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 809b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int fNum; 810b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int fTraceInfo; 811b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 8121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert LocalPointer<ThreadSafeFormat> fTSF; 81359d709d503bab6e2b61931737e662dd293b40578ccornelius 814b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTest() // constructor is NOT multithread safe. 815b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : ThreadWithStatus(), 816b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNum(0), 817b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo(0), 8181b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fTSF(NULL), 819b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fOffset(0) 820b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // the locale to use 821b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 8221b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UErrorCode status = U_ZERO_ERROR; // TODO: rearrange code to allow checking of status. 8231b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert fTSF.adoptInstead(new ThreadSafeFormat(status)); 824b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static int32_t fgOffset = 0; 825b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fgOffset += 3; 826b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fOffset = fgOffset; 827b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 828b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 829b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 830b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual void run() 831b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 832b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo = 1; 83350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalPointer<NumberFormat> percentFormatter; 834b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 835b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 836b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0 8371b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert // debugging code, 838b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (int i=0; i<4000; i++) { 839b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ZERO_ERROR; 840b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDataMemory *data1 = udata_openChoice(0, "res", "en_US", isAcceptable, 0, &status); 841b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDataMemory *data2 = udata_openChoice(0, "res", "fr", isAcceptable, 0, &status); 842b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(data1); 843b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru udata_close(data2); 844b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 845b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error("udata_openChoice failed.\n"); 846b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 847b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 848b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 849b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 850b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 851b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 852b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if 0 8531b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert // debugging code, 854b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int m; 855b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (m=0; m<4000; m++) { 856b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ZERO_ERROR; 857b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UResourceBundle *res = NULL; 858b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *localeName = NULL; 859b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 860b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale loc = Locale::getEnglish(); 861b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 862b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru localeName = loc.getName(); 863b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // localeName = "en"; 864b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 865b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // ResourceBundle bund = ResourceBundle(0, loc, status); 866b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //umtx_lock(&gDebugMutex); 867b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru res = ures_open(NULL, localeName, &status); 868b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //umtx_unlock(&gDebugMutex); 869b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 870b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //umtx_lock(&gDebugMutex); 871b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ures_close(res); 872b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //umtx_unlock(&gDebugMutex); 873b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 874b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 875b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error("Resource bundle construction failed.\n"); 876b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 877b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 878b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 879b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 880b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif 881b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 882b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Keep this data here to avoid static initialization. 8831b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert FormatThreadTestData kNumberFormatTestData[] = 884b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 885b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData((double)5.0, UnicodeString("5", "")), 886b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 6.0, UnicodeString("6", "")), 887b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 20.0, UnicodeString("20", "")), 888b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 8.0, UnicodeString("8", "")), 889b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 8.3, UnicodeString("8.3", "")), 890b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 12345, UnicodeString("12,345", "")), 891b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 81890.23, UnicodeString("81,890.23", "")), 892b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 8931b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert int32_t kNumberFormatTestDataLength = UPRV_LENGTHOF(kNumberFormatTestData); 8941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 895b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Keep this data here to avoid static initialization. 8961b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert FormatThreadTestData kPercentFormatTestData[] = 897b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 898b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData((double)5.0, CharsToUnicodeString("500\\u00a0%")), 899b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 1.0, CharsToUnicodeString("100\\u00a0%")), 900b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FormatThreadTestData( 0.26, CharsToUnicodeString("26\\u00a0%")), 9011b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert FormatThreadTestData( 902b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 16384.99, CharsToUnicodeString("1\\u00a0638\\u00a0499\\u00a0%")), // U+00a0 = NBSP 9031b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert FormatThreadTestData( 904b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 81890.23, CharsToUnicodeString("8\\u00a0189\\u00a0023\\u00a0%")), 905b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 9061b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert int32_t kPercentFormatTestDataLength = UPRV_LENGTHOF(kPercentFormatTestData); 907b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t iteration; 9081b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 909b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru status = U_ZERO_ERROR; 91050294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalPointer<NumberFormat> formatter(NumberFormat::createInstance(Locale::getEnglish(),status)); 911b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 9126d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru error("Error on NumberFormat::createInstance()."); 913b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 914b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9151b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 91650294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho percentFormatter.adoptInstead(NumberFormat::createPercentInstance(Locale::getFrench(),status)); 917b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 9186d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru error("Error on NumberFormat::createPercentInstance()."); 919b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 920b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9211b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 922b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(iteration = 0;!getError() && iteration<kFormatThreadIterations;iteration++) 923b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 9241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 925b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t whichLine = (iteration + fOffset)%kNumberFormatTestDataLength; 9261b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 927b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString output; 9281b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 929b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru formatter->format(kNumberFormatTestData[whichLine].number, output); 9301b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 931b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(0 != output.compare(kNumberFormatTestData[whichLine].string)) { 9321b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert error("format().. expected " + kNumberFormatTestData[whichLine].string 933b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru + " got " + output); 934b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 935b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9361b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 937b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Now check percent. 938b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru output.remove(); 939b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru whichLine = (iteration + fOffset)%kPercentFormatTestDataLength; 9401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 941b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru percentFormatter->format(kPercentFormatTestData[whichLine].number, output); 942b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(0 != output.compare(kPercentFormatTestData[whichLine].string)) 943b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 9441b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert error("percent format().. \n" + 945b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru showDifference(kPercentFormatTestData[whichLine].string,output)); 946b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 947b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9481b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 9491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert // Test message error 950b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const int kNumberOfMessageTests = 3; 951b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode statusToCheck; 952b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString patternToCheck; 953b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale messageLocale; 954b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Locale countryToCheck; 955b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru double currencyToCheck; 9561b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 957b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString expected; 9581b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 959b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // load the cases. 960b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru switch((iteration+fOffset) % kNumberOfMessageTests) 961b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 962b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru default: 963b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 0: 964b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru statusToCheck= U_FILE_ACCESS_ERROR; 965b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru patternToCheck= "0:Someone from {2} is receiving a #{0}" 966b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " error - {1}. Their telephone call is costing " 967b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "{3,number,currency}."; // number,currency 968b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru messageLocale= Locale("en","US"); 969b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru countryToCheck= Locale("","HR"); 970b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currencyToCheck= 8192.77; 971b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected= "0:Someone from Croatia is receiving a #4 error - " 972b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "U_FILE_ACCESS_ERROR. Their telephone call is costing $8,192.77."; 973b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 974b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 1: 975b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru statusToCheck= U_INDEX_OUTOFBOUNDS_ERROR; 9761b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert patternToCheck= "1:A customer in {2} is receiving a #{0} error - {1}. " 9771b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert "Their telephone call is costing {3,number,currency}."; // number,currency 978b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru messageLocale= Locale("de","DE@currency=DEM"); 979b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru countryToCheck= Locale("","BF"); 980b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currencyToCheck= 2.32; 981c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru expected= CharsToUnicodeString( 9821b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert "1:A customer in Burkina Faso is receiving a #8 error - U_INDEX_OUTOFBOUNDS_ERROR. " 9831b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert "Their telephone call is costing 2,32\\u00A0DM."); 984b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 985b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru case 2: 986b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru statusToCheck= U_MEMORY_ALLOCATION_ERROR; 987b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru patternToCheck= "2:user in {2} is receiving a #{0} error - {1}. " 988b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "They insist they just spent {3,number,currency} " 989b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "on memory."; // number,currency 990b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru messageLocale= Locale("de","AT@currency=ATS"); // Austrian German 991b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru countryToCheck= Locale("","US"); // hmm 992b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru currencyToCheck= 40193.12; 993b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru expected= CharsToUnicodeString( 994b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "2:user in Vereinigte Staaten is receiving a #7 error" 995b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru " - U_MEMORY_ALLOCATION_ERROR. They insist they just spent" 996c69afcec261fc345fda8daf46f0ea6b4351dc777Jean-Baptiste Queru " \\u00f6S\\u00A040.193,12 on memory."); 997b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 998b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 9991b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1000b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString result; 1001b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 1002b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru formatErrorMessage(status,patternToCheck,messageLocale,statusToCheck, 1003b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru countryToCheck,currencyToCheck,result); 1004b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) 1005b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1006b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString tmp(u_errorName(status)); 1007b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error("Failure on message format, pattern=" + patternToCheck + 1008b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru ", error = " + tmp); 1009b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 1010b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10111b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1012b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(result != expected) 1013b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1014b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error("PatternFormat: \n" + showDifference(expected,result)); 1015b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 1016b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 101759d709d503bab6e2b61931737e662dd293b40578ccornelius // test the Thread Safe Format 101859d709d503bab6e2b61931737e662dd293b40578ccornelius UnicodeString appendErr; 10191b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert if(!fTSF->doStuff(fNum, appendErr, status)) { 102059d709d503bab6e2b61931737e662dd293b40578ccornelius error(appendErr); 102159d709d503bab6e2b61931737e662dd293b40578ccornelius goto cleanupAndReturn; 102259d709d503bab6e2b61931737e662dd293b40578ccornelius } 1023b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } /* end of for loop */ 102459d709d503bab6e2b61931737e662dd293b40578ccornelius 102559d709d503bab6e2b61931737e662dd293b40578ccornelius 102659d709d503bab6e2b61931737e662dd293b40578ccornelius 1027b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucleanupAndReturn: 1028b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while (fNum == 4) {SimpleThread::sleep(10000);} // Force a failure by preventing thread from finishing 1029b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo = 2; 1030b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 10311b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1032b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruprivate: 1033b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t fOffset; // where we are testing from. 1034b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1035b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1036b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ** The actual test function. 1037b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1038b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MultithreadTest::TestThreadedIntl() 1039b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1040b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int i; 1041b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString theErr; 1042b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool haveDisplayedInfo[kFormatThreadThreads]; 1043b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru static const int32_t PATIENCE_SECONDS = 45; 1044b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 104559d709d503bab6e2b61931737e662dd293b40578ccornelius UErrorCode threadSafeErr = U_ZERO_ERROR; 104659d709d503bab6e2b61931737e662dd293b40578ccornelius 10471b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert ThreadSafeFormatSharedData sharedData(threadSafeErr); 104859d709d503bab6e2b61931737e662dd293b40578ccornelius assertSuccess("initializing ThreadSafeFormat", threadSafeErr, TRUE); 104959d709d503bab6e2b61931737e662dd293b40578ccornelius 1050b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1051b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Create and start the test threads 1052b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1053b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Spawning: %d threads * %d iterations each.", 1054b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru kFormatThreadThreads, kFormatThreadIterations); 105550294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalArray<FormatThreadTest> tests(new FormatThreadTest[kFormatThreadThreads]); 1056b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t j = 0; j < kFormatThreadThreads; j++) { 1057b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tests[j].fNum = j; 1058b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t threadStatus = tests[j].start(); 1059b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (threadStatus != 0) { 1060b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("System Error %d starting thread number %d.", threadStatus, j); 1061b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::errorFunc(); 106250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho return; 1063b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1064b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru haveDisplayedInfo[j] = FALSE; 1065b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1066b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1067b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1068b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // Spin, waiting for the test threads to finish. 1069b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UBool stillRunning; 1070b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UDate startTime, endTime; 1071b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru startTime = Calendar::getNow(); 107259d709d503bab6e2b61931737e662dd293b40578ccornelius double lastComplaint = 0; 1073b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru do { 1074b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* Spin until the test threads complete. */ 1075b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stillRunning = FALSE; 1076b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru endTime = Calendar::getNow(); 107759d709d503bab6e2b61931737e662dd293b40578ccornelius double elapsedSeconds = ((int32_t)(endTime - startTime)/U_MILLIS_PER_SECOND); 107859d709d503bab6e2b61931737e662dd293b40578ccornelius if (elapsedSeconds > PATIENCE_SECONDS) { 1079b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("Patience exceeded. Test is taking too long."); 1080b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 108159d709d503bab6e2b61931737e662dd293b40578ccornelius } else if((elapsedSeconds-lastComplaint) > 2.0) { 108259d709d503bab6e2b61931737e662dd293b40578ccornelius infoln("%.1f seconds elapsed (still waiting..)", elapsedSeconds); 108359d709d503bab6e2b61931737e662dd293b40578ccornelius lastComplaint = elapsedSeconds; 1084b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1085b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1086b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru The following sleep must be here because the *BSD operating systems 1087b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru have a brain dead thread scheduler. They starve the child threads from 1088b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CPU time. 1089b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1090b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(1); // yield 1091b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<kFormatThreadThreads;i++) { 1092b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tests[i].isRunning()) { 1093b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru stillRunning = TRUE; 1094b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else if (haveDisplayedInfo[i] == FALSE) { 1095b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Thread # %d is complete..", i); 1096b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tests[i].getError(theErr)) { 10976d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru dataerrln(UnicodeString("#") + i + ": " + theErr); 1098b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::errorFunc(); 1099b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1100b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru haveDisplayedInfo[i] = TRUE; 1101b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1102b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1103b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } while (stillRunning); 1104b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1105b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 1106b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // All threads have finished. 1107b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // 110859d709d503bab6e2b61931737e662dd293b40578ccornelius assertSuccess("finalizing ThreadSafeFormat", threadSafeErr, TRUE); 1109b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1110b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_FORMATTING */ 1111b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1112b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1113b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1114b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1115b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1116b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 1117b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 1118b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// Collation threading test 1119b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 1120b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 1121b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#if !UCONFIG_NO_COLLATION 1122b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1123b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kCollatorThreadThreads 10 // # of threads to spawn 1124b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#define kCollatorThreadPatience kCollatorThreadThreads*30 1125b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1126b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querustruct Line { 1127b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar buff[25]; 1128b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t buflen; 1129b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} ; 1130b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 113154dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UBool 113254dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusskipLineBecauseOfBug(const UChar *s, int32_t length) { 113354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // TODO: Fix ICU ticket #8052 113454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(length >= 3 && 113554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius (s[0] == 0xfb2 || s[0] == 0xfb3) && 113654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius s[1] == 0x334 && 113754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius (s[2] == 0xf73 || s[2] == 0xf75 || s[2] == 0xf81)) { 113854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return TRUE; 113954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 114054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return FALSE; 114154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 114254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 114354dcd9b6a06071f647dac967e9e267abb9410720Craig Corneliusstatic UCollationResult 114454dcd9b6a06071f647dac967e9e267abb9410720Craig CorneliusnormalizeResult(int32_t result) { 114554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius return result<0 ? UCOL_LESS : result==0 ? UCOL_EQUAL : UCOL_GREATER; 114654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius} 114754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 1148b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass CollatorThreadTest : public ThreadWithStatus 1149b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 11501b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertprivate: 115154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius const Collator *coll; 1152b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const Line *lines; 1153b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t noLines; 115454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UBool isAtLeastUCA62; 1155b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 1156b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru CollatorThreadTest() : ThreadWithStatus(), 1157b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru coll(NULL), 1158b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lines(NULL), 115954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius noLines(0), 116054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius isAtLeastUCA62(TRUE) 1161b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1162b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 116354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius void setCollator(Collator *c, Line *l, int32_t nl, UBool atLeastUCA62) 1164b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1165b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru coll = c; 1166b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lines = l; 1167b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru noLines = nl; 116854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius isAtLeastUCA62 = atLeastUCA62; 1169b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1170b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual void run() { 1171b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t sk1[1024], sk2[1024]; 1172b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint8_t *oldSk = NULL, *newSk = sk1; 117354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t oldLen = 0; 117454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t prev = 0; 1175b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i = 0; 117627f654740f2a26ad62a5c155af9199af9e69b889claireho 1177b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i = 0; i < noLines; i++) { 117854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(lines[i].buflen == 0) { continue; } 117954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 118054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(skipLineBecauseOfBug(lines[i].buff, lines[i].buflen)) { continue; } 118127f654740f2a26ad62a5c155af9199af9e69b889claireho 118254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t resLen = coll->getSortKey(lines[i].buff, lines[i].buflen, newSk, 1024); 118327f654740f2a26ad62a5c155af9199af9e69b889claireho 1184b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(oldSk != NULL) { 118554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t skres = strcmp((char *)oldSk, (char *)newSk); 118654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t cmpres = coll->compare(lines[prev].buff, lines[prev].buflen, lines[i].buff, lines[i].buflen); 118754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t cmpres2 = coll->compare(lines[i].buff, lines[i].buflen, lines[prev].buff, lines[prev].buflen); 118827f654740f2a26ad62a5c155af9199af9e69b889claireho 1189b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(cmpres != -cmpres2) { 11908393335b955da7340c9f19b1b4b2d6c0c2c04be7Craig Cornelius error(UnicodeString("Compare result not symmetrical on line ") + (i + 1)); 1191b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1192b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 119327f654740f2a26ad62a5c155af9199af9e69b889claireho 119454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(cmpres != normalizeResult(skres)) { 119554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius error(UnicodeString("Difference between coll->compare and sortkey compare on line ") + (i + 1)); 1196b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1197b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 119827f654740f2a26ad62a5c155af9199af9e69b889claireho 119954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t res = cmpres; 120054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(res == 0 && !isAtLeastUCA62) { 120154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Up to UCA 6.1, the collation test files use a custom tie-breaker, 120254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // comparing the raw input strings. 120354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius res = u_strcmpCodePointOrder(lines[prev].buff, lines[i].buff); 120454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Starting with UCA 6.2, the collation test files use the standard UCA tie-breaker, 120554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // comparing the NFD versions of the input strings, 120654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // which we do via setting strength=identical. 120754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } 1208b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(res > 0) { 120954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius error(UnicodeString("Line is not greater or equal than previous line, for line ") + (i + 1)); 1210b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1211b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1212b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 121327f654740f2a26ad62a5c155af9199af9e69b889claireho 1214b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldSk = newSk; 1215b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru oldLen = resLen; 121659d709d503bab6e2b61931737e662dd293b40578ccornelius (void)oldLen; // Suppress set but not used warning. 121754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius prev = i; 121827f654740f2a26ad62a5c155af9199af9e69b889claireho 1219b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru newSk = (newSk == sk1)?sk2:sk1; 1220b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1221b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1222b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1223b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1224b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MultithreadTest::TestCollators() 1225b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1226b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1227b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UErrorCode status = U_ZERO_ERROR; 1228b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru FILE *testFile = NULL; 1229b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char testDataPath[1024]; 1230b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(testDataPath, IntlTest::getSourceTestData(status)); 1231b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (U_FAILURE(status)) { 1232b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("ERROR: could not open test data %s", u_errorName(status)); 1233b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1234b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1235b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcat(testDataPath, "CollationTest_"); 1236b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1237b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char* type = "NON_IGNORABLE"; 1238b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1239b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const char *ext = ".txt"; 1240b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(testFile) { 1241b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fclose(testFile); 1242b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1243b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru char buffer[1024]; 1244b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(buffer, testDataPath); 1245b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcat(buffer, type); 1246b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru size_t bufLen = strlen(buffer); 1247b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1248b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we try to open 3 files: 1249b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // path/CollationTest_type.txt 1250b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // path/CollationTest_type_SHORT.txt 1251b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // path/CollationTest_type_STUB.txt 1252b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // we are going to test with the first one that we manage to open. 1253b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1254b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(buffer+bufLen, ext); 1255b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1256b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testFile = fopen(buffer, "rb"); 1257b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1258b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(testFile == 0) { 1259b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(buffer+bufLen, "_SHORT"); 1260b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcat(buffer, ext); 1261b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testFile = fopen(buffer, "rb"); 1262b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1263b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(testFile == 0) { 1264b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcpy(buffer+bufLen, "_STUB"); 1265b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru strcat(buffer, ext); 1266b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru testFile = fopen(buffer, "rb"); 1267b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1268b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (testFile == 0) { 1269b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru *(buffer+bufLen) = 0; 12706d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru dataerrln("could not open any of the conformance test files, tried opening base %s", buffer); 12711b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert return; 1272b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } else { 1273b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru infoln( 1274b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "INFO: Working with the stub file.\n" 1275b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "If you need the full conformance test, please\n" 1276b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "download the appropriate data files from:\n" 1277b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru "http://source.icu-project.org/repos/icu/tools/trunk/unicodetools/com/ibm/text/data/"); 1278b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1279b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1280b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1281b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 128254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius LocalArray<Line> lines(new Line[200000]); 128354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius memset(lines.getAlias(), 0, sizeof(Line)*200000); 1284b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t lineNum = 0; 1285b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1286b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UChar bufferU[1024]; 1287b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru uint32_t first = 0; 1288b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1289b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru while (fgets(buffer, 1024, testFile) != NULL) { 129054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius if(*buffer == 0 || buffer[0] == '#') { 129154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // Store empty and comment lines so that errors are reported 129254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius // for the real test file lines. 129354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius lines[lineNum].buflen = 0; 129454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius lines[lineNum].buff[0] = 0; 129554dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius } else { 129654dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius int32_t buflen = u_parseString(buffer, bufferU, 1024, &first, &status); 129754dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius lines[lineNum].buflen = buflen; 129854dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius u_memcpy(lines[lineNum].buff, bufferU, buflen); 129954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius lines[lineNum].buff[buflen] = 0; 1300b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1301b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru lineNum++; 1302b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1303b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fclose(testFile); 1304b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 13056d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru dataerrln("Couldn't read the test file!"); 1306b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1307b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1308b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 130954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UVersionInfo uniVersion; 131054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius static const UVersionInfo v62 = { 6, 2, 0, 0 }; 131154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius u_getUnicodeVersion(uniVersion); 131254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius UBool isAtLeastUCA62 = uprv_memcmp(uniVersion, v62, 4) >= 0; 131354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius 131454dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius LocalPointer<Collator> coll(Collator::createInstance(Locale::getRoot(), status)); 1315b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(U_FAILURE(status)) { 13166d5deb12725f146643d443090dfa11b206df528aJean-Baptiste Queru errcheckln(status, "Couldn't open UCA collator"); 1317b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1318b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 131954dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius coll->setAttribute(UCOL_NORMALIZATION_MODE, UCOL_ON, status); 132054dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius coll->setAttribute(UCOL_CASE_FIRST, UCOL_OFF, status); 132154dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius coll->setAttribute(UCOL_CASE_LEVEL, UCOL_OFF, status); 132254dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius coll->setAttribute(UCOL_STRENGTH, isAtLeastUCA62 ? UCOL_IDENTICAL : UCOL_TERTIARY, status); 132354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius coll->setAttribute(UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, status); 1324b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1325b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t noSpawned = 0; 1326b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t spawnResult = 0; 132750294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho LocalArray<CollatorThreadTest> tests(new CollatorThreadTest[kCollatorThreadThreads]); 1328b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1329b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(UnicodeString("Spawning: ") + kCollatorThreadThreads + " threads * " + kFormatThreadIterations + " iterations each."); 1330b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t j = 0; 1331b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < kCollatorThreadThreads; j++) { 1332b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //logln("Setting collator %i", j); 133354dcd9b6a06071f647dac967e9e267abb9410720Craig Cornelius tests[j].setCollator(coll.getAlias(), lines.getAlias(), lineNum, isAtLeastUCA62); 1334b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1335b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < kCollatorThreadThreads; j++) { 1336b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru log("%i ", j); 1337b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru spawnResult = tests[j].start(); 1338b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(spawnResult != 0) { 1339b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru infoln("THREAD INFO: Couldn't spawn more than %i threads", noSpawned); 1340b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1341b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1342b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru noSpawned++; 1343b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1344b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Spawned all"); 1345b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (noSpawned == 0) { 1346b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("No threads could be spawned."); 1347b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1348b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1349b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1350b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(int32_t patience = kCollatorThreadPatience;patience > 0; patience --) 1351b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1352b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Waiting..."); 1353b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1354b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1355b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t terrs = 0; 1356b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t completed =0; 1357b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1358b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<kCollatorThreadThreads;i++) 1359b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1360b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tests[i].isRunning() == FALSE) 1361b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1362b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru completed++; 1363b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1364b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru //logln(UnicodeString("Test #") + i + " is complete.. "); 1365b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1366b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString theErr; 1367b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tests[i].getError(theErr)) 1368b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1369b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru terrs++; 1370b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln(UnicodeString("#") + i + ": " + theErr); 1371b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1372b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // print out the error, too, if any. 1373b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1374b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1375b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Completed %i tests", completed); 1376b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1377b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(completed == noSpawned) 1378b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1379b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Done! All %i tests are finished", noSpawned); 1380b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1381b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(terrs) 1382b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1383b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("There were errors."); 1384b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::errorFunc(); 1385b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1386b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru return; 1387b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1388b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1389b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(900); 1390b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1391b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("patience exceeded. "); 1392b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::errorFunc(); 1393b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1394b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1395b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif /* #if !UCONFIG_NO_COLLATION */ 1396b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1397b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1398b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1399b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1400b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 1401b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 14021b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// StringThreadTest2 1403b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// 1404b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru//------------------------------------------------------------------------------------------- 1405b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1406b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int kStringThreadIterations = 2500;// # of iterations per thread 1407b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int kStringThreadThreads = 10; // # of threads to spawn 1408b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruconst int kStringThreadPatience = 120; // time in seconds to wait for all threads 1409b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1410b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1411b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruclass StringThreadTest2 : public ThreadWithStatus 1412b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1413b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Querupublic: 1414b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int fNum; 1415b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int fTraceInfo; 1416b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru const UnicodeString *fSharedString; 1417b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1418b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StringThreadTest2(const UnicodeString *sharedString, int num) // constructor is NOT multithread safe. 1419b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru : ThreadWithStatus(), 1420b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fNum(num), 1421b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo(0), 1422b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fSharedString(sharedString) 1423b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1424b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru }; 1425b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1426b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1427b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru virtual void run() 1428b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1429b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo = 1; 1430b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int loopCount = 0; 1431b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1432b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for (loopCount = 0; loopCount < kStringThreadIterations; loopCount++) { 1433b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (*fSharedString != "This is the original test string.") { 1434b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru error("Original string is corrupt."); 1435b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1436b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1437b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString s1 = *fSharedString; 1438b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s1 += "cat this"; 1439b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString s2(s1); 1440b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString s3 = *fSharedString; 1441b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s2 = s3; 1442b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s3.truncate(12); 1443b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru s2.truncate(0); 1444b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1445b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1446b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while (fNum == 4) {SimpleThread::sleep(10000);} // Force a failure by preventing thread from finishing 1447b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru fTraceInfo = 2; 1448b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 14491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1450b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru}; 1451b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1452b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru// ** The actual test function. 1453b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1454b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queruvoid MultithreadTest::TestString() 1455b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru{ 1456b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int patience; 1457b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int terrs = 0; 1458b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int j; 1459b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1460b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString *testString = new UnicodeString("This is the original test string."); 1461b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 146250294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // Not using LocalArray<StringThreadTest2> tests[kStringThreadThreads]; 146350294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // because we don't always want to delete them. 146450294ead5e5d23f5bbfed76e00e6b510bd41eee1claireho // See the comments below the cleanupAndReturn label. 1465b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru StringThreadTest2 *tests[kStringThreadThreads]; 1466b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < kStringThreadThreads; j++) { 1467b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru tests[j] = new StringThreadTest2(testString, j); 1468b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 14691b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1470b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(UnicodeString("Spawning: ") + kStringThreadThreads + " threads * " + kStringThreadIterations + " iterations each."); 1471b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < kStringThreadThreads; j++) { 1472b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t threadStatus = tests[j]->start(); 1473b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (threadStatus != 0) { 1474b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("System Error %d starting thread number %d.", threadStatus, j); 14751b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert SimpleThread::errorFunc(); 1476b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru goto cleanupAndReturn; 1477b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1478b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1479b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1480b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(patience = kStringThreadPatience;patience > 0; patience --) 1481b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1482b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Waiting..."); 1483b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1484b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t i; 1485b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru terrs = 0; 1486b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru int32_t completed =0; 1487b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1488b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(i=0;i<kStringThreadThreads;i++) { 1489b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (tests[i]->isRunning() == FALSE) 1490b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1491b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru completed++; 14921b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1493b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln(UnicodeString("Test #") + i + " is complete.. "); 14941b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1495b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru UnicodeString theErr; 1496b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(tests[i]->getError(theErr)) 1497b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1498b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru terrs++; 1499b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln(UnicodeString("#") + i + ": " + theErr); 1500b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1501b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // print out the error, too, if any. 1502b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1503b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 15041b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1505b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(completed == kStringThreadThreads) 1506b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru { 1507b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru logln("Done!"); 1508b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if(terrs) { 1509b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("There were errors."); 1510b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1511b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru break; 1512b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1513b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1514b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru SimpleThread::sleep(900); 1515b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1516b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1517b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (patience <= 0) { 1518b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru errln("patience exceeded. "); 1519b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru // while (TRUE) {SimpleThread::sleep(10000);} // TODO: for debugging. Sleep forever on failure. 1520b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru terrs++; 1521b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1522b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1523b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (terrs > 0) { 15241b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert SimpleThread::errorFunc(); 1525b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1526b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1527b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste QuerucleanupAndReturn: 1528b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if (terrs == 0) { 1529b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru /* 1530b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru Don't clean up if there are errors. This prevents crashes if the 1531b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru threads are still running and using this data. This will only happen 1532b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru if there is an error with the test, ICU, or the machine is too slow. 1533b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru It's better to leak than crash. 1534b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru */ 1535b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru for(j = 0; j < kStringThreadThreads; j++) { 1536b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete tests[j]; 1537b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1538b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru delete testString; 1539b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru } 1540b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru} 1541b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru 1542fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1543fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// Test for ticket #10673, race in cache code in AnyTransliterator. 1544fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// It's difficult to make the original unsafe code actually fail, but 15451b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert// this test will fairly reliably take the code path for races in 1546fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius// populating the cache. 1547fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1548fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_TRANSLITERATION 1549fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusclass TxThread: public SimpleThread { 1550fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius private: 1551fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius Transliterator *fSharedTranslit; 1552fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius public: 1553fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool fSuccess; 1554fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius TxThread(Transliterator *tx) : fSharedTranslit(tx), fSuccess(FALSE) {}; 1555fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius ~TxThread(); 1556fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius void run(); 1557fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius}; 1558fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1559fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusTxThread::~TxThread() {} 1560fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid TxThread::run() { 1561fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UnicodeString greekString("\\u03B4\\u03B9\\u03B1\\u03C6\\u03BF\\u03C1\\u03B5\\u03C4\\u03B9\\u03BA\\u03BF\\u03CD\\u03C2"); 1562fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius greekString = greekString.unescape(); 1563fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSharedTranslit->transliterate(greekString); 1564fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius fSuccess = greekString[0] == 0x64; // 'd'. The whole transliterated string is "diaphoretikous" (accented u). 1565fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1566fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif 15671b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1568fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1569fceb39872958b9fa2505e63f8b8699a9e0f882f4ccorneliusvoid MultithreadTest::TestAnyTranslit() { 1570fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#if !UCONFIG_NO_TRANSLITERATION 1571fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UErrorCode status = U_ZERO_ERROR; 1572fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius LocalPointer<Transliterator> tx(Transliterator::createInstance("Any-Latin", UTRANS_FORWARD, status)); 1573fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (U_FAILURE(status)) { 1574fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius dataerrln("File %s, Line %d: Error, status = %s", __FILE__, __LINE__, u_errorName(status)); 1575fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius return; 1576fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1577fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius TxThread * threads[4]; 1578fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t i; 1579fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (i=0; i<4; i++) { 1580fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius threads[i] = new TxThread(tx.getAlias()); 1581fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1582fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (i=0; i<4; i++) { 1583fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius threads[i]->start(); 1584fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1585fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius int32_t patience = 100; 1586fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool success; 1587fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius UBool someThreadRunning; 1588fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius do { 1589fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius someThreadRunning = FALSE; 1590fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius success = TRUE; 1591fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (i=0; i<4; i++) { 1592fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (threads[i]->isRunning()) { 1593fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius someThreadRunning = TRUE; 1594fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius SimpleThread::sleep(10); 1595fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius break; 1596fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } else { 1597fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (threads[i]->fSuccess == FALSE) { 1598fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius success = FALSE; 1599fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1600fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1601fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1602fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } while (someThreadRunning && --patience > 0); 1603fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1604fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (patience <= 0) { 1605fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius errln("File %s, Line %d: Error, one or more threads did not complete.", __FILE__, __LINE__); 1606fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1607fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius if (success == FALSE) { 1608fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius errln("File %s, Line %d: Error, transliteration result incorrect.", __FILE__, __LINE__); 1609fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 16101b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1611fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius for (i=0; i<4; i++) { 1612fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius delete threads[i]; 1613fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius } 1614fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius#endif // !UCONFIG_NO_TRANSLITERATION 1615fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius} 1616fceb39872958b9fa2505e63f8b8699a9e0f882f4ccornelius 1617f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1618f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Condition Variables Test 1619f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Create a swarm of threads. 1620f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Using a mutex and a condition variables each thread 1621f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Increments a global count of started threads. 1622f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Broadcasts that it has started. 1623f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Waits on the condition that all threads have started. 1624f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Increments a global count of finished threads. 1625f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Waits on the condition that all threads have finished. 1626f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Exits. 1627f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1628f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass CondThread: public SimpleThread { 1629f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius public: 1630f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius CondThread() :fFinished(false) {}; 1631f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ~CondThread() {}; 1632f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius void run(); 1633f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius bool fFinished; 1634f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 1635f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1636f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UMutex gCTMutex = U_MUTEX_INITIALIZER; 1637f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic UConditionVar gCTConditionVar = U_CONDITION_INITIALIZER; 1638f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusint gConditionTestOne = 1; // Value one. Non-const, extern linkage to inhibit 1639f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // compiler assuming a known value. 16401b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubertint gStartedThreads; 1641f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusint gFinishedThreads; 1642f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic const int NUMTHREADS = 10; 1643f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1644f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic MultithreadTest *gThisTest = NULL; // Make test frame work functions available to 1645f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // non-member functions. 1646f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1647f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius// Worker thread function. 1648f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid CondThread::run() { 16491b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert umtx_lock(&gCTMutex); 1650f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gStartedThreads += gConditionTestOne; 1651f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condBroadcast(&gCTConditionVar); 16521b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert 1653f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (gStartedThreads < NUMTHREADS) { 1654f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (gFinishedThreads != 0) { 16551b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert gThisTest->errln("File %s, Line %d: Error, gStartedThreads = %d, gFinishedThreads = %d", 1656f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius __FILE__, __LINE__, gStartedThreads, gFinishedThreads); 1657f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1658f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condWait(&gCTConditionVar, &gCTMutex); 1659f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1660f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1661f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gFinishedThreads += gConditionTestOne; 1662f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius fFinished = true; 1663f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condBroadcast(&gCTConditionVar); 1664f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1665f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (gFinishedThreads < NUMTHREADS) { 1666f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condWait(&gCTConditionVar, &gCTMutex); 1667f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1668f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1669f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1670f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1671f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid MultithreadTest::TestConditionVariables() { 1672f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gThisTest = this; 1673f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gStartedThreads = 0; 1674f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gFinishedThreads = 0; 1675f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius int i; 1676f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1677f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gCTMutex); 1678f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius CondThread *threads[NUMTHREADS]; 1679f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (i=0; i<NUMTHREADS; ++i) { 1680f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius threads[i] = new CondThread; 1681f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius threads[i]->start(); 1682f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1683f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1684f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (gStartedThreads < NUMTHREADS) { 1685f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condWait(&gCTConditionVar, &gCTMutex); 1686f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1687f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1688f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (gFinishedThreads < NUMTHREADS) { 1689f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condWait(&gCTConditionVar, &gCTMutex); 1690f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1691f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1692f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1693f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1694f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (i=0; i<NUMTHREADS; ++i) { 1695f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (!threads[i]->fFinished) { 1696f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius errln("File %s, Line %d: Error, threads[%d]->fFinished == false", __FILE__, __LINE__, i); 1697f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1698f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete threads[i]; 1699f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1700f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1701f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1702f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic const char *gCacheLocales[] = {"en_US", "en_GB", "fr_FR", "fr"}; 1703f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic int32_t gObjectsCreated = 0; 1704f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusstatic const int32_t CACHE_LOAD = 3; 1705f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1706f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass UCTMultiThreadItem : public SharedObject { 1707f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius public: 1708f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius char *value; 17091b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert UCTMultiThreadItem(const char *x) : value(NULL) { 1710f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius value = uprv_strdup(x); 1711f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 17121b7d32f919554dda9c193b32188251337bc756f1Fredrik Roubert virtual ~UCTMultiThreadItem() { 1713f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius uprv_free(value); 1714f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1715f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 1716f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1717f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_BEGIN 1718f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1719f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliustemplate<> U_EXPORT 1720f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusconst UCTMultiThreadItem *LocaleCacheKey<UCTMultiThreadItem>::createObject( 1721f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const void * /*unused*/, UErrorCode & /* status */) const { 1722f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Since multiple threads are hitting the cache for the first time, 1723f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // no objects should be created yet. 1724f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gCTMutex); 1725f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (gObjectsCreated != 0) { 1726f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gThisTest->errln("Expected no objects to be created yet."); 1727f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1728f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1729f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1730f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Big, expensive object that takes 1 second to create. 1731f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius SimpleThread::sleep(1000); 1732f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1733f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Log that we created an object. 1734f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gCTMutex); 1735f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ++gObjectsCreated; 1736f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1737f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UCTMultiThreadItem *result = new UCTMultiThreadItem(fLoc.getName()); 1738f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius result->addRef(); 1739f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius return result; 1740f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1741f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1742f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusU_NAMESPACE_END 1743f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1744f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusclass UnifiedCacheThread: public SimpleThread { 1745f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius public: 1746f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnifiedCacheThread(const char *loc) : fLoc(loc) {}; 1747f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ~UnifiedCacheThread() {}; 1748f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius void run(); 1749f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const char *fLoc; 1750f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius}; 1751f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1752f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid UnifiedCacheThread::run() { 1753f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 1754f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UnifiedCache *cache = UnifiedCache::getInstance(status); 1755f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(status == U_ZERO_ERROR); 1756f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UCTMultiThreadItem *item = NULL; 1757f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cache->get(LocaleCacheKey<UCTMultiThreadItem>(fLoc), item, status); 1758f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(item != NULL); 1759f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius if (uprv_strcmp(fLoc, item->value)) { 1760f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gThisTest->errln("Expected %s, got %s", fLoc, item->value); 1761f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1762f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius item->removeRef(); 1763f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1764f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Mark this thread as finished 1765f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gCTMutex); 1766f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius ++gFinishedThreads; 1767f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condBroadcast(&gCTConditionVar); 1768f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1769f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1770f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1771f9878a236aa0d9662d8e40cafdaf2e04cd615835ccorneliusvoid MultithreadTest::TestUnifiedCache() { 1772f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UErrorCode status = U_ZERO_ERROR; 1773f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius const UnifiedCache *cache = UnifiedCache::getInstance(status); 1774f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius U_ASSERT(cache != NULL); 1775f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius cache->flush(); 1776f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gThisTest = this; 1777f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gFinishedThreads = 0; 1778f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius gObjectsCreated = 0; 1779f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1780f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius UnifiedCacheThread *threads[CACHE_LOAD][UPRV_LENGTHOF(gCacheLocales)]; 1781f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i=0; i<CACHE_LOAD; ++i) { 1782f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t j=0; j<UPRV_LENGTHOF(gCacheLocales); ++j) { 1783f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius threads[i][j] = new UnifiedCacheThread(gCacheLocales[j]); 1784f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius threads[i][j]->start(); 1785f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1786f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1787f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // Wait on all the threads to complete verify that LENGTHOF(gCacheLocales) 1788f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // objects were created. 1789f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_lock(&gCTMutex); 1790f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius while (gFinishedThreads < CACHE_LOAD*UPRV_LENGTHOF(gCacheLocales)) { 1791f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_condWait(&gCTConditionVar, &gCTMutex); 1792f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1793f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius assertEquals("Objects created", UPRV_LENGTHOF(gCacheLocales), gObjectsCreated); 1794f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius umtx_unlock(&gCTMutex); 1795f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1796f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius // clean up threads 1797f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t i=0; i<CACHE_LOAD; ++i) { 1798f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius for (int32_t j=0; j<UPRV_LENGTHOF(gCacheLocales); ++j) { 1799f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius delete threads[i][j]; 1800f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1801f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius } 1802f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius} 1803f9878a236aa0d9662d8e40cafdaf2e04cd615835ccornelius 1804b13da9df870a61b11249bf741347908dbea0edd8Jean-Baptiste Queru#endif // ICU_USE_THREADS 1805