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) 1999-2015, International Business Machines Corporation and
6 * others. All Rights Reserved.
7 ********************************************************************/
8
9
10#include "simplethread.h"
11
12#include <thread>
13#include "unicode/utypes.h"
14#include "intltest.h"
15
16
17SimpleThread::SimpleThread() {
18}
19
20SimpleThread::~SimpleThread() {
21    this->join();     // Avoid crashes if user neglected to join().
22}
23
24int SimpleThread::start() {
25    fThread = std::thread(&SimpleThread::run, this);
26    return fThread.joinable() ? 0 : 1;
27}
28
29void SimpleThread::join() {
30    if (fThread.joinable()) {
31        fThread.join();
32    }
33}
34
35
36
37class ThreadPoolThread: public SimpleThread {
38  public:
39    ThreadPoolThread(ThreadPoolBase *pool, int32_t threadNum) : fPool(pool), fNum(threadNum) {}
40    virtual void run() override { fPool->callFn(fNum); }
41    ThreadPoolBase *fPool;
42    int32_t         fNum;
43};
44
45
46ThreadPoolBase::ThreadPoolBase(IntlTest *test, int32_t howMany) :
47        fIntlTest(test), fNumThreads(howMany), fThreads(NULL) {
48    fThreads = new SimpleThread *[fNumThreads];
49    if (fThreads == NULL) {
50        fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
51        return;
52    }
53
54    for (int i=0; i<fNumThreads; i++) {
55        fThreads[i] = new ThreadPoolThread(this, i);
56        if (fThreads[i] == NULL) {
57            fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
58        }
59    }
60}
61
62void ThreadPoolBase::start() {
63    for (int i=0; i<fNumThreads; i++) {
64        if (fThreads && fThreads[i]) {
65            fThreads[i]->start();
66        }
67    }
68}
69
70void ThreadPoolBase::join() {
71    for (int i=0; i<fNumThreads; i++) {
72        if (fThreads && fThreads[i]) {
73            fThreads[i]->join();
74        }
75    }
76}
77
78ThreadPoolBase::~ThreadPoolBase() {
79    if (fThreads) {
80        for (int i=0; i<fNumThreads; i++) {
81            delete fThreads[i];
82            fThreads[i] = NULL;
83        }
84        delete[] fThreads;
85        fThreads = NULL;
86    }
87}
88