1 /*
2  *  Copyright (C) 2019 Savoir-faire Linux Inc.
3  *
4  *  Author: Adrien Béraud <adrien.beraud@savoirfairelinux.com>
5  *
6  *  This program is free software; you can redistribute it and/or modify
7  *  it under the terms of the GNU General Public License as published by
8  *  the Free Software Foundation; either version 3 of the License, or
9  *  (at your option) any later version.
10  *
11  *  This program is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  *  GNU General Public License for more details.
15  *
16  *  You should have received a copy of the GNU General Public License
17  *  along with this program. If not, see <https://www.gnu.org/licenses/>.
18  */
19 
20 #include "threadpooltester.h"
21 
22 #include "opendht/thread_pool.h"
23 #include <atomic>
24 
25 namespace test {
26 CPPUNIT_TEST_SUITE_REGISTRATION(ThreadPoolTester);
27 using clock = std::chrono::steady_clock;
28 
29 void
setUp()30 ThreadPoolTester::setUp() {
31 
32 }
33 
34 void
testThreadPool()35 ThreadPoolTester::testThreadPool() {
36     dht::ThreadPool pool(16);
37 
38     constexpr unsigned N = 64 * 1024;
39     std::atomic_uint count {0};
40     for (unsigned i=0; i<N; i++)
41         pool.run([&] {
42             count++;
43         });
44 
45     auto start = clock::now();
46     while (count.load() != N && clock::now() - start < std::chrono::seconds(10))
47         std::this_thread::sleep_for(std::chrono::milliseconds(10));
48 
49     pool.join();
50     CPPUNIT_ASSERT(count.load() == N);
51 }
52 
53 void
testExecutor()54 ThreadPoolTester::testExecutor()
55 {
56     dht::ThreadPool pool(8);
57     auto executor1 = std::make_shared<dht::Executor>(pool, 1);
58     auto executor4 = std::make_shared<dht::Executor>(pool, 4);
59     auto executor8 = std::make_shared<dht::Executor>(pool, 8);
60 
61     constexpr unsigned N = 64 * 1024;
62     std::atomic_uint count1 {0};
63     std::atomic_uint count4 {0};
64     std::atomic_uint count8 {0};
65     for (unsigned i=0; i<N; i++) {
66         executor1->run([&] { count1++; });
67         executor4->run([&] { count4++; });
68         executor8->run([&] { count8++; });
69     }
70 
71     auto start = clock::now();
72     while ((count1.load() != N ||
73             count4.load() != N ||
74             count8.load() != N) && clock::now() - start < std::chrono::seconds(20))
75     {
76         std::this_thread::sleep_for(std::chrono::milliseconds(10));
77     }
78     executor1.reset();
79     executor4.reset();
80     executor8.reset();
81     CPPUNIT_ASSERT_EQUAL(N, count1.load());
82     CPPUNIT_ASSERT_EQUAL(N, count4.load());
83     CPPUNIT_ASSERT_EQUAL(N, count8.load());
84 }
85 
86 void
tearDown()87 ThreadPoolTester::tearDown() {
88 }
89 
90 }  // namespace test
91