1 | // |
2 | // ThreadPoolTest.cpp |
3 | // |
4 | // Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH. |
5 | // and Contributors. |
6 | // |
7 | // SPDX-License-Identifier: BSL-1.0 |
8 | // |
9 | |
10 | |
11 | #include "ThreadPoolTest.h" |
12 | #include "Poco/CppUnit/TestCaller.h" |
13 | #include "Poco/CppUnit/TestSuite.h" |
14 | #include "Poco/ThreadPool.h" |
15 | #include "Poco/RunnableAdapter.h" |
16 | #include "Poco/Exception.h" |
17 | #include "Poco/Thread.h" |
18 | |
19 | |
20 | using Poco::Event; |
21 | using Poco::ThreadPool; |
22 | using Poco::RunnableAdapter; |
23 | using Poco::Thread; |
24 | |
25 | |
26 | ThreadPoolTest::ThreadPoolTest(const std::string& rName): CppUnit::TestCase(rName), _event(Event::EVENT_MANUALRESET) |
27 | { |
28 | } |
29 | |
30 | |
31 | ThreadPoolTest::~ThreadPoolTest() |
32 | { |
33 | } |
34 | |
35 | |
36 | void ThreadPoolTest::startThreadPoolTest(int affinityPolicy) |
37 | { |
38 | int cpu = -1; |
39 | if (affinityPolicy == static_cast<int>(ThreadPool::TAP_CUSTOM)) |
40 | { |
41 | cpu = 0; |
42 | } |
43 | |
44 | ThreadPool pool(2, 3, 3, POCO_THREAD_STACK_SIZE, static_cast<ThreadPool::ThreadAffinityPolicy>(affinityPolicy)); |
45 | pool.setStackSize(1); |
46 | |
47 | assertTrue (pool.allocated() == 2); |
48 | assertTrue (pool.used() == 0); |
49 | assertTrue (pool.capacity() == 3); |
50 | assertTrue (pool.available() == 3); |
51 | pool.addCapacity(1); |
52 | assertTrue (pool.allocated() == 2); |
53 | assertTrue (pool.used() == 0); |
54 | assertTrue (pool.capacity() == 4); |
55 | assertTrue (pool.available() == 4); |
56 | |
57 | RunnableAdapter<ThreadPoolTest> ra(*this, &ThreadPoolTest::count); |
58 | pool.start(ra, cpu); |
59 | assertTrue (pool.allocated() == 2); |
60 | assertTrue (pool.used() == 1); |
61 | assertTrue (pool.capacity() == 4); |
62 | assertTrue (pool.available() == 3); |
63 | |
64 | pool.start(ra, cpu); |
65 | assertTrue (pool.allocated() == 2); |
66 | assertTrue (pool.used() == 2); |
67 | assertTrue (pool.capacity() == 4); |
68 | assertTrue (pool.available() == 2); |
69 | |
70 | pool.start(ra, cpu); |
71 | assertTrue (pool.allocated() == 3); |
72 | assertTrue (pool.used() == 3); |
73 | assertTrue (pool.capacity() == 4); |
74 | assertTrue (pool.available() == 1); |
75 | |
76 | pool.start(ra, cpu); |
77 | assertTrue (pool.allocated() == 4); |
78 | assertTrue (pool.used() == 4); |
79 | assertTrue (pool.capacity() == 4); |
80 | assertTrue (pool.available() == 0); |
81 | |
82 | try |
83 | { |
84 | pool.start(ra, cpu); |
85 | failmsg("thread pool exhausted - must throw exception" ); |
86 | } |
87 | catch (Poco::NoThreadAvailableException&) |
88 | { |
89 | } |
90 | catch (...) |
91 | { |
92 | failmsg("wrong exception thrown" ); |
93 | } |
94 | |
95 | _event.set(); // go!!! |
96 | pool.joinAll(); |
97 | |
98 | assertTrue (_count == 40000); |
99 | |
100 | assertTrue (pool.allocated() == 4); |
101 | assertTrue (pool.used() == 0); |
102 | assertTrue (pool.capacity() == 4); |
103 | assertTrue (pool.available() == 4); |
104 | |
105 | Thread::sleep(4000); |
106 | |
107 | pool.collect(); |
108 | assertTrue (pool.allocated() == 2); |
109 | assertTrue (pool.used() == 0); |
110 | assertTrue (pool.capacity() == 4); |
111 | assertTrue (pool.available() == 4); |
112 | |
113 | _count = 0; |
114 | _event.reset(); |
115 | pool.start(ra, cpu); |
116 | assertTrue (pool.allocated() == 2); |
117 | assertTrue (pool.used() == 1); |
118 | assertTrue (pool.capacity() == 4); |
119 | assertTrue (pool.available() == 3); |
120 | |
121 | pool.start(ra, cpu); |
122 | assertTrue (pool.allocated() == 2); |
123 | assertTrue (pool.used() == 2); |
124 | assertTrue (pool.capacity() == 4); |
125 | assertTrue (pool.available() == 2); |
126 | _event.set(); // go!!! |
127 | pool.joinAll(); |
128 | |
129 | assertTrue (_count == 20000); |
130 | |
131 | assertTrue (pool.allocated() == 2); |
132 | assertTrue (pool.used() == 0); |
133 | assertTrue (pool.capacity() == 4); |
134 | assertTrue (pool.available() == 4); |
135 | } |
136 | |
137 | |
138 | void ThreadPoolTest::testThreadPool() |
139 | { |
140 | startThreadPoolTest(Poco::ThreadPool::TAP_DEFAULT); |
141 | } |
142 | |
143 | |
144 | void ThreadPoolTest::testThreadPoolUniformDistribution() |
145 | { |
146 | startThreadPoolTest(Poco::ThreadPool::TAP_UNIFORM_DISTRIBUTION); |
147 | } |
148 | |
149 | |
150 | void ThreadPoolTest::testThreadPoolCustomDistribution() |
151 | { |
152 | startThreadPoolTest(Poco::ThreadPool::TAP_CUSTOM); |
153 | } |
154 | |
155 | |
156 | void ThreadPoolTest::setUp() |
157 | { |
158 | _event.reset(); |
159 | _count = 0; |
160 | } |
161 | |
162 | |
163 | void ThreadPoolTest::tearDown() |
164 | { |
165 | } |
166 | |
167 | |
168 | void ThreadPoolTest::count() |
169 | { |
170 | _event.wait(); |
171 | for (int i = 0; i < 10000; ++i) |
172 | { |
173 | _mutex.lock(); |
174 | ++_count; |
175 | _mutex.unlock(); |
176 | } |
177 | } |
178 | |
179 | |
180 | CppUnit::Test* ThreadPoolTest::suite() |
181 | { |
182 | CppUnit::TestSuite* pSuite = new CppUnit::TestSuite("ThreadPoolTest" ); |
183 | |
184 | CppUnit_addTest(pSuite, ThreadPoolTest, testThreadPool); |
185 | CppUnit_addTest(pSuite, ThreadPoolTest, testThreadPoolUniformDistribution); |
186 | CppUnit_addTest(pSuite, ThreadPoolTest, testThreadPoolCustomDistribution); |
187 | |
188 | return pSuite; |
189 | } |
190 | |