summaryrefslogtreecommitdiffstats
path: root/src/seastar/tests/unit/thread_context_switch_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'src/seastar/tests/unit/thread_context_switch_test.cc')
-rw-r--r--src/seastar/tests/unit/thread_context_switch_test.cc95
1 files changed, 95 insertions, 0 deletions
diff --git a/src/seastar/tests/unit/thread_context_switch_test.cc b/src/seastar/tests/unit/thread_context_switch_test.cc
new file mode 100644
index 00000000..c83b95d1
--- /dev/null
+++ b/src/seastar/tests/unit/thread_context_switch_test.cc
@@ -0,0 +1,95 @@
+/*
+ * This file is open source software, licensed to you under the terms
+ * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
+ * distributed with this work for additional information regarding copyright
+ * ownership. You may not use this file except in compliance with the License.
+ *
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Copyright (C) 2015 Cloudius Systems, Ltd.
+ */
+
+#include <seastar/core/thread.hh>
+#include <seastar/core/semaphore.hh>
+#include <seastar/core/app-template.hh>
+#include <seastar/core/do_with.hh>
+#include <seastar/core/distributed.hh>
+#include <seastar/core/sleep.hh>
+
+using namespace seastar;
+using namespace std::chrono_literals;
+
+class context_switch_tester {
+ uint64_t _switches{0};
+ semaphore _s1{0};
+ semaphore _s2{0};
+ bool _done1{false};
+ bool _done2{false};
+ thread _t1{[this] { main1(); }};
+ thread _t2{[this] { main2(); }};
+private:
+ void main1() {
+ while (!_done1) {
+ _s1.wait().get();
+ ++_switches;
+ _s2.signal();
+ }
+ _done2 = true;
+ }
+ void main2() {
+ while (!_done2) {
+ _s2.wait().get();
+ ++_switches;
+ _s1.signal();
+ }
+ }
+public:
+ void begin_measurement() {
+ _s1.signal();
+ }
+ future<uint64_t> measure() {
+ _done1 = true;
+ return _t1.join().then([this] {
+ return _t2.join();
+ }).then([this] {
+ return _switches;
+ });
+ }
+ future<> stop() {
+ return make_ready_future<>();
+ }
+};
+
+int main(int ac, char** av) {
+ static const auto test_time = 5s;
+ return app_template().run_deprecated(ac, av, [] {
+ return do_with(distributed<context_switch_tester>(), [] (distributed<context_switch_tester>& dcst) {
+ return dcst.start().then([&dcst] {
+ return dcst.invoke_on_all(&context_switch_tester::begin_measurement);
+ }).then([] {
+ return sleep(test_time);
+ }).then([&dcst] {
+ return dcst.map_reduce0(std::mem_fn(&context_switch_tester::measure), uint64_t(), std::plus<uint64_t>());
+ }).then([] (uint64_t switches) {
+ switches /= smp::count;
+ fmt::print("context switch time: {:5.1f} ns\n",
+ double(std::chrono::duration_cast<std::chrono::nanoseconds>(test_time).count()) / switches);
+ }).then([&dcst] {
+ return dcst.stop();
+ }).then([] {
+ engine_exit(0);
+ });
+ });
+ });
+}