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 successfull.
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) {
83         TestClass *test = dynamic_cast<TestClass *>(fIntlTest);
84         (test->*fRunFnPtr)(param);
85     }
86 };
87 #endif
88