12e5b6d6dSopenharmony_ci// © 2016 and later: Unicode, Inc. and others.
22e5b6d6dSopenharmony_ci// License & terms of use: http://www.unicode.org/copyright.html
32e5b6d6dSopenharmony_ci/********************************************************************
42e5b6d6dSopenharmony_ci * COPYRIGHT:
52e5b6d6dSopenharmony_ci * Copyright (c) 1999-2015, International Business Machines Corporation and
62e5b6d6dSopenharmony_ci * others. All Rights Reserved.
72e5b6d6dSopenharmony_ci ********************************************************************/
82e5b6d6dSopenharmony_ci
92e5b6d6dSopenharmony_ci
102e5b6d6dSopenharmony_ci#include "simplethread.h"
112e5b6d6dSopenharmony_ci
122e5b6d6dSopenharmony_ci#include <thread>
132e5b6d6dSopenharmony_ci#include "unicode/utypes.h"
142e5b6d6dSopenharmony_ci#include "intltest.h"
152e5b6d6dSopenharmony_ci
162e5b6d6dSopenharmony_ci
172e5b6d6dSopenharmony_ciSimpleThread::SimpleThread() {
182e5b6d6dSopenharmony_ci}
192e5b6d6dSopenharmony_ci
202e5b6d6dSopenharmony_ciSimpleThread::~SimpleThread() {
212e5b6d6dSopenharmony_ci    this->join();     // Avoid crashes if user neglected to join().
222e5b6d6dSopenharmony_ci}
232e5b6d6dSopenharmony_ci
242e5b6d6dSopenharmony_ciint SimpleThread::start() {
252e5b6d6dSopenharmony_ci    fThread = std::thread(&SimpleThread::run, this);
262e5b6d6dSopenharmony_ci    return fThread.joinable() ? 0 : 1;
272e5b6d6dSopenharmony_ci}
282e5b6d6dSopenharmony_ci
292e5b6d6dSopenharmony_civoid SimpleThread::join() {
302e5b6d6dSopenharmony_ci    if (fThread.joinable()) {
312e5b6d6dSopenharmony_ci        fThread.join();
322e5b6d6dSopenharmony_ci    }
332e5b6d6dSopenharmony_ci}
342e5b6d6dSopenharmony_ci
352e5b6d6dSopenharmony_ci
362e5b6d6dSopenharmony_ci
372e5b6d6dSopenharmony_ciclass ThreadPoolThread: public SimpleThread {
382e5b6d6dSopenharmony_ci  public:
392e5b6d6dSopenharmony_ci    ThreadPoolThread(ThreadPoolBase *pool, int32_t threadNum) : fPool(pool), fNum(threadNum) {}
402e5b6d6dSopenharmony_ci    virtual void run() override { fPool->callFn(fNum); }
412e5b6d6dSopenharmony_ci    ThreadPoolBase *fPool;
422e5b6d6dSopenharmony_ci    int32_t         fNum;
432e5b6d6dSopenharmony_ci};
442e5b6d6dSopenharmony_ci
452e5b6d6dSopenharmony_ci
462e5b6d6dSopenharmony_ciThreadPoolBase::ThreadPoolBase(IntlTest *test, int32_t howMany) :
472e5b6d6dSopenharmony_ci        fIntlTest(test), fNumThreads(howMany), fThreads(NULL) {
482e5b6d6dSopenharmony_ci    fThreads = new SimpleThread *[fNumThreads];
492e5b6d6dSopenharmony_ci    if (fThreads == NULL) {
502e5b6d6dSopenharmony_ci        fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
512e5b6d6dSopenharmony_ci        return;
522e5b6d6dSopenharmony_ci    }
532e5b6d6dSopenharmony_ci
542e5b6d6dSopenharmony_ci    for (int i=0; i<fNumThreads; i++) {
552e5b6d6dSopenharmony_ci        fThreads[i] = new ThreadPoolThread(this, i);
562e5b6d6dSopenharmony_ci        if (fThreads[i] == NULL) {
572e5b6d6dSopenharmony_ci            fIntlTest->errln("%s:%d memory allocation failure.", __FILE__, __LINE__);
582e5b6d6dSopenharmony_ci        }
592e5b6d6dSopenharmony_ci    }
602e5b6d6dSopenharmony_ci}
612e5b6d6dSopenharmony_ci
622e5b6d6dSopenharmony_civoid ThreadPoolBase::start() {
632e5b6d6dSopenharmony_ci    for (int i=0; i<fNumThreads; i++) {
642e5b6d6dSopenharmony_ci        if (fThreads && fThreads[i]) {
652e5b6d6dSopenharmony_ci            fThreads[i]->start();
662e5b6d6dSopenharmony_ci        }
672e5b6d6dSopenharmony_ci    }
682e5b6d6dSopenharmony_ci}
692e5b6d6dSopenharmony_ci
702e5b6d6dSopenharmony_civoid ThreadPoolBase::join() {
712e5b6d6dSopenharmony_ci    for (int i=0; i<fNumThreads; i++) {
722e5b6d6dSopenharmony_ci        if (fThreads && fThreads[i]) {
732e5b6d6dSopenharmony_ci            fThreads[i]->join();
742e5b6d6dSopenharmony_ci        }
752e5b6d6dSopenharmony_ci    }
762e5b6d6dSopenharmony_ci}
772e5b6d6dSopenharmony_ci
782e5b6d6dSopenharmony_ciThreadPoolBase::~ThreadPoolBase() {
792e5b6d6dSopenharmony_ci    if (fThreads) {
802e5b6d6dSopenharmony_ci        for (int i=0; i<fNumThreads; i++) {
812e5b6d6dSopenharmony_ci            delete fThreads[i];
822e5b6d6dSopenharmony_ci            fThreads[i] = NULL;
832e5b6d6dSopenharmony_ci        }
842e5b6d6dSopenharmony_ci        delete[] fThreads;
852e5b6d6dSopenharmony_ci        fThreads = NULL;
862e5b6d6dSopenharmony_ci    }
872e5b6d6dSopenharmony_ci}
88