1 // © 2016 and later: Unicode, Inc. and others. 2 // License & terms of use: http://www.unicode.org/copyright.html 3 /******************************************************************** 4 * COPYRIGHT: 5 * Copyright (c) 1997-2015, International Business Machines Corporation and 6 * others. All Rights Reserved. 7 ********************************************************************/ 8 9 #ifndef SIMPLETHREAD_H 10 #define SIMPLETHREAD_H 11 12 #include <thread> 13 #include "unicode/utypes.h" 14 15 /* 16 * Simple class for creating threads in ICU tests. 17 * Originally created to provide a portable abstraction over platform 18 * (POSIX or Win32) threading interfaces. 19 * 20 * New threaded tests should consider skipping this class and directly using C++ std library 21 * threading functions. SimpleThread is retained primarily to support existing use. 22 */ 23 class SimpleThread 24 { 25 public: 26 SimpleThread(); 27 virtual ~SimpleThread(); 28 int32_t start(); // start the thread. Return 0 if successful. 29 void join(); // A thread must be joined before deleting its SimpleThread. 30 31 virtual void run() = 0; // Override this to provide the code to run 32 // in the thread. 33 private: 34 std::thread fThread = {}; 35 }; 36 37 38 class IntlTest; 39 40 // ThreadPool - utililty class to simplify the spawning a group of threads by 41 // a multi-threaded test. 42 // 43 // Usage: from within an intltest test function, 44 // ThreadPool<TestClass> pool( 45 // this, // The current intltest test object, 46 // // of type "TestClass *" 47 // numberOfThreads, // How many threads to spawn. 48 // &TestClass::func); // The function to be run by each thread. 49 // // It takes one int32_t parameter which 50 // // is set to the thread number, 0 to numberOfThreads-1. 51 // 52 // pool.start(); // Start all threads running. 53 // pool.join(); // Wait until all threads have terminated. 54 55 class ThreadPoolBase { 56 public: 57 ThreadPoolBase(IntlTest *test, int32_t numThreads); 58 virtual ~ThreadPoolBase(); 59 60 void start(); 61 void join(); 62 63 protected: 64 virtual void callFn(int32_t param) = 0; 65 friend class ThreadPoolThread; 66 67 IntlTest *fIntlTest; 68 int32_t fNumThreads; 69 SimpleThread **fThreads; 70 }; 71 72 73 template<class TestClass> 74 class ThreadPool : public ThreadPoolBase { 75 private: 76 void (TestClass::*fRunFnPtr)(int32_t); 77 public: ThreadPool(TestClass * test,int howMany,void (TestClass::* runFnPtr)(int32_t threadNumber))78 ThreadPool(TestClass *test, int howMany, void (TestClass::*runFnPtr)(int32_t threadNumber)) : 79 ThreadPoolBase(test, howMany), fRunFnPtr(runFnPtr) {} ~ThreadPool()80 virtual ~ThreadPool() {} 81 private: callFn(int32_t param)82 virtual void callFn(int32_t param) override { 83 TestClass *test = dynamic_cast<TestClass *>(fIntlTest); 84 (test->*fRunFnPtr)(param); 85 } 86 }; 87 #endif 88