1 /********************************************************************
3 * Copyright (c) 1999-2015, International Business Machines Corporation and
4 * others. All Rights Reserved.
5 ********************************************************************/
8 # ifndef _INCLUDE_POSIX_SOURCE
9 # define _INCLUDE_POSIX_SOURCE
13 /* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */
14 #ifndef __EXTENSIONS__
15 #define __EXTENSIONS__
18 // Defines _XOPEN_SOURCE for access to POSIX functions.
19 // Must be before any other #includes.
20 #include "uposixdefs.h"
22 #include "simplethread.h"
24 #include "unicode/utypes.h"
25 #include "unicode/ustring.h"
30 #include "unicode/resbund.h"
31 #include "unicode/udata.h"
32 #include "unicode/uloc.h"
33 #include "unicode/locid.h"
39 #include <ctype.h> // tolower, toupper
41 #if U_PLATFORM_USES_ONLY_WIN32_API
42 /* Prefer native Windows APIs even if POSIX is implemented (i.e., on Cygwin). */
44 #elif U_PLATFORM_IMPLEMENTS_POSIX
50 /* Needed by z/OS to get usleep */
51 #if U_PLATFORM == U_PF_OS390
67 #if U_PLATFORM == U_PF_OS390
68 #include <sys/types.h>
71 #if U_PLATFORM != U_PF_OS390
75 /* Define _XPG4_2 for Solaris and friends. */
80 /* Define __USE_XOPEN_EXTENDED for Linux and glibc. */
81 #ifndef __USE_XOPEN_EXTENDED
82 #define __USE_XOPEN_EXTENDED
85 /* Define _INCLUDE_XOPEN_SOURCE_EXTENDED for HP/UX (11?). */
86 #ifndef _INCLUDE_XOPEN_SOURCE_EXTENDED
87 #define _INCLUDE_XOPEN_SOURCE_EXTENDED
99 #include "unicode/putil.h"
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"
110 #if U_PLATFORM_USES_ONLY_WIN32_API
113 # define VC_EXTRALEAN
114 # define WIN32_LEAN_AND_MEAN
122 //-----------------------------------------------------------------------------------
124 // class SimpleThread Windows Implementation
126 //-----------------------------------------------------------------------------------
127 struct Win32ThreadImplementation
130 unsigned int fThreadID
;
134 extern "C" unsigned int __stdcall
SimpleThreadProc(void *arg
)
136 ((SimpleThread
*)arg
)->run();
140 SimpleThread::SimpleThread()
143 Win32ThreadImplementation
*imp
= new Win32ThreadImplementation
;
145 fImplementation
= imp
;
148 SimpleThread::~SimpleThread()
150 // Destructor. Because we start the thread running with _beginthreadex(),
151 // we own the Windows HANDLE for the thread and must
153 Win32ThreadImplementation
*imp
= (Win32ThreadImplementation
*)fImplementation
;
155 if (imp
->fHandle
!= 0) {
156 CloseHandle(imp
->fHandle
);
160 delete (Win32ThreadImplementation
*)fImplementation
;
163 int32_t SimpleThread::start()
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.
172 imp
->fHandle
= (HANDLE
) _beginthreadex(
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
181 if (imp
->fHandle
== 0) {
193 void SimpleThread::join() {
194 Win32ThreadImplementation
*imp
= (Win32ThreadImplementation
*)fImplementation
;
195 if (imp
->fHandle
== 0) {
196 // No handle, thread must not be running.
199 WaitForSingleObject(imp
->fHandle
, INFINITE
);
205 //-----------------------------------------------------------------------------------
207 // class SimpleThread POSIX implementation
209 //-----------------------------------------------------------------------------------
213 struct PosixThreadImplementation
218 extern "C" void* SimpleThreadProc(void *arg
)
220 // This is the code that is run in the new separate thread.
221 SimpleThread
*This
= (SimpleThread
*)arg
;
226 SimpleThread::SimpleThread()
228 PosixThreadImplementation
*imp
= new PosixThreadImplementation
;
229 fImplementation
= imp
;
232 SimpleThread::~SimpleThread()
234 PosixThreadImplementation
*imp
= (PosixThreadImplementation
*)fImplementation
;
236 fImplementation
= (void *)0xdeadbeef;
239 int32_t SimpleThread::start()
242 static pthread_attr_t attr
;
243 static UBool attrIsInitialized
= FALSE
;
245 PosixThreadImplementation
*imp
= (PosixThreadImplementation
*)fImplementation
;
247 if (attrIsInitialized
== FALSE
) {
248 rc
= pthread_attr_init(&attr
);
249 #if U_PLATFORM == U_PF_OS390
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
256 pthread_attr_setdetachstate(&attr
, &detachstate
);
259 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
260 pthread_attr_setdetachstate(&attr
, PTHREAD_CREATE_JOINABLE
);
262 attrIsInitialized
= TRUE
;
264 rc
= pthread_create(&(imp
->fThread
), &attr
, &SimpleThreadProc
, (void*)this);
267 // some kind of error occured, the thread did not start.
273 void SimpleThread::join() {
274 PosixThreadImplementation
*imp
= (PosixThreadImplementation
*)fImplementation
;
275 pthread_join(imp
->fThread
, NULL
);
283 #error No implementation for threads! Cannot test.
287 class ThreadPoolThread
: public SimpleThread
{
289 ThreadPoolThread(ThreadPoolBase
*pool
, int32_t threadNum
) : fPool(pool
), fNum(threadNum
) {};
290 virtual void run() {fPool
->callFn(fNum
); }
291 ThreadPoolBase
*fPool
;
296 ThreadPoolBase::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__
);
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__
);
312 void ThreadPoolBase::start() {
313 for (int i
=0; i
<fNumThreads
; i
++) {
314 if (fThreads
&& fThreads
[i
]) {
315 fThreads
[i
]->start();
320 void ThreadPoolBase::join() {
321 for (int i
=0; i
<fNumThreads
; i
++) {
322 if (fThreads
&& fThreads
[i
]) {
328 ThreadPoolBase::~ThreadPoolBase() {
330 for (int i
=0; i
<fNumThreads
; i
++) {