aboutsummaryrefslogtreecommitdiffstats
path: root/vespalib
diff options
context:
space:
mode:
authorHåvard Pettersen <havardpe@oath.com>2022-01-10 11:02:42 +0000
committerHåvard Pettersen <havardpe@oath.com>2022-01-10 11:02:42 +0000
commit8c4b988a9eaebf9a7af83f1de0d15a4e6f17374f (patch)
tree8b509ff6ce784d4af76b786cf36e62a7b3bf6239 /vespalib
parent9af6e27766b372bcf51525b41e663accc9444afd (diff)
dummy fall-back for non-linux platforms
Diffstat (limited to 'vespalib')
-rw-r--r--vespalib/src/tests/cpu_usage/cpu_usage_test.cpp27
-rw-r--r--vespalib/src/vespa/vespalib/util/cpu_usage.cpp21
-rw-r--r--vespalib/src/vespa/vespalib/util/cpu_usage.h20
3 files changed, 61 insertions, 7 deletions
diff --git a/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp b/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp
index c8835d82cd8..d003689b864 100644
--- a/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp
+++ b/vespalib/src/tests/cpu_usage/cpu_usage_test.cpp
@@ -12,6 +12,7 @@ bool verbose = false;
size_t loop_cnt = 10;
double budget = 0.25;
+using DummySampler = vespalib::cpu_usage::DummyThreadSampler;
using Sampler = vespalib::cpu_usage::ThreadSampler;
//-----------------------------------------------------------------------------
@@ -29,10 +30,11 @@ void be_busy(duration d) {
}
}
-std::vector<duration> sample(const std::vector<Sampler*> &list) {
+template <typename LIST>
+std::vector<duration> sample(const LIST &list) {
std::vector<duration> result;
result.reserve(list.size());
- for (Sampler *sampler: list) {
+ for (auto *sampler: list) {
result.push_back(sampler->sample());
}
return result;
@@ -40,15 +42,16 @@ std::vector<duration> sample(const std::vector<Sampler*> &list) {
//-----------------------------------------------------------------------------
-TEST_MT_F("require that external thread-based CPU usage sampling works", 5, std::vector<Sampler*>(4, nullptr)) {
+template <typename SAMPLER>
+void verify_sampling(size_t thread_id, size_t num_threads, std::vector<SAMPLER*> &samplers) {
if (thread_id == 0) {
TEST_BARRIER(); // #1
auto t0 = steady_clock::now();
- std::vector<duration> pre_usage = sample(f1);
+ std::vector<duration> pre_usage = sample(samplers);
TEST_BARRIER(); // #2
TEST_BARRIER(); // #3
auto t1 = steady_clock::now();
- std::vector<duration> post_usage = sample(f1);
+ std::vector<duration> post_usage = sample(samplers);
TEST_BARRIER(); // #4
double wall = to_s(t1 - t0);
std::vector<double> load(4, 0.0);
@@ -58,9 +61,11 @@ TEST_MT_F("require that external thread-based CPU usage sampling works", 5, std:
EXPECT_GREATER(load[3], load[0]);
fprintf(stderr, "loads: { %.2f, %.2f, %.2f, %.2f }\n", load[0], load[1], load[2], load[3]);
} else {
+ SAMPLER sampler;
int idx = (thread_id - 1);
- Sampler sampler;
- f1[idx] = &sampler;
+ double target_load = double(thread_id - 1) / (num_threads - 2);
+ sampler.expected_load(target_load);
+ samplers[idx] = &sampler;
TEST_BARRIER(); // #1
TEST_BARRIER(); // #2
for (size_t i = 0; i < loop_cnt; ++i) {
@@ -73,6 +78,14 @@ TEST_MT_F("require that external thread-based CPU usage sampling works", 5, std:
//-----------------------------------------------------------------------------
+TEST_MT_F("require that dummy thread-based CPU usage sampling with known expected load works", 5, std::vector<DummySampler*>(4, nullptr)) {
+ TEST_DO(verify_sampling(thread_id, num_threads, f1));
+}
+
+TEST_MT_F("require that external thread-based CPU usage sampling works", 5, std::vector<Sampler*>(4, nullptr)) {
+ TEST_DO(verify_sampling(thread_id, num_threads, f1));
+}
+
TEST("measure thread CPU clock overhead") {
Sampler sampler;
duration d;
diff --git a/vespalib/src/vespa/vespalib/util/cpu_usage.cpp b/vespalib/src/vespa/vespalib/util/cpu_usage.cpp
index b5bd3ed76ac..1c126cb7884 100644
--- a/vespalib/src/vespa/vespalib/util/cpu_usage.cpp
+++ b/vespalib/src/vespa/vespalib/util/cpu_usage.cpp
@@ -7,6 +7,25 @@ namespace vespalib {
namespace cpu_usage {
+DummyThreadSampler::DummyThreadSampler()
+ : _start(steady_clock::now()),
+ _load(0.16)
+{
+}
+
+void
+DummyThreadSampler::expected_load(double load) {
+ _load = load;
+}
+
+duration
+DummyThreadSampler::sample() const
+{
+ return from_s(to_s(steady_clock::now() - _start) * _load);
+}
+
+#ifdef __linux__
+
ThreadSampler::ThreadSampler()
: _my_clock()
{
@@ -21,6 +40,8 @@ ThreadSampler::sample() const
return from_timespec(ts);
}
+#endif
+
} // cpu_usage
} // namespace
diff --git a/vespalib/src/vespa/vespalib/util/cpu_usage.h b/vespalib/src/vespa/vespalib/util/cpu_usage.h
index 452e96ba0ff..03a438ef6aa 100644
--- a/vespalib/src/vespa/vespalib/util/cpu_usage.h
+++ b/vespalib/src/vespa/vespalib/util/cpu_usage.h
@@ -7,6 +7,19 @@ namespace vespalib {
namespace cpu_usage {
+// do not use this directly (use ThreadSampler)
+class DummyThreadSampler {
+private:
+ steady_time _start;
+ double _load;
+public:
+ DummyThreadSampler();
+ void expected_load(double load);
+ duration sample() const;
+};
+
+#ifdef __linux__
+
/**
* Samples the total CPU usage of the thread that created it. Note
* that this must not be used after thread termination. Enables
@@ -19,9 +32,16 @@ private:
clockid_t _my_clock;
public:
ThreadSampler();
+ constexpr void expected_load(double) noexcept {}
duration sample() const;
};
+#else
+
+using ThreadSampler = DummyThreadSampler;
+
+#endif
+
} // cpu_usage
} // namespace