| /** @file |
| |
| Micro Benchmark tool for Event System - requires Catch2 v2.9.0+ |
| |
| @section license License |
| |
| Licensed to the Apache Software Foundation (ASF) under one |
| or more contributor license agreements. See the NOTICE file |
| distributed with this work for additional information |
| regarding copyright ownership. The ASF licenses this file |
| to you under the Apache License, Version 2.0 (the |
| "License"); 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. |
| */ |
| |
| #define CATCH_CONFIG_ENABLE_BENCHMARKING |
| |
| #include <catch2/catch_test_macros.hpp> |
| #include <catch2/reporters/catch_reporter_event_listener.hpp> |
| #include <catch2/reporters/catch_reporter_registrars.hpp> |
| #include <catch2/interfaces/catch_interfaces_config.hpp> |
| #include <catch2/catch_session.hpp> |
| #include <catch2/benchmark/catch_benchmark.hpp> |
| |
| #include "iocore/eventsystem/Continuation.h" |
| #include "iocore/eventsystem/EventSystem.h" |
| #include "iocore/eventsystem/Lock.h" |
| |
| #include "iocore/utils/diags.i" |
| |
| #include "tscore/Layout.h" |
| #include "tscore/TSSystemState.h" |
| |
| namespace |
| { |
| // Args |
| int nevents = 1; |
| int nthreads = 1; |
| |
| std::atomic<int> counter = 0; |
| |
| struct Task : public Continuation { |
| Task() : Continuation(new_ProxyMutex()) { SET_HANDLER(&Task::event_handler); } |
| |
| int |
| event_handler(int /* event ATS_UNUSED */, Event * /* e ATS_UNUSED */) |
| { |
| ++counter; |
| |
| if (counter == nevents) { |
| TSSystemState::shut_down_event_system(); |
| } |
| |
| return 0; |
| } |
| }; |
| } // namespace |
| |
| TEST_CASE("event process benchmark", "") |
| { |
| char name[64]; |
| snprintf(name, sizeof(name), "nevents = %d nthreads = %d", nevents, nthreads); |
| |
| BENCHMARK(name) |
| { |
| REQUIRE(!TSSystemState::is_initializing()); |
| |
| for (int i = 0; i < nevents; ++i) { |
| Task *t = new Task(); |
| eventProcessor.schedule_in(t, 0); |
| } |
| |
| while (!TSSystemState::is_event_system_shut_down()) { |
| sleep(1); |
| } |
| }; |
| } |
| |
| struct EventProcessorListener : Catch::EventListenerBase { |
| using EventListenerBase::EventListenerBase; |
| |
| void |
| testRunStarting(Catch::TestRunInfo const & /* testRunInfo ATS_UNUSED */) override |
| { |
| Layout::create(); |
| init_diags("", nullptr); |
| RecProcessInit(); |
| |
| ink_event_system_init(EVENT_SYSTEM_MODULE_PUBLIC_VERSION); |
| eventProcessor.start(nthreads, 1048576); // Hardcoded stacksize at 1MB |
| |
| EThread *main_thread = new EThread; |
| main_thread->set_specific(); |
| |
| TSSystemState::initialization_done(); |
| } |
| }; |
| |
| CATCH_REGISTER_LISTENER(EventProcessorListener); |
| |
| int |
| main(int argc, char *argv[]) |
| { |
| Catch::Session session; |
| |
| using namespace Catch::Clara; |
| |
| auto cli = session.cli() | Opt(nevents, "n")["--ts-nevents"]("number of events (default: 1)\n") | |
| Opt(nthreads, "n")["--ts-nthreads"]("number of ethreads (default: 1)\n"); |
| |
| session.cli(cli); |
| |
| if (int res = session.applyCommandLine(argc, argv); res != 0) { |
| return res; |
| } |
| |
| return session.run(); |
| } |