]> git.saurik.com Git - apple/icu.git/blame - icuSources/test/intltest/simplethread.cpp
ICU-57166.0.1.tar.gz
[apple/icu.git] / icuSources / test / intltest / simplethread.cpp
CommitLineData
729e4ab9
A
1/********************************************************************
2 * COPYRIGHT:
2ca993e8 3 * Copyright (c) 1999-2015, International Business Machines Corporation and
729e4ab9
A
4 * others. All Rights Reserved.
5 ********************************************************************/
6
7#if defined(hpux)
8# ifndef _INCLUDE_POSIX_SOURCE
9# define _INCLUDE_POSIX_SOURCE
10# endif
11#endif
12
4388f060
A
13/* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */
14#ifndef __EXTENSIONS__
15#define __EXTENSIONS__
16#endif
17
18// Defines _XOPEN_SOURCE for access to POSIX functions.
19// Must be before any other #includes.
20#include "uposixdefs.h"
21
729e4ab9
A
22#include "simplethread.h"
23
24#include "unicode/utypes.h"
25#include "unicode/ustring.h"
26#include "umutex.h"
27#include "cmemory.h"
28#include "cstring.h"
29#include "uparse.h"
30#include "unicode/resbund.h"
31#include "unicode/udata.h"
32#include "unicode/uloc.h"
33#include "unicode/locid.h"
34#include "putilimp.h"
51004dcb 35#include "intltest.h"
729e4ab9
A
36
37#include <stdio.h>
38#include <string.h>
39#include <ctype.h> // tolower, toupper
40
4388f060
A
41#if U_PLATFORM_USES_ONLY_WIN32_API
42 /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */
43# undef POSIX
44#elif U_PLATFORM_IMPLEMENTS_POSIX
45# define POSIX
46#else
47# undef POSIX
729e4ab9
A
48#endif
49
50/* Needed by z/OS to get usleep */
4388f060 51#if U_PLATFORM == U_PF_OS390
729e4ab9 52#define __DOT1 1
57a6839d
A
53#ifndef __UU
54# define __UU
55#endif
729e4ab9 56#ifndef _XPG4_2
57a6839d 57# define _XPG4_2
729e4ab9
A
58#endif
59#include <unistd.h>
729e4ab9
A
60#endif
61
4388f060 62#if defined(POSIX)
729e4ab9
A
63#define HAVE_IMP
64
729e4ab9 65#include <pthread.h>
729e4ab9 66
4388f060 67#if U_PLATFORM == U_PF_OS390
729e4ab9
A
68#include <sys/types.h>
69#endif
70
4388f060 71#if U_PLATFORM != U_PF_OS390
729e4ab9
A
72#include <signal.h>
73#endif
74
75/* Define _XPG4_2 for Solaris and friends. */
76#ifndef _XPG4_2
77#define _XPG4_2
78#endif
79
80/* Define __USE_XOPEN_EXTENDED for Linux and glibc. */
81#ifndef __USE_XOPEN_EXTENDED
82#define __USE_XOPEN_EXTENDED
83#endif
84
85/* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */
86#ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED
87#define _INCLUDE_XOPEN_SOURCE_EXTENDED
88#endif
89
90#include <unistd.h>
91
92#endif
93/* HPUX */
94#ifdef sleep
95#undef sleep
96#endif
97
98
729e4ab9
A
99#include "unicode/putil.h"
100
101/* for mthreadtest*/
102#include "unicode/numfmt.h"
103#include "unicode/choicfmt.h"
104#include "unicode/msgfmt.h"
105#include "unicode/locid.h"
106#include "unicode/ucol.h"
107#include "unicode/calendar.h"
108#include "ucaconf.h"
109
4388f060 110#if U_PLATFORM_USES_ONLY_WIN32_API
729e4ab9
A
111#define HAVE_IMP
112
113# define VC_EXTRALEAN
114# define WIN32_LEAN_AND_MEAN
115# define NOUSER
116# define NOSERVICE
117# define NOIME
118# define NOMCX
119#include <windows.h>
120#include <process.h>
121
122//-----------------------------------------------------------------------------------
123//
124// class SimpleThread Windows Implementation
125//
126//-----------------------------------------------------------------------------------
127struct Win32ThreadImplementation
128{
129 HANDLE fHandle;
130 unsigned int fThreadID;
131};
132
133
134extern "C" unsigned int __stdcall SimpleThreadProc(void *arg)
135{
136 ((SimpleThread*)arg)->run();
137 return 0;
138}
139
140SimpleThread::SimpleThread()
141:fImplementation(0)
142{
143 Win32ThreadImplementation *imp = new Win32ThreadImplementation;
144 imp->fHandle = 0;
145 fImplementation = imp;
146}
147
148SimpleThread::~SimpleThread()
149{
150 // Destructor. Because we start the thread running with _beginthreadex(),
151 // we own the Windows HANDLE for the thread and must
152 // close it here.
153 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
154 if (imp != 0) {
155 if (imp->fHandle != 0) {
156 CloseHandle(imp->fHandle);
157 imp->fHandle = 0;
158 }
159 }
160 delete (Win32ThreadImplementation*)fImplementation;
161}
162
163int32_t SimpleThread::start()
164{
165 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
166 if(imp->fHandle != NULL) {
167 // The thread appears to have already been started.
168 // This is probably an error on the part of our caller.
169 return -1;
170 }
171
172 imp->fHandle = (HANDLE) _beginthreadex(
173 NULL, // Security
174 0x20000, // Stack Size
175 SimpleThreadProc, // Function to Run
176 (void *)this, // Arg List
177 0, // initflag. Start running, not suspended
178 &imp->fThreadID // thraddr
179 );
180
181 if (imp->fHandle == 0) {
182 // An error occured
183 int err = errno;
184 if (err == 0) {
185 err = -1;
186 }
187 return err;
188 }
189 return 0;
190}
191
192
2ca993e8 193void SimpleThread::join() {
729e4ab9 194 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation;
729e4ab9
A
195 if (imp->fHandle == 0) {
196 // No handle, thread must not be running.
2ca993e8 197 return;
729e4ab9 198 }
2ca993e8 199 WaitForSingleObject(imp->fHandle, INFINITE);
729e4ab9
A
200}
201
202#endif
203
204
205//-----------------------------------------------------------------------------------
206//
207// class SimpleThread POSIX implementation
208//
729e4ab9 209//-----------------------------------------------------------------------------------
4388f060 210#if defined(POSIX)
729e4ab9
A
211#define HAVE_IMP
212
213struct PosixThreadImplementation
214{
215 pthread_t fThread;
729e4ab9
A
216};
217
218extern "C" void* SimpleThreadProc(void *arg)
219{
220 // This is the code that is run in the new separate thread.
221 SimpleThread *This = (SimpleThread *)arg;
2ca993e8 222 This->run();
729e4ab9
A
223 return 0;
224}
225
226SimpleThread::SimpleThread()
227{
228 PosixThreadImplementation *imp = new PosixThreadImplementation;
729e4ab9
A
229 fImplementation = imp;
230}
231
232SimpleThread::~SimpleThread()
233{
234 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
729e4ab9
A
235 delete imp;
236 fImplementation = (void *)0xdeadbeef;
237}
238
239int32_t SimpleThread::start()
240{
241 int32_t rc;
242 static pthread_attr_t attr;
243 static UBool attrIsInitialized = FALSE;
244
245 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
729e4ab9 246
729e4ab9
A
247 if (attrIsInitialized == FALSE) {
248 rc = pthread_attr_init(&attr);
4388f060 249#if U_PLATFORM == U_PF_OS390
729e4ab9
A
250 {
251 int detachstate = 0; // jdc30: detach state of zero causes
252 //threads created with this attr to be in
253 //an undetached state. An undetached
254 //thread will keep its resources after
255 //termination.
256 pthread_attr_setdetachstate(&attr, &detachstate);
257 }
258#else
259 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
260 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
261#endif
262 attrIsInitialized = TRUE;
263 }
2ca993e8 264 rc = pthread_create(&(imp->fThread), &attr, &SimpleThreadProc, (void*)this);
729e4ab9
A
265
266 if (rc != 0) {
267 // some kind of error occured, the thread did not start.
729e4ab9
A
268 }
269
270 return rc;
271}
272
2ca993e8 273void SimpleThread::join() {
729e4ab9 274 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation;
2ca993e8 275 pthread_join(imp->fThread, NULL);
729e4ab9
A
276}
277
2ca993e8
A
278#endif
279// end POSIX
729e4ab9 280
2ca993e8
A
281
282#ifndef HAVE_IMP
283#error No implementation for threads! Cannot test.
729e4ab9
A
284#endif
285
2ca993e8
A
286
287class ThreadPoolThread: public SimpleThread {
288 public:
289 ThreadPoolThread(ThreadPoolBase *pool, int32_t threadNum) : fPool(pool), fNum(threadNum) {};
290 virtual void run() {fPool->callFn(fNum); }
291 ThreadPoolBase *fPool;
292 int32_t fNum;
293};
294
295
296ThreadPoolBase::ThreadPoolBase(IntlTest *test, int32_t howMany) :
297 fIntlTest(test), fNumThreads(howMany), fThreads(NULL) {
298 fThreads = new SimpleThread *[fNumThreads];
299 if (fThreads == NULL) {
300 fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
301 return;
729e4ab9 302 }
2ca993e8
A
303
304 for (int i=0; i<fNumThreads; i++) {
305 fThreads[i] = new ThreadPoolThread(this, i);
306 if (fThreads[i] == NULL) {
307 fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
308 }
729e4ab9 309 }
729e4ab9
A
310}
311
2ca993e8
A
312void ThreadPoolBase::start() {
313 for (int i=0; i<fNumThreads; i++) {
314 if (fThreads && fThreads[i]) {
315 fThreads[i]->start();
316 }
317 }
318}
729e4ab9 319
2ca993e8
A
320void ThreadPoolBase::join() {
321 for (int i=0; i<fNumThreads; i++) {
322 if (fThreads && fThreads[i]) {
323 fThreads[i]->join();
324 }
325 }
326}
729e4ab9 327
2ca993e8
A
328ThreadPoolBase::~ThreadPoolBase() {
329 if (fThreads) {
330 for (int i=0; i<fNumThreads; i++) {
331 delete fThreads[i];
332 fThreads[i] = NULL;
333 }
334 delete[] fThreads;
335 fThreads = NULL;
729e4ab9 336 }
2ca993e8
A
337}
338
339
729e4ab9 340