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
20using Poco::Event;
21using Poco::ThreadPool;
22using Poco::RunnableAdapter;
23using Poco::Thread;
24
25
26ThreadPoolTest::ThreadPoolTest(const std::string& rName): CppUnit::TestCase(rName), _event(Event::EVENT_MANUALRESET)
27{
28}
29
30
31ThreadPoolTest::~ThreadPoolTest()
32{
33}
34
35
36void 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
138void ThreadPoolTest::testThreadPool()
139{
140 startThreadPoolTest(Poco::ThreadPool::TAP_DEFAULT);
141}
142
143
144void ThreadPoolTest::testThreadPoolUniformDistribution()
145{
146 startThreadPoolTest(Poco::ThreadPool::TAP_UNIFORM_DISTRIBUTION);
147}
148
149
150void ThreadPoolTest::testThreadPoolCustomDistribution()
151{
152 startThreadPoolTest(Poco::ThreadPool::TAP_CUSTOM);
153}
154
155
156void ThreadPoolTest::setUp()
157{
158 _event.reset();
159 _count = 0;
160}
161
162
163void ThreadPoolTest::tearDown()
164{
165}
166
167
168void 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
180CppUnit::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