Skip to content

Commit a45fd64

Browse files
author
Vlada Kanivets
committed
add tests for ThreadPool
1 parent bf56e1b commit a45fd64

File tree

4 files changed

+159
-2
lines changed

4 files changed

+159
-2
lines changed

include/kf/ThreadPool.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ namespace kf
1111
{
1212
}
1313

14-
ThreadPool(ThreadPool&&) = default;
14+
ThreadPool(ThreadPool&& other) = default;
1515

1616
~ThreadPool()
1717
{
@@ -53,7 +53,7 @@ namespace kf
5353
}
5454

5555
private:
56-
Thread m_threads[kMaxCount];
56+
Thread m_threads[kMaxCount]{};
5757
int m_count;
5858
};
5959
}

test/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ wdk_add_driver(kf-test WINVER NTDDI_WIN10 STL
5959
AutoSpinLockTest.cpp
6060
EResourceSharedLockTest.cpp
6161
RecursiveAutoSpinLockTest.cpp
62+
ThreadPoolTest.cpp
6263
)
6364

6465
target_link_libraries(kf-test kf::kf kmtest::kmtest)

test/ThreadPoolTest.cpp

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
#include "pch.h"
2+
#include <kf/ThreadPool.h>
3+
4+
SCENARIO("kf::ThreadPool")
5+
{
6+
struct TestObject
7+
{
8+
NTSTATUS run()
9+
{
10+
InterlockedIncrement(&value);
11+
return STATUS_SUCCESS;
12+
}
13+
14+
LONG value = 0;
15+
};
16+
17+
constexpr auto fn = [](void* context) {
18+
LARGE_INTEGER interval;
19+
interval.QuadPart = -10'000;
20+
KeDelayExecutionThread(KernelMode, FALSE, &interval);
21+
auto p = static_cast<LONG*>(context);
22+
InterlockedIncrement(p);
23+
};
24+
25+
GIVEN("A ThreadPool with count <= kMaxCount")
26+
{
27+
kf::ThreadPool pool(4);
28+
29+
WHEN("Starting threads with a lambda")
30+
{
31+
LONG value = 0;
32+
NTSTATUS status = pool.start(fn, &value);
33+
34+
THEN("Status is successful")
35+
{
36+
REQUIRE(NT_SUCCESS(status));
37+
}
38+
39+
pool.join();
40+
41+
THEN("All threads incremented the value")
42+
{
43+
REQUIRE(value == 4);
44+
}
45+
}
46+
47+
WHEN("Starting threads with a member function")
48+
{
49+
TestObject obj;
50+
NTSTATUS status = pool.start<&TestObject::run>(&obj);
51+
52+
THEN("Status is successful")
53+
{
54+
REQUIRE(NT_SUCCESS(status));
55+
}
56+
57+
pool.join();
58+
59+
THEN("All threads executed the member routine")
60+
{
61+
REQUIRE(obj.value == 4);
62+
}
63+
}
64+
}
65+
66+
GIVEN("A ThreadPool with count > kMaxCount")
67+
{
68+
kf::ThreadPool pool(100);
69+
LONG value = 0;
70+
71+
WHEN("Starting threads")
72+
{
73+
REQUIRE_NT_SUCCESS(pool.start(fn, &value));
74+
75+
pool.join();
76+
77+
THEN("ThreadPool started up to kMaxCount threads")
78+
{
79+
REQUIRE(value == 64);
80+
}
81+
}
82+
}
83+
84+
GIVEN("A ThreadPool with 4 threads")
85+
{
86+
LONG value = 0;
87+
88+
WHEN("ThreadPool with started threads goes out of scope")
89+
{
90+
{
91+
kf::ThreadPool pool(4);
92+
REQUIRE_NT_SUCCESS(pool.start(fn, &value));
93+
}
94+
95+
THEN("All threads are complete successfully")
96+
{
97+
REQUIRE(value == 4);
98+
}
99+
}
100+
}
101+
102+
GIVEN("ThreadPool with 4 started threads")
103+
{
104+
LONG value = 0;
105+
kf::ThreadPool pool1(4);
106+
107+
REQUIRE_NT_SUCCESS(pool1.start(fn, &value));
108+
109+
WHEN("ThreadPool moved into another pool")
110+
{
111+
kf::ThreadPool pool2(std::move(pool1));
112+
pool2.join();
113+
114+
THEN("Threads still run and complete successfully")
115+
{
116+
REQUIRE(value == 4);
117+
}
118+
}
119+
}
120+
}

test/pch.h

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,42 @@ extern "C" inline int _CrtDbgReport(
2121
KeBugCheckEx(KERNEL_SECURITY_CHECK_FAILURE, 0, 0, 0, 0);
2222
}
2323

24+
inline void __ehvec_dtor(
25+
void* ptr,
26+
unsigned __int64 size,
27+
unsigned __int64 count,
28+
void(__cdecl* dtor)(void*)
29+
)
30+
{
31+
UNREFERENCED_PARAMETER(ptr);
32+
UNREFERENCED_PARAMETER(size);
33+
UNREFERENCED_PARAMETER(count);
34+
UNREFERENCED_PARAMETER(dtor);
35+
}
36+
37+
inline void __cdecl __ehvec_copy_ctor(
38+
void* dst,
39+
void* src,
40+
unsigned __int64 size,
41+
unsigned __int64 count,
42+
void(__cdecl* copy_ctor)(void*, void*),
43+
void(__cdecl* dtor)(void*)
44+
)
45+
{
46+
UNREFERENCED_PARAMETER(dtor);
47+
48+
auto d = static_cast<unsigned char*>(dst);
49+
auto s = static_cast<unsigned char*>(src);
50+
51+
for (unsigned __int64 i = 0; i < count; ++i)
52+
{
53+
copy_ctor(d, s);
54+
d += size;
55+
s += size;
56+
}
57+
}
58+
59+
2460
namespace std
2561
{
2662
[[noreturn]] inline void __cdecl _Xinvalid_argument(_In_z_ const char* /*What*/)

0 commit comments

Comments
 (0)