forked from npshub/mantid
-
Notifications
You must be signed in to change notification settings - Fork 0
/
ThreadSchedulerTest.h
112 lines (89 loc) · 3.68 KB
/
ThreadSchedulerTest.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include "MantidKernel/System.h"
#include "MantidKernel/Timer.h"
#include <cxxtest/TestSuite.h>
#include "MantidKernel/Task.h"
#include "MantidKernel/ThreadScheduler.h"
using namespace Mantid::Kernel;
int ThreadSchedulerTest_numDestructed;
class ThreadSchedulerTest : public CxxTest::TestSuite {
public:
class TaskDoNothing : public Task {
public:
TaskDoNothing() : Task() {}
TaskDoNothing(double cost) : Task() { m_cost = cost; }
~TaskDoNothing() override {
// To keep track of proper deleting of Task pointers
ThreadSchedulerTest_numDestructed++;
}
void run() override {}
};
void do_basic_test(std::unique_ptr<ThreadScheduler> sc) {
ThreadSchedulerTest_numDestructed = 0;
TS_ASSERT(!sc->getAborted());
TS_ASSERT_EQUALS(std::string(sc->getAbortException().what()), "");
TS_ASSERT_EQUALS(sc->size(), 0);
sc->push(std::make_shared<TaskDoNothing>());
TS_ASSERT_EQUALS(sc->size(), 1);
sc->push(std::make_shared<TaskDoNothing>());
TS_ASSERT_EQUALS(sc->size(), 2);
// Clear empties the queue
ThreadSchedulerTest_numDestructed = 0;
sc->clear();
TS_ASSERT_EQUALS(sc->size(), 0);
// And deletes the tasks properly
TS_ASSERT_EQUALS(ThreadSchedulerTest_numDestructed, 2);
}
void test_basic_ThreadSchedulerFIFO() { do_basic_test(std::make_unique<ThreadSchedulerFIFO>()); }
void test_basic_ThreadSchedulerLIFO() { do_basic_test(std::make_unique<ThreadSchedulerLIFO>()); }
void test_basic_ThreadSchedulerLargestCost() { do_basic_test(std::make_unique<ThreadSchedulerLargestCost>()); }
//==================================================================================================
void do_test(ThreadScheduler *sc, double *costs, size_t *poppedIndices) {
ThreadSchedulerTest_numDestructed = 0;
// Create and push them in order
TaskDoNothing *tasks[4];
for (size_t i = 0; i < 4; i++) {
auto temp = std::make_shared<TaskDoNothing>(costs[i]);
sc->push(temp);
tasks[i] = temp.get();
}
std::vector<std::shared_ptr<TaskDoNothing>> task(4, nullptr);
// Pop them, and check that we get them in the order we expected
for (size_t i = 0; i < 4; i++) {
task[i] = std::dynamic_pointer_cast<TaskDoNothing>(sc->pop(0));
size_t index = 0;
for (index = 0; index < 4; index++)
if (task[i]->cost() == tasks[index]->cost())
break;
TS_ASSERT_EQUALS(index, poppedIndices[i]);
}
// Nothing is left
TS_ASSERT_EQUALS(sc->size(), 0);
// And ThreadScheduler does not delete popped tasks in this way
TS_ASSERT_EQUALS(ThreadSchedulerTest_numDestructed, 0);
}
void test_ThreadSchedulerFIFO() {
std::unique_ptr<ThreadScheduler> sc = std::make_unique<ThreadSchedulerFIFO>();
double costs[4] = {0, 1, 2, 3};
size_t poppedIndices[4] = {0, 1, 2, 3};
do_test(sc.get(), costs, poppedIndices);
}
void test_ThreadSchedulerLIFO() {
std::unique_ptr<ThreadScheduler> sc = std::make_unique<ThreadSchedulerLIFO>();
double costs[4] = {0, 1, 2, 3};
size_t poppedIndices[4] = {3, 2, 1, 0};
do_test(sc.get(), costs, poppedIndices);
}
void test_ThreadSchedulerLargestCost() {
std::unique_ptr<ThreadScheduler> sc = std::make_unique<ThreadSchedulerLargestCost>();
double costs[4] = {1, 5, 2, -3};
size_t poppedIndices[4] = {1, 2, 0, 3};
do_test(sc.get(), costs, poppedIndices);
}
};