Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(31)

Side by Side Diff: source/test/intltest/simplethread.cpp

Issue 1621843002: ICU 56 update step 1 (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/icu.git@561
Patch Set: Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « source/test/intltest/simplethread.h ('k') | source/test/intltest/strtest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /******************************************************************** 1 /********************************************************************
2 * COPYRIGHT: 2 * COPYRIGHT:
3 * Copyright (c) 1999-2013, International Business Machines Corporation and 3 * Copyright (c) 1999-2015, International Business Machines Corporation and
4 * others. All Rights Reserved. 4 * others. All Rights Reserved.
5 ********************************************************************/ 5 ********************************************************************/
6 6
7 #if defined(hpux) 7 #if defined(hpux)
8 # ifndef _INCLUDE_POSIX_SOURCE 8 # ifndef _INCLUDE_POSIX_SOURCE
9 # define _INCLUDE_POSIX_SOURCE 9 # define _INCLUDE_POSIX_SOURCE
10 # endif 10 # endif
11 #endif 11 #endif
12 12
13 /* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */ 13 /* Define __EXTENSIONS__ for Solaris and old friends in strict mode. */
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
55 #endif 55 #endif
56 #ifndef _XPG4_2 56 #ifndef _XPG4_2
57 # define _XPG4_2 57 # define _XPG4_2
58 #endif 58 #endif
59 #include <unistd.h> 59 #include <unistd.h>
60 #endif 60 #endif
61 61
62 #if defined(POSIX) 62 #if defined(POSIX)
63 #define HAVE_IMP 63 #define HAVE_IMP
64 64
65 #if (ICU_USE_THREADS == 1)
66 #include <pthread.h> 65 #include <pthread.h>
67 #endif
68
69 #if defined(__hpux) && defined(HPUX_CMA)
70 # if defined(read) // read being defined as cma_read causes trouble with iostre am::read
71 # undef read
72 # endif
73 #endif
74 66
75 #if U_PLATFORM == U_PF_OS390 67 #if U_PLATFORM == U_PF_OS390
76 #include <sys/types.h> 68 #include <sys/types.h>
77 #endif 69 #endif
78 70
79 #if U_PLATFORM != U_PF_OS390 71 #if U_PLATFORM != U_PF_OS390
80 #include <signal.h> 72 #include <signal.h>
81 #endif 73 #endif
82 74
83 /* Define _XPG4_2 for Solaris and friends. */ 75 /* Define _XPG4_2 for Solaris and friends. */
(...skipping 13 matching lines...) Expand all
97 89
98 #include <unistd.h> 90 #include <unistd.h>
99 91
100 #endif 92 #endif
101 /* HPUX */ 93 /* HPUX */
102 #ifdef sleep 94 #ifdef sleep
103 #undef sleep 95 #undef sleep
104 #endif 96 #endif
105 97
106 98
107 #if (ICU_USE_THREADS==0)
108 SimpleThread::SimpleThread()
109 {}
110
111 SimpleThread::~SimpleThread()
112 {}
113
114 int32_t
115 SimpleThread::start()
116 { return -1; }
117
118 void
119 SimpleThread::run()
120 {}
121
122 void
123 SimpleThread::sleep(int32_t millis)
124 {}
125
126 UBool
127 SimpleThread::isRunning() {
128 return FALSE;
129 }
130 #else
131
132 #include "unicode/putil.h" 99 #include "unicode/putil.h"
133 100
134 /* for mthreadtest*/ 101 /* for mthreadtest*/
135 #include "unicode/numfmt.h" 102 #include "unicode/numfmt.h"
136 #include "unicode/choicfmt.h" 103 #include "unicode/choicfmt.h"
137 #include "unicode/msgfmt.h" 104 #include "unicode/msgfmt.h"
138 #include "unicode/locid.h" 105 #include "unicode/locid.h"
139 #include "unicode/ucol.h" 106 #include "unicode/ucol.h"
140 #include "unicode/calendar.h" 107 #include "unicode/calendar.h"
141 #include "ucaconf.h" 108 #include "ucaconf.h"
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
216 int err = errno; 183 int err = errno;
217 if (err == 0) { 184 if (err == 0) {
218 err = -1; 185 err = -1;
219 } 186 }
220 return err; 187 return err;
221 } 188 }
222 return 0; 189 return 0;
223 } 190 }
224 191
225 192
226 UBool SimpleThread::isRunning() { 193 void SimpleThread::join() {
227 //
228 // Test whether the thread associated with the SimpleThread object is
229 // still actually running.
230 //
231 // NOTE: on Win64 on Itanium processors, a crashes
232 // occur if the main thread of a process exits concurrently with some
233 // other thread(s) exiting. To avoid the possibility, we wait until the
234 // OS indicates that all threads have terminated, rather than waiting
235 // only until the end of the user's Run function has been reached.
236 //
237 // I don't know whether the crashes represent a Windows bug, or whether
238 // main() programs are supposed to have to wait for their threads.
239 //
240 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation ; 194 Win32ThreadImplementation *imp = (Win32ThreadImplementation*)fImplementation ;
241
242 bool success;
243 DWORD threadExitCode;
244
245 if (imp->fHandle == 0) { 195 if (imp->fHandle == 0) {
246 // No handle, thread must not be running. 196 // No handle, thread must not be running.
247 return FALSE; 197 return;
248 } 198 }
249 success = GetExitCodeThread(imp->fHandle, &threadExitCode) != 0; 199 WaitForSingleObject(imp->fHandle, INFINITE);
250 if (! success) {
251 // Can't get status, thread must not be running.
252 return FALSE;
253 }
254 return (threadExitCode == STILL_ACTIVE);
255 }
256
257
258 void SimpleThread::sleep(int32_t millis)
259 {
260 ::Sleep(millis);
261 }
262
263 //------------------------------------------------------------------------------ -----
264 //
265 // class SimpleThread NULL Implementation
266 //
267 //------------------------------------------------------------------------------ -----
268 #elif U_PLATFORM == U_PF_CLASSIC_MACOS
269
270 // since the Mac has no preemptive threading (at least on MacOS 8), only
271 // cooperative threading, threads are a no-op. We have no yield() calls
272 // anywhere in the ICU, so we are guaranteed to be thread-safe.
273
274 #define HAVE_IMP
275
276 SimpleThread::SimpleThread()
277 {}
278
279 SimpleThread::~SimpleThread()
280 {}
281
282 int32_t
283 SimpleThread::start()
284 { return 0; }
285
286 void
287 SimpleThread::run()
288 {}
289
290 void
291 SimpleThread::sleep(int32_t millis)
292 {}
293
294 UBool
295 SimpleThread::isRunning() {
296 return FALSE;
297 } 200 }
298 201
299 #endif 202 #endif
300 203
301 204
302 //------------------------------------------------------------------------------ ----- 205 //------------------------------------------------------------------------------ -----
303 // 206 //
304 // class SimpleThread POSIX implementation 207 // class SimpleThread POSIX implementation
305 // 208 //
306 // A note on the POSIX vs the Windows implementations of this class..
307 // On Windows, the main thread must verify that other threads have finish ed
308 // before exiting, or crashes occasionally occur. (Seen on Itanium Win64 only)
309 // The function SimpleThread::isRunning() is used for this purpose.
310 //
311 // On POSIX, there is NO reliable non-blocking mechanism to determine
312 // whether a thread has exited. pthread_kill(thread, 0) almost works,
313 // but the system can recycle thread ids immediately, so seeing that a
314 // thread exists with this call could mean that the original thread has
315 // finished and a new one started with the same ID. Useless.
316 //
317 // So we need to do the check with user code, by setting a flag just befo re
318 // the thread function returns. A technique that is guaranteed to fail
319 // on Windows, because it indicates that the thread is done before all
320 // system level cleanup has happened.
321 //
322 //------------------------------------------------------------------------------ ----- 209 //------------------------------------------------------------------------------ -----
323 #if defined(POSIX) 210 #if defined(POSIX)
324 #define HAVE_IMP 211 #define HAVE_IMP
325 212
326 struct PosixThreadImplementation 213 struct PosixThreadImplementation
327 { 214 {
328 pthread_t fThread; 215 pthread_t fThread;
329 UBool fRunning;
330 UBool fRan; // True if the thread was successfully start ed
331 }; 216 };
332 217
333 extern "C" void* SimpleThreadProc(void *arg) 218 extern "C" void* SimpleThreadProc(void *arg)
334 { 219 {
335 // This is the code that is run in the new separate thread. 220 // This is the code that is run in the new separate thread.
336 SimpleThread *This = (SimpleThread *)arg; 221 SimpleThread *This = (SimpleThread *)arg;
337 This->run(); // Run the user code. 222 This->run();
338
339 // The user function has returned. Set the flag indicating that this thread
340 // is done. Need a mutex for memory barrier purposes only, so that other th read
341 // will reliably see that the flag has changed.
342 PosixThreadImplementation *imp = (PosixThreadImplementation*)This->fImplemen tation;
343 umtx_lock(NULL);
344 imp->fRunning = FALSE;
345 umtx_unlock(NULL);
346 return 0; 223 return 0;
347 } 224 }
348 225
349 SimpleThread::SimpleThread() 226 SimpleThread::SimpleThread()
350 { 227 {
351 PosixThreadImplementation *imp = new PosixThreadImplementation; 228 PosixThreadImplementation *imp = new PosixThreadImplementation;
352 imp->fRunning = FALSE;
353 imp->fRan = FALSE;
354 fImplementation = imp; 229 fImplementation = imp;
355 } 230 }
356 231
357 SimpleThread::~SimpleThread() 232 SimpleThread::~SimpleThread()
358 { 233 {
359 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ; 234 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ;
360 if (imp->fRan) {
361 pthread_join(imp->fThread, NULL);
362 }
363 delete imp; 235 delete imp;
364 fImplementation = (void *)0xdeadbeef; 236 fImplementation = (void *)0xdeadbeef;
365 } 237 }
366 238
367 int32_t SimpleThread::start() 239 int32_t SimpleThread::start()
368 { 240 {
369 int32_t rc; 241 int32_t rc;
370 static pthread_attr_t attr; 242 static pthread_attr_t attr;
371 static UBool attrIsInitialized = FALSE; 243 static UBool attrIsInitialized = FALSE;
372 244
373 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ; 245 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ;
374 imp->fRunning = TRUE;
375 imp->fRan = TRUE;
376 246
377 #ifdef HPUX_CMA
378 if (attrIsInitialized == FALSE) {
379 rc = pthread_attr_create(&attr);
380 attrIsInitialized = TRUE;
381 }
382 rc = pthread_create(&(imp->fThread),attr,&SimpleThreadProc,(void*)this);
383 #else
384 if (attrIsInitialized == FALSE) { 247 if (attrIsInitialized == FALSE) {
385 rc = pthread_attr_init(&attr); 248 rc = pthread_attr_init(&attr);
386 #if U_PLATFORM == U_PF_OS390 249 #if U_PLATFORM == U_PF_OS390
387 { 250 {
388 int detachstate = 0; // jdc30: detach state of zero causes 251 int detachstate = 0; // jdc30: detach state of zero causes
389 //threads created with this attr to be in 252 //threads created with this attr to be in
390 //an undetached state. An undetached 253 //an undetached state. An undetached
391 //thread will keep its resources after 254 //thread will keep its resources after
392 //termination. 255 //termination.
393 pthread_attr_setdetachstate(&attr, &detachstate); 256 pthread_attr_setdetachstate(&attr, &detachstate);
394 } 257 }
395 #else 258 #else
396 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); 259 // pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
397 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); 260 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
398 #endif 261 #endif
399 attrIsInitialized = TRUE; 262 attrIsInitialized = TRUE;
400 } 263 }
401 rc = pthread_create(&(imp->fThread),&attr,&SimpleThreadProc,(void*)this); 264 rc = pthread_create(&(imp->fThread), &attr, &SimpleThreadProc, (void*)this);
402 #endif
403 265
404 if (rc != 0) { 266 if (rc != 0) {
405 // some kind of error occured, the thread did not start. 267 // some kind of error occured, the thread did not start.
406 imp->fRan = FALSE;
407 imp->fRunning = FALSE;
408 } 268 }
409 269
410 return rc; 270 return rc;
411 } 271 }
412 272
413 273 void SimpleThread::join() {
414 UBool
415 SimpleThread::isRunning() {
416 // Note: Mutex functions are used here not for synchronization,
417 // but to force memory barriors to exist, to ensure that one thread
418 // can see changes made by another when running on processors
419 // with memory models having weak coherency.
420 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ; 274 PosixThreadImplementation *imp = (PosixThreadImplementation*)fImplementation ;
421 umtx_lock(NULL); 275 pthread_join(imp->fThread, NULL);
422 UBool retVal = imp->fRunning;
423 umtx_unlock(NULL);
424 return retVal;
425 }
426
427
428 void SimpleThread::sleep(int32_t millis)
429 {
430 #if U_PLATFORM == U_PF_SOLARIS
431 sigignore(SIGALRM);
432 #endif
433
434 #ifdef HPUX_CMA
435 cma_sleep(millis/100);
436 #elif U_PLATFORM == U_PF_HPUX || U_PLATFORM == U_PF_OS390
437 millis *= 1000;
438 while(millis >= 1000000) {
439 usleep(999999);
440 millis -= 1000000;
441 }
442 if(millis > 0) {
443 usleep(millis);
444 }
445 #else
446 usleep(millis * 1000);
447 #endif
448 } 276 }
449 277
450 #endif 278 #endif
451 // end POSIX 279 // end POSIX
452 280
453 281
454 #ifndef HAVE_IMP 282 #ifndef HAVE_IMP
455 #error No implementation for threads! Cannot test. 283 #error No implementation for threads! Cannot test.
456 0 = 216; //die
457 #endif 284 #endif
458
459 //------------------------------------------------------------------------------ -------------
460 //
461 // class ThreadWithStatus - a thread that we can check the status and error cond ition of
462 //
463 //------------------------------------------------------------------------------ -------------
464 class ThreadWithStatus : public SimpleThread
465 {
466 public:
467 UBool getError() { return (fErrors > 0); }
468 UBool getError(UnicodeString& fillinError) { fillinError = fErrorString; re turn (fErrors > 0); }
469 virtual ~ThreadWithStatus(){}
470 protected:
471 ThreadWithStatus() : fErrors(0) {}
472 void error(const UnicodeString &error) {
473 fErrors++; fErrorString = error;
474 SimpleThread::errorFunc();
475 }
476 void error() { error("An error occured."); }
477 private:
478 int32_t fErrors;
479 UnicodeString fErrorString;
480 };
481
482 #endif // ICU_USE_THREADS
OLDNEW
« no previous file with comments | « source/test/intltest/simplethread.h ('k') | source/test/intltest/strtest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698