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