1f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/********************************************************************
2f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * COPYRIGHT:
3f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * Copyright (c) 1999-2010, International Business Machines Corporation and
4f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) * others. All Rights Reserved.
5f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles) ********************************************************************/
6f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
7f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(hpux)
8f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# ifndef _INCLUDE_POSIX_SOURCE
9f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#  define _INCLUDE_POSIX_SOURCE
10f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# endif
11f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
12f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
13f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "simplethread.h"
14f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
15f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/utypes.h"
16f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ustring.h"
17f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "umutex.h"
18f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cmemory.h"
19f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "cstring.h"
20f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "uparse.h"
21f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/localpointer.h"
22f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/resbund.h"
23f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/udata.h"
24f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/uloc.h"
25f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h"
26f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "putilimp.h"
27f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(U_WINDOWS) && !defined(XP_MAC) && !defined(U_RHAPSODY)
28f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define POSIX 1
29f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
30f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
31f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Needed by z/OS to get usleep */
32f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(OS390)
33f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __DOT1 1
34f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __UU
35f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XOPEN_SOURCE_EXTENDED 1
36f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _XPG4_2
37f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XPG4_2
38f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
39f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <unistd.h>
40f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/*#include "platform_xopen_source_extended.h"*/
41f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
42f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(POSIX) || defined(U_SOLARIS) || defined(U_AIX) || defined(U_HPUX)
43f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
44f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define HAVE_IMP
45f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
46f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (ICU_USE_THREADS == 1)
47f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <pthread.h>
48f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
49f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
50f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(__hpux) && defined(HPUX_CMA)
51f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# if defined(read)  // read being defined as cma_read causes trouble with iostream::read
52f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#  undef read
53f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)# endif
54f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
55f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
56f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */
57f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef __EXTENSIONS__
58f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __EXTENSIONS__
59f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
60f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
61f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if defined(OS390)
62f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <sys/types.h>
63f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
64f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
65f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !defined(OS390)
66f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <signal.h>
67f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
68f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
69f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define _XPG4_2 for Solaris and friends. */
70f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _XPG4_2
71f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _XPG4_2
72f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
73f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
74f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define __USE_XOPEN_EXTENDED for Linux and glibc. */
75f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef __USE_XOPEN_EXTENDED
76f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define __USE_XOPEN_EXTENDED
77f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
78f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
79f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */
80f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED
81f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define _INCLUDE_XOPEN_SOURCE_EXTENDED
82f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
83f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
84f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <unistd.h>
85f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
86f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
87f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)/* HPUX */
88f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#ifdef sleep
89f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#undef sleep
90f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
91f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
92f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
93f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
94f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "tsmthred.h"
95f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
96f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TSMTHREAD_FAIL(msg) errln("%s at file %s, line %d", msg, __FILE__, __LINE__)
97f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define TSMTHREAD_ASSERT(expr) {if (!(expr)) {TSMTHREAD_FAIL("Fail");}}
98f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
99f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)MultithreadTest::MultithreadTest()
100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)MultithreadTest::~MultithreadTest()
104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if (ICU_USE_THREADS==0)
110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::runIndexedTest( int32_t index, UBool exec,
111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                const char* &name, char* /*par*/ ) {
112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if (exec) logln("TestSuite MultithreadTest: ");
113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(index == 0)
115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      name = "NO_THREADED_TESTS";
116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  else
117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      name = "";
118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  if(exec) { logln("MultithreadTest - test DISABLED.  ICU_USE_THREADS set to 0, check your configuration if this is a problem..");
120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)  }
121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#else
123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <stdio.h>
125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <string.h>
126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include <ctype.h>    // tolower, toupper
127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/putil.h"
129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// for mthreadtest
131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/numfmt.h"
132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/choicfmt.h"
133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/msgfmt.h"
134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/locid.h"
135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/ucol.h"
136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "unicode/calendar.h"
137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#include "ucaconf.h"
138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void SimpleThread::errorFunc() {
140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // *(char *)0 = 3;            // Force entry into a debugger via a crash;
141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::runIndexedTest( int32_t index, UBool exec,
144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                const char* &name, char* /*par*/ ) {
145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (exec)
146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln("TestSuite MultithreadTest: ");
147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    switch (index) {
148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 0:
149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = "TestThreads";
150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (exec)
151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TestThreads();
152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 1:
155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = "TestMutex";
156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (exec)
157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TestMutex();
158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 2:
161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = "TestThreadedIntl";
162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (exec) {
164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TestThreadedIntl();
165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 3:
170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      name = "TestCollators";
171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_COLLATION
172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      if (exec) {
173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TestCollators();
174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      }
175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_COLLATION */
176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      break;
177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    case 4:
179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = "TestString";
180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (exec) {
181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TestString();
182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break;
184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    default:
186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        name = "";
187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        break; //needed to end loop
188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   TestThreads -- see if threads really work at all.
195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   Set up N threads pointing at N chars. When they are started, they will
197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   each sleep 1 second and then set their chars. At the end we make sure they
198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   are all set.
199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------------------
201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define THREADTEST_NRTHREADS 8
202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class TestThreadsThread : public SimpleThread
204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestThreadsThread(char* whatToChange) { fWhatToChange = whatToChange; }
207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void run() { SimpleThread::sleep(1000);
208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         Mutex m;
209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                         *fWhatToChange = '*';
210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char *fWhatToChange;
213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::TestThreads()
216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char threadTestChars[THREADTEST_NRTHREADS + 1];
218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread *threads[THREADTEST_NRTHREADS];
219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t numThreadsStarted = 0;
220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t i;
222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0;i<THREADTEST_NRTHREADS;i++)
223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        threadTestChars[i] = ' ';
225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        threads[i] = new TestThreadsThread(&threadTestChars[i]);
226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    threadTestChars[THREADTEST_NRTHREADS] = '\0';
228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln("->" + UnicodeString(threadTestChars) + "<- Firing off threads.. ");
230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0;i<THREADTEST_NRTHREADS;i++)
231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (threads[i]->start() != 0) {
233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errln("Error starting thread %d", i);
234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            numThreadsStarted++;
237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(100);
239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln(" Subthread started.");
240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
241f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
242f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln("Waiting for threads to be set..");
243f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (numThreadsStarted == 0) {
244f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("No threads could be started for testing!");
245f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
246f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
247f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
248f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t patience = 40; // seconds to wait
249f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
250f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while(patience--)
251f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
252f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t count = 0;
253f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_lock(NULL);
254f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0;i<THREADTEST_NRTHREADS;i++)
255f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
256f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(threadTestChars[i] == '*')
257f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
258f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                count++;
259f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
260f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
261f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_unlock(NULL);
262f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
263f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(count == THREADTEST_NRTHREADS)
264f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
265f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            logln("->" + UnicodeString(threadTestChars) + "<- Got all threads! cya");
266f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            for(i=0;i<THREADTEST_NRTHREADS;i++)
267f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
268f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                delete threads[i];
269f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
270f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
271f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
272f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
273f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln("->" + UnicodeString(threadTestChars) + "<- Waiting..");
274f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(500);
275f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
276f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
277f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errln("->" + UnicodeString(threadTestChars) + "<- PATIENCE EXCEEDED!! Still missing some.");
278f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(i=0;i<THREADTEST_NRTHREADS;i++)
279f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
280f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete threads[i];
281f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
282f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
283f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
284f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
285f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-----------------------------------------------------------------------
286f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
287f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//  TestMutex  - a simple (non-stress) test to verify that ICU mutexes
288f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//               are actually mutexing.  Does not test the use of
289f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//               mutexes within ICU services, but rather that the
290f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//               platform's mutex support is at least superficially there.
291f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
292f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//----------------------------------------------------------------------
293f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX    gTestMutexA = NULL;
294f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static UMTX    gTestMutexB = NULL;
295f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
296f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int     gThreadsStarted = 0;
297f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int     gThreadsInMiddle = 0;
298f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int     gThreadsDone = 0;
299f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
300f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static const int TESTMUTEX_THREAD_COUNT = 4;
301f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
302f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)static int safeIncr(int &var, int amt) {
303f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Thread safe (using global mutex) increment of a variable.
304f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Return the updated value.
305f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Can also be used as a safe load of a variable by incrementing it by 0.
306f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Mutex m;
307f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    var += amt;
308f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return var;
309f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
310f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
311f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class TestMutexThread : public SimpleThread
312f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
313f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
314f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void run()
315f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
316f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // This is the code that each of the spawned threads runs.
317f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // All of the spawned threads bunch up together at each of the two mutexes
318f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // because the main holds the mutexes until they do.
319f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //
320f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        safeIncr(gThreadsStarted, 1);
321f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_lock(&gTestMutexA);
322f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_unlock(&gTestMutexA);
323f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        safeIncr(gThreadsInMiddle, 1);
324f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_lock(&gTestMutexB);
325f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        umtx_unlock(&gTestMutexB);
326f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        safeIncr(gThreadsDone, 1);
327f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
328f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
329f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
330f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::TestMutex()
331f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
332f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Start up the test threads.  They should all pile up waiting on
333f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // gTestMutexA, which we (the main thread) hold until the test threads
334f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   all get there.
335f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gThreadsStarted = 0;
336f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gThreadsInMiddle = 0;
337f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gThreadsDone = 0;
338f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(&gTestMutexA);
339f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TestMutexThread  *threads[TESTMUTEX_THREAD_COUNT];
340f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int i;
341f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t numThreadsStarted = 0;
342f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
343f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        threads[i] = new TestMutexThread;
344f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (threads[i]->start() != 0) {
345f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errln("Error starting thread %d", i);
346f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
347f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        else {
348f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            numThreadsStarted++;
349f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
350f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
351f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (numThreadsStarted == 0) {
352f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("No threads could be started for testing!");
353f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
354f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
355f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
356f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int patience = 0;
357f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (safeIncr(gThreadsStarted, 0) != TESTMUTEX_THREAD_COUNT) {
358f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (patience++ > 24) {
359f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TSMTHREAD_FAIL("Patience Exceeded");
360f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
361f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
362f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(500);
363f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
364f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // None of the test threads should have advanced past the first mutex.
365f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TSMTHREAD_ASSERT(gThreadsInMiddle==0);
366f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TSMTHREAD_ASSERT(gThreadsDone==0);
367f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
368f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  All of the test threads have made it to the first mutex.
369f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  We (the main thread) now let them advance to the second mutex,
370f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   where they should all pile up again.
371f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_lock(&gTestMutexB);
372f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(&gTestMutexA);
373f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
374f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    patience = 0;
375f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (safeIncr(gThreadsInMiddle, 0) != TESTMUTEX_THREAD_COUNT) {
376f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (patience++ > 24) {
377f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TSMTHREAD_FAIL("Patience Exceeded");
378f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
379f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
380f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(500);
381f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
382f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    TSMTHREAD_ASSERT(gThreadsDone==0);
383f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
384f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  All test threads made it to the second mutex.
385f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //   Now let them proceed from there.  They will all terminate.
386f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_unlock(&gTestMutexB);
387f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    patience = 0;
388f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (safeIncr(gThreadsDone, 0) != TESTMUTEX_THREAD_COUNT) {
389f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (patience++ > 24) {
390f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            TSMTHREAD_FAIL("Patience Exceeded");
391f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
392f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
393f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(500);
394f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
395f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
396f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // All threads made it by both mutexes.
397f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Destroy the test mutexes.
398f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_destroy(&gTestMutexA);
399f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    umtx_destroy(&gTestMutexB);
400f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gTestMutexA=NULL;
401f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    gTestMutexB=NULL;
402f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
403f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for (i=0; i<TESTMUTEX_THREAD_COUNT; i++) {
404f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete threads[i];
405f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
406f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
407f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
408f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
409f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
410f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
411f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
412f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// class ThreadWithStatus - a thread that we can check the status and error condition of
413f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
414f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
415f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class ThreadWithStatus : public SimpleThread
416f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
417f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
418f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool  getError() { return (fErrors > 0); }
419f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool  getError(UnicodeString& fillinError) { fillinError = fErrorString; return (fErrors > 0); }
420f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual ~ThreadWithStatus(){}
421f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)protected:
422f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ThreadWithStatus() :  fErrors(0) {}
423f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void error(const UnicodeString &error) {
424f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fErrors++; fErrorString = error;
425f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::errorFunc();
426f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
427f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void error() { error("An error occured."); }
428f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
429f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t fErrors;
430f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString fErrorString;
431f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
432f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
433f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
434f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
435f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
436f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
437f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   TestMultithreadedIntl.  Test ICU Formatting n a multi-threaded environment
438f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
439f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
440f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
441f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
442f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// * Show exactly where the string's differences lie.
443f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UnicodeString showDifference(const UnicodeString& expected, const UnicodeString& result)
444f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
445f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString res;
446f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    res = expected + "<Expected\n";
447f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(expected.length() != result.length())
448f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        res += " [ Different lengths ] \n";
449f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    else
450f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
451f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(int32_t i=0;i<expected.length();i++)
452f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
453f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(expected[i] == result[i])
454f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
455f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                res += " ";
456f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
457f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            else
458f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
459f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                res += "|";
460f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
461f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
462f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        res += "<Differences";
463f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        res += "\n";
464f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
465f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    res += result + "<Result\n";
466f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
467f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return res;
468f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
469f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
470f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
471f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
472f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
473f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
474f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
475f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   FormatThreadTest - a thread that tests performing a number of numberformats.
476f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
477f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
478f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
479f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kFormatThreadIterations = 20;  // # of iterations per thread
480f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kFormatThreadThreads    = 10;  // # of threads to spawn
481f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kFormatThreadPatience   = 60;  // time in seconds to wait for all threads
482f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
483f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_FORMATTING
484f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
485f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
486f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
487f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct FormatThreadTestData
488f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
489f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    double number;
490f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString string;
491f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FormatThreadTestData(double a, const UnicodeString& b) : number(a),string(b) {}
492f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} ;
493f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
494f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
495f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// "Someone from {2} is receiving a #{0} error - {1}. Their telephone call is costing {3 number,currency}."
496f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
497f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void formatErrorMessage(UErrorCode &realStatus, const UnicodeString& pattern, const Locale& theLocale,
498f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UErrorCode inStatus0, /* statusString 1 */ const Locale &inCountry2, double currency3, // these numbers are the message arguments.
499f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     UnicodeString &result)
500f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
501f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(realStatus))
502f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return; // you messed up
503f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
504f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString errString1(u_errorName(inStatus0));
505f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
506f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString countryName2;
507f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    inCountry2.getDisplayCountry(theLocale,countryName2);
508f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
509f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Formattable myArgs[] = {
510f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Formattable((int32_t)inStatus0),   // inStatus0      {0}
511f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Formattable(errString1), // statusString1 {1}
512f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Formattable(countryName2),  // inCountry2 {2}
513f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Formattable(currency3)// currency3  {3,number,currency}
514f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
515f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
516f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    MessageFormat *fmt = new MessageFormat("MessageFormat's API is broken!!!!!!!!!!!",realStatus);
517f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fmt->setLocale(theLocale);
518f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fmt->applyPattern(pattern, realStatus);
519f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
520f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(realStatus)) {
521f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete fmt;
522f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
523f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
524f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
525f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FieldPosition ignore = 0;
526f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fmt->format(myArgs,4,result,ignore,realStatus);
527f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
528f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    delete fmt;
529f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
530f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
531f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
532f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)UBool U_CALLCONV isAcceptable(void *, const char *, const char *, const UDataInfo *) {
533f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    return TRUE;
534f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
535f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
536f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//static UMTX debugMutex = NULL;
537f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//static UMTX gDebugMutex;
538f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
539f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
540f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class FormatThreadTest : public ThreadWithStatus
541f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
542f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
543f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int     fNum;
544f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int     fTraceInfo;
545f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
546f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FormatThreadTest() // constructor is NOT multithread safe.
547f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        : ThreadWithStatus(),
548f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNum(0),
549f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo(0),
550f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fOffset(0)
551f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // the locale to use
552f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
553f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        static int32_t fgOffset = 0;
554f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fgOffset += 3;
555f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fOffset = fgOffset;
556f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
557f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
558f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
559f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void run()
560f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
561f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo                     = 1;
562f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        LocalPointer<NumberFormat> percentFormatter;
563f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        UErrorCode status = U_ZERO_ERROR;
564f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
565f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0
566f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // debugging code,
567f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (int i=0; i<4000; i++) {
568f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status = U_ZERO_ERROR;
569f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UDataMemory *data1 = udata_openChoice(0, "res", "en_US", isAcceptable, 0, &status);
570f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UDataMemory *data2 = udata_openChoice(0, "res", "fr", isAcceptable, 0, &status);
571f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_close(data1);
572f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            udata_close(data2);
573f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (U_FAILURE(status)) {
574f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("udata_openChoice failed.\n");
575f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
576f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
577f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
578f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
579f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
580f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
581f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if 0
582f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // debugging code,
583f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int m;
584f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (m=0; m<4000; m++) {
585f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            status         = U_ZERO_ERROR;
586f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UResourceBundle *res   = NULL;
587f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            const char *localeName = NULL;
588f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
589f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            Locale  loc = Locale::getEnglish();
590f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
591f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            localeName = loc.getName();
592f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // localeName = "en";
593f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
594f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // ResourceBundle bund = ResourceBundle(0, loc, status);
595f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //umtx_lock(&gDebugMutex);
596f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            res = ures_open(NULL, localeName, &status);
597f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //umtx_unlock(&gDebugMutex);
598f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
599f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //umtx_lock(&gDebugMutex);
600f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ures_close(res);
601f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //umtx_unlock(&gDebugMutex);
602f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
603f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (U_FAILURE(status)) {
604f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("Resource bundle construction failed.\n");
605f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
606f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
607f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
608f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
609f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif
610f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
611f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Keep this data here to avoid static initialization.
612f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        FormatThreadTestData kNumberFormatTestData[] =
613f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
614f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            FormatThreadTestData((double)5.0, UnicodeString("5", "")),
615f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 6.0, UnicodeString("6", "")),
616f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 20.0, UnicodeString("20", "")),
617f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 8.0, UnicodeString("8", "")),
618f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 8.3, UnicodeString("8.3", "")),
619f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 12345, UnicodeString("12,345", "")),
620f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 81890.23, UnicodeString("81,890.23", "")),
621f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        };
622f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t kNumberFormatTestDataLength = (int32_t)(sizeof(kNumberFormatTestData) /
623f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                        sizeof(kNumberFormatTestData[0]));
624f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
625f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // Keep this data here to avoid static initialization.
626f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        FormatThreadTestData kPercentFormatTestData[] =
627f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
628f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            FormatThreadTestData((double)5.0, CharsToUnicodeString("500\\u00a0%")),
629f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 1.0, CharsToUnicodeString("100\\u00a0%")),
630f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData( 0.26, CharsToUnicodeString("26\\u00a0%")),
631f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData(
632f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                   16384.99, CharsToUnicodeString("1\\u00a0638\\u00a0499\\u00a0%")), // U+00a0 = NBSP
633f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                FormatThreadTestData(
634f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    81890.23, CharsToUnicodeString("8\\u00a0189\\u00a0023\\u00a0%")),
635f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        };
636f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t kPercentFormatTestDataLength =
637f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                (int32_t)(sizeof(kPercentFormatTestData) / sizeof(kPercentFormatTestData[0]));
638f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t iteration;
639f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
640f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        status = U_ZERO_ERROR;
641f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        LocalPointer<NumberFormat> formatter(NumberFormat::createInstance(Locale::getEnglish(),status));
642f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(status)) {
643f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            error("Error on NumberFormat::createInstance().");
644f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            goto cleanupAndReturn;
645f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
646f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
647f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        percentFormatter.adoptInstead(NumberFormat::createPercentInstance(Locale::getFrench(),status));
648f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(U_FAILURE(status))             {
649f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            error("Error on NumberFormat::createPercentInstance().");
650f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            goto cleanupAndReturn;
651f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
652f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
653f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(iteration = 0;!getError() && iteration<kFormatThreadIterations;iteration++)
654f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
655f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
656f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t whichLine = (iteration + fOffset)%kNumberFormatTestDataLength;
657f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
658f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString  output;
659f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
660f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            formatter->format(kNumberFormatTestData[whichLine].number, output);
661f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
662f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(0 != output.compare(kNumberFormatTestData[whichLine].string)) {
663f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("format().. expected " + kNumberFormatTestData[whichLine].string
664f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        + " got " + output);
665f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto cleanupAndReturn;
666f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
667f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
668f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Now check percent.
669f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            output.remove();
670f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            whichLine = (iteration + fOffset)%kPercentFormatTestDataLength;
671f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
672f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            percentFormatter->format(kPercentFormatTestData[whichLine].number, output);
673f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(0 != output.compare(kPercentFormatTestData[whichLine].string))
674f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
675f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("percent format().. \n" +
676f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        showDifference(kPercentFormatTestData[whichLine].string,output));
677f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto cleanupAndReturn;
678f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
679f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
680f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // Test message error
681f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            const int       kNumberOfMessageTests = 3;
682f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UErrorCode      statusToCheck;
683f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString   patternToCheck;
684f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            Locale          messageLocale;
685f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            Locale          countryToCheck;
686f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            double          currencyToCheck;
687f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
688f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString   expected;
689f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
690f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            // load the cases.
691f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            switch((iteration+fOffset) % kNumberOfMessageTests)
692f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
693f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            default:
694f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case 0:
695f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                statusToCheck=                      U_FILE_ACCESS_ERROR;
696f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                patternToCheck=        "0:Someone from {2} is receiving a #{0}"
697f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       " error - {1}. Their telephone call is costing "
698f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                       "{3,number,currency}."; // number,currency
699f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                messageLocale=                      Locale("en","US");
700f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                countryToCheck=                     Locale("","HR");
701f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                currencyToCheck=                    8192.77;
702f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expected=  "0:Someone from Croatia is receiving a #4 error - "
703f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            "U_FILE_ACCESS_ERROR. Their telephone call is costing $8,192.77.";
704f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
705f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case 1:
706f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                statusToCheck=                      U_INDEX_OUTOFBOUNDS_ERROR;
707f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                patternToCheck=                     "1:A customer in {2} is receiving a #{0} error - {1}. Their telephone call is costing {3,number,currency}."; // number,currency
708f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                messageLocale=                      Locale("de","DE@currency=DEM");
709f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                countryToCheck=                     Locale("","BF");
710f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                currencyToCheck=                    2.32;
711f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expected=                           CharsToUnicodeString(
712f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                                    "1:A customer in Burkina Faso is receiving a #8 error - U_INDEX_OUTOFBOUNDS_ERROR. Their telephone call is costing 2,32\\u00A0DM.");
713f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
714f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            case 2:
715f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                statusToCheck=                      U_MEMORY_ALLOCATION_ERROR;
716f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                patternToCheck=   "2:user in {2} is receiving a #{0} error - {1}. "
717f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  "They insist they just spent {3,number,currency} "
718f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                  "on memory."; // number,currency
719f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                messageLocale=                      Locale("de","AT@currency=ATS"); // Austrian German
720f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                countryToCheck=                     Locale("","US"); // hmm
721f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                currencyToCheck=                    40193.12;
722f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                expected=       CharsToUnicodeString(
723f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            "2:user in Vereinigte Staaten is receiving a #7 error"
724f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            " - U_MEMORY_ALLOCATION_ERROR. They insist they just spent"
725f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                            " \\u00f6S\\u00A040.193,12 on memory.");
726f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
727f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
728f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
729f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString result;
730f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UErrorCode status = U_ZERO_ERROR;
731f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            formatErrorMessage(status,patternToCheck,messageLocale,statusToCheck,
732f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                                countryToCheck,currencyToCheck,result);
733f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(U_FAILURE(status))
734f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
735f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UnicodeString tmp(u_errorName(status));
736f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("Failure on message format, pattern=" + patternToCheck +
737f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        ", error = " + tmp);
738f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto cleanupAndReturn;
739f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
740f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
741f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(result != expected)
742f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
743f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("PatternFormat: \n" + showDifference(expected,result));
744f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                goto cleanupAndReturn;
745f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
746f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }   /*  end of for loop */
747f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
748f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanupAndReturn:
749f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //  while (fNum == 4) {SimpleThread::sleep(10000);}   // Force a failure by preventing thread from finishing
750f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo = 2;
751f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
752f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
753f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
754f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t fOffset; // where we are testing from.
755f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
756f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
757f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ** The actual test function.
758f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
759f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::TestThreadedIntl()
760f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
761f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int i;
762f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString theErr;
763f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool   haveDisplayedInfo[kFormatThreadThreads];
764f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    static const int32_t PATIENCE_SECONDS = 45;
765f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
766f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
767f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  Create and start the test threads
768f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
769f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln("Spawning: %d threads * %d iterations each.",
770f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                kFormatThreadThreads, kFormatThreadIterations);
771f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    LocalArray<FormatThreadTest> tests(new FormatThreadTest[kFormatThreadThreads]);
772f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(int32_t j = 0; j < kFormatThreadThreads; j++) {
773f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tests[j].fNum = j;
774f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t threadStatus = tests[j].start();
775f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (threadStatus != 0) {
776f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errln("System Error %d starting thread number %d.", threadStatus, j);
777f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            SimpleThread::errorFunc();
778f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
779f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
780f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        haveDisplayedInfo[j] = FALSE;
781f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
782f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
783f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
784f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Spin, waiting for the test threads to finish.
785f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UBool   stillRunning;
786f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UDate startTime, endTime;
787f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    startTime = Calendar::getNow();
788f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    do {
789f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*  Spin until the test threads  complete. */
790f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        stillRunning = FALSE;
791f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        endTime = Calendar::getNow();
792f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (((int32_t)(endTime - startTime)/U_MILLIS_PER_SECOND) > PATIENCE_SECONDS) {
793f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errln("Patience exceeded. Test is taking too long.");
794f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
795f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
796f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*
797f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         The following sleep must be here because the *BSD operating systems
798f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         have a brain dead thread scheduler. They starve the child threads from
799f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)         CPU time.
800f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        */
801f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(1); // yield
802f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0;i<kFormatThreadThreads;i++) {
803f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (tests[i].isRunning()) {
804f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                stillRunning = TRUE;
805f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else if (haveDisplayedInfo[i] == FALSE) {
806f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                logln("Thread # %d is complete..", i);
807f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(tests[i].getError(theErr)) {
808f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    dataerrln(UnicodeString("#") + i + ": " + theErr);
809f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    SimpleThread::errorFunc();
810f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
811f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                haveDisplayedInfo[i] = TRUE;
812f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
813f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
814f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    } while (stillRunning);
815f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
816f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
817f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //  All threads have finished.
818f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    //
819f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
820f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_FORMATTING */
821f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
822f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
823f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
824f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
825f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
826f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
827f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
828f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// Collation threading test
829f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
830f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
831f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#if !UCONFIG_NO_COLLATION
832f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
833f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define kCollatorThreadThreads   10  // # of threads to spawn
834f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#define kCollatorThreadPatience kCollatorThreadThreads*30
835f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
836f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)struct Line {
837f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar buff[25];
838f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t buflen;
839f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)} ;
840f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
841f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class CollatorThreadTest : public ThreadWithStatus
842f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
843f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)private:
844f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UCollator *coll;
845f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const Line *lines;
846f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t noLines;
847f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
848f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    CollatorThreadTest()  : ThreadWithStatus(),
849f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        coll(NULL),
850f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lines(NULL),
851f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        noLines(0)
852f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
853f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
854f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    void setCollator(UCollator *c, Line *l, int32_t nl)
855f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
856f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        coll = c;
857f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lines = l;
858f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        noLines = nl;
859f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
860f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void run() {
861f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //sleep(10000);
862f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t line = 0;
863f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
864f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uint8_t sk1[1024], sk2[1024];
865f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        uint8_t *oldSk = NULL, *newSk = sk1;
866f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t resLen = 0, oldLen = 0;
867f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t i = 0;
868f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
869f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i = 0; i < noLines; i++) {
870f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            resLen = ucol_getSortKey(coll, lines[i].buff, lines[i].buflen, newSk, 1024);
871f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
872f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            int32_t res = 0, cmpres = 0, cmpres2 = 0;
873f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
874f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(oldSk != NULL) {
875f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                res = strcmp((char *)oldSk, (char *)newSk);
876f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cmpres = ucol_strcoll(coll, lines[i-1].buff, lines[i-1].buflen, lines[i].buff, lines[i].buflen);
877f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                cmpres2 = ucol_strcoll(coll, lines[i].buff, lines[i].buflen, lines[i-1].buff, lines[i-1].buflen);
878f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                //cmpres = res;
879f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                //cmpres2 = -cmpres;
880f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
881f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(cmpres != -cmpres2) {
882f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    error("Compare result not symmetrical on line "+ line);
883f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
884f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
885f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
886f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(((res&0x80000000) != (cmpres&0x80000000)) || (res == 0 && cmpres != 0) || (res != 0 && cmpres == 0)) {
887f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    error(UnicodeString("Difference between ucol_strcoll and sortkey compare on line ")+ UnicodeString(line));
888f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
889f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
890f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
891f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(res > 0) {
892f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    error(UnicodeString("Line %i is not greater or equal than previous line ")+ UnicodeString(i));
893f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    break;
894f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                } else if(res == 0) { /* equal */
895f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    res = u_strcmpCodePointOrder(lines[i-1].buff, lines[i].buff);
896f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    if (res == 0) {
897f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        error(UnicodeString("Probable error in test file on line %i (comparing identical strings)")+ UnicodeString(i));
898f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
899f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
900f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    /*
901f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     * UCA 6.0 test files can have lines that compare == if they are
902f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     * different strings but canonically equivalent.
903f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    else if (res > 0) {
904f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        error(UnicodeString("Sortkeys are identical, but code point compare gives >0 on line ")+ UnicodeString(i));
905f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                        break;
906f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    }
907f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                     */
908f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
909f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
910f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
911f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            oldSk = newSk;
912f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            oldLen = resLen;
913f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
914f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            newSk = (newSk == sk1)?sk2:sk1;
915f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
916f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
917f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
918f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
919f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::TestCollators()
920f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
921f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
922f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UErrorCode status = U_ZERO_ERROR;
923f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    FILE *testFile = NULL;
924f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char testDataPath[1024];
925f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcpy(testDataPath, IntlTest::getSourceTestData(status));
926f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (U_FAILURE(status)) {
927f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("ERROR: could not open test data %s", u_errorName(status));
928f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
929f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
930f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcat(testDataPath, "CollationTest_");
931f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
932f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char* type = "NON_IGNORABLE";
933f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
934f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const char *ext = ".txt";
935f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(testFile) {
936f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fclose(testFile);
937f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
938f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    char buffer[1024];
939f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcpy(buffer, testDataPath);
940f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcat(buffer, type);
941f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    size_t bufLen = strlen(buffer);
942f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
943f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // we try to open 3 files:
944f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // path/CollationTest_type.txt
945f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // path/CollationTest_type_SHORT.txt
946f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // path/CollationTest_type_STUB.txt
947f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // we are going to test with the first one that we manage to open.
948f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
949f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    strcpy(buffer+bufLen, ext);
950f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
951f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    testFile = fopen(buffer, "rb");
952f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
953f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(testFile == 0) {
954f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        strcpy(buffer+bufLen, "_SHORT");
955f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        strcat(buffer, ext);
956f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        testFile = fopen(buffer, "rb");
957f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
958f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(testFile == 0) {
959f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            strcpy(buffer+bufLen, "_STUB");
960f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            strcat(buffer, ext);
961f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            testFile = fopen(buffer, "rb");
962f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
963f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (testFile == 0) {
964f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                *(buffer+bufLen) = 0;
965f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                dataerrln("could not open any of the conformance test files, tried opening base %s", buffer);
966f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                return;
967f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            } else {
968f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                infoln(
969f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    "INFO: Working with the stub file.\n"
970f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    "If you need the full conformance test, please\n"
971f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    "download the appropriate data files from:\n"
972f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    "http://source.icu-project.org/repos/icu/tools/trunk/unicodetools/com/ibm/text/data/");
973f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
974f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
975f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
976f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
977f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    Line *lines = new Line[200000];
978f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    memset(lines, 0, sizeof(Line)*200000);
979f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t lineNum = 0;
980f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
981f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UChar bufferU[1024];
982f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t buflen = 0;
983f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t first = 0;
984f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    uint32_t offset = 0;
985f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
986f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    while (fgets(buffer, 1024, testFile) != NULL) {
987f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = 0;
988f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(*buffer == 0 || strlen(buffer) < 3 || buffer[0] == '#') {
989f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            continue;
990f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
991f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        offset = u_parseString(buffer, bufferU, 1024, &first, &status);
992f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        buflen = offset;
993f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        bufferU[offset++] = 0;
994f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lines[lineNum].buflen = buflen;
995f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //lines[lineNum].buff = new UChar[buflen+1];
996f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        u_memcpy(lines[lineNum].buff, bufferU, buflen);
997f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        lineNum++;
998f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
999f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    fclose(testFile);
1000f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
1001f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      dataerrln("Couldn't read the test file!");
1002f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)      return;
1003f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1004f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1005f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UCollator *coll = ucol_open("root", &status);
1006f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if(U_FAILURE(status)) {
1007f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errcheckln(status, "Couldn't open UCA collator");
1008f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1009f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1010f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_setAttribute(coll, UCOL_NORMALIZATION_MODE, UCOL_ON, &status);
1011f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_setAttribute(coll, UCOL_CASE_FIRST, UCOL_OFF, &status);
1012f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_setAttribute(coll, UCOL_CASE_LEVEL, UCOL_OFF, &status);
1013f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_setAttribute(coll, UCOL_STRENGTH, UCOL_TERTIARY, &status);
1014f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_setAttribute(coll, UCOL_ALTERNATE_HANDLING, UCOL_NON_IGNORABLE, &status);
1015f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1016f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t noSpawned = 0;
1017f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t spawnResult = 0;
1018f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    LocalArray<CollatorThreadTest> tests(new CollatorThreadTest[kCollatorThreadThreads]);
1019f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1020f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln(UnicodeString("Spawning: ") + kCollatorThreadThreads + " threads * " + kFormatThreadIterations + " iterations each.");
1021f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int32_t j = 0;
1022f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(j = 0; j < kCollatorThreadThreads; j++) {
1023f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //logln("Setting collator %i", j);
1024f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tests[j].setCollator(coll, lines, lineNum);
1025f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1026f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(j = 0; j < kCollatorThreadThreads; j++) {
1027f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        log("%i ", j);
1028f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        spawnResult = tests[j].start();
1029f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(spawnResult != 0) {
1030f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            infoln("THREAD INFO: Couldn't spawn more than %i threads", noSpawned);
1031f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1032f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1033f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        noSpawned++;
1034f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1035f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln("Spawned all");
1036f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (noSpawned == 0) {
1037f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("No threads could be spawned.");
1038f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        return;
1039f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1040f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1041f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(int32_t patience = kCollatorThreadPatience;patience > 0; patience --)
1042f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1043f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln("Waiting...");
1044f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1045f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t i;
1046f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t terrs = 0;
1047f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t completed =0;
1048f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1049f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0;i<kCollatorThreadThreads;i++)
1050f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1051f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (tests[i].isRunning() == FALSE)
1052f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
1053f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                completed++;
1054f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1055f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                //logln(UnicodeString("Test #") + i + " is complete.. ");
1056f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1057f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UnicodeString theErr;
1058f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(tests[i].getError(theErr))
1059f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                {
1060f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    terrs++;
1061f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    errln(UnicodeString("#") + i + ": " + theErr);
1062f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1063f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // print out the error, too, if any.
1064f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1065f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1066f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln("Completed %i tests", completed);
1067f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1068f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(completed == noSpawned)
1069f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1070f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            logln("Done! All %i tests are finished", noSpawned);
1071f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1072f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(terrs)
1073f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
1074f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                errln("There were errors.");
1075f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                SimpleThread::errorFunc();
1076f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1077f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            ucol_close(coll);
1078f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //for(i = 0; i < lineNum; i++) {
1079f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //delete[] lines[i].buff;
1080f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            //}
1081f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete[] lines;
1082f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1083f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            return;
1084f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1085f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1086f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(900);
1087f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1088f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    errln("patience exceeded. ");
1089f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    SimpleThread::errorFunc();
1090f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    ucol_close(coll);
1091f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1092f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1093f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif /* #if !UCONFIG_NO_COLLATION */
1094f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1095f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1096f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1097f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1098f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
1099f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
1100f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//   StringThreadTest2
1101f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//
1102f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)//-------------------------------------------------------------------------------------------
1103f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1104f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kStringThreadIterations = 2500;// # of iterations per thread
1105f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kStringThreadThreads    = 10;  // # of threads to spawn
1106f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)const int kStringThreadPatience   = 120; // time in seconds to wait for all threads
1107f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1108f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1109f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)class StringThreadTest2 : public ThreadWithStatus
1110f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1111f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)public:
1112f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                 fNum;
1113f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int                 fTraceInfo;
1114f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    const UnicodeString *fSharedString;
1115f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1116f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    StringThreadTest2(const UnicodeString *sharedString, int num) // constructor is NOT multithread safe.
1117f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        : ThreadWithStatus(),
1118f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fNum(num),
1119f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo(0),
1120f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fSharedString(sharedString)
1121f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1122f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    };
1123f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1124f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1125f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    virtual void run()
1126f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1127f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo    = 1;
1128f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int loopCount = 0;
1129f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1130f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for (loopCount = 0; loopCount < kStringThreadIterations; loopCount++) {
1131f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (*fSharedString != "This is the original test string.") {
1132f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                error("Original string is corrupt.");
1133f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                break;
1134f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1135f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString s1 = *fSharedString;
1136f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            s1 += "cat this";
1137f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString s2(s1);
1138f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            UnicodeString s3 = *fSharedString;
1139f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            s2 = s3;
1140f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            s3.truncate(12);
1141f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            s2.truncate(0);
1142f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1143f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1144f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        //  while (fNum == 4) {SimpleThread::sleep(10000);}   // Force a failure by preventing thread from finishing
1145f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        fTraceInfo = 2;
1146f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1147f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1148f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)};
1149f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1150f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)// ** The actual test function.
1151f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1152f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)void MultithreadTest::TestString()
1153f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles){
1154f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int     patience;
1155f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int     terrs = 0;
1156f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    int     j;
1157f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1158f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    UnicodeString *testString = new UnicodeString("This is the original test string.");
1159f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1160f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // Not using LocalArray<StringThreadTest2> tests[kStringThreadThreads];
1161f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // because we don't always want to delete them.
1162f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    // See the comments below the cleanupAndReturn label.
1163f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    StringThreadTest2  *tests[kStringThreadThreads];
1164f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(j = 0; j < kStringThreadThreads; j++) {
1165f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        tests[j] = new StringThreadTest2(testString, j);
1166f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1167f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1168f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    logln(UnicodeString("Spawning: ") + kStringThreadThreads + " threads * " + kStringThreadIterations + " iterations each.");
1169f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(j = 0; j < kStringThreadThreads; j++) {
1170f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t threadStatus = tests[j]->start();
1171f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if (threadStatus != 0) {
1172f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            errln("System Error %d starting thread number %d.", threadStatus, j);
1173f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            SimpleThread::errorFunc();
1174f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            goto cleanupAndReturn;
1175f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1176f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1177f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1178f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    for(patience = kStringThreadPatience;patience > 0; patience --)
1179f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    {
1180f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        logln("Waiting...");
1181f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1182f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t i;
1183f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        terrs = 0;
1184f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        int32_t completed =0;
1185f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1186f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(i=0;i<kStringThreadThreads;i++) {
1187f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if (tests[i]->isRunning() == FALSE)
1188f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            {
1189f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                completed++;
1190f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1191f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                logln(UnicodeString("Test #") + i + " is complete.. ");
1192f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1193f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                UnicodeString theErr;
1194f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                if(tests[i]->getError(theErr))
1195f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                {
1196f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    terrs++;
1197f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                    errln(UnicodeString("#") + i + ": " + theErr);
1198f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                }
1199f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                // print out the error, too, if any.
1200f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1201f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1202f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1203f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if(completed == kStringThreadThreads)
1204f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        {
1205f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            logln("Done!");
1206f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            if(terrs) {
1207f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)                errln("There were errors.");
1208f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            }
1209f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            break;
1210f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1211f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1212f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::sleep(900);
1213f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1214f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1215f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (patience <= 0) {
1216f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        errln("patience exceeded. ");
1217f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        // while (TRUE) {SimpleThread::sleep(10000);}   // TODO:   for debugging.  Sleep forever on failure.
1218f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        terrs++;
1219f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1220f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1221f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (terrs > 0) {
1222f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        SimpleThread::errorFunc();
1223f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1224f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1225f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)cleanupAndReturn:
1226f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    if (terrs == 0) {
1227f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        /*
1228f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        Don't clean up if there are errors. This prevents crashes if the
1229f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        threads are still running and using this data. This will only happen
1230f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        if there is an error with the test, ICU, or the machine is too slow.
1231f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        It's better to leak than crash.
1232f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        */
1233f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        for(j = 0; j < kStringThreadThreads; j++) {
1234f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)            delete tests[j];
1235f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        }
1236f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)        delete testString;
1237f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)    }
1238f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)}
1239f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)
1240f4ed1cf5d184064c4cf0e4359c6d5d8aadb50afaTorne (Richard Coles)#endif // ICU_USE_THREADS
1241