| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include <stdio.h> |
| |
| #include "base/logging.h" |
| #include "base/strings/string_number_conversions.h" |
| #include "base/trace_event/trace_event.h" |
| #include "examples/echo/echo.mojom.h" |
| #include "mojo/application/application_runner_chromium.h" |
| #include "mojo/common/tracing_impl.h" |
| #include "mojo/public/c/system/main.h" |
| #include "mojo/public/cpp/application/application_delegate.h" |
| #include "mojo/public/cpp/application/application_impl.h" |
| #include "mojo/public/cpp/application/connect.h" |
| #include "mojo/public/cpp/utility/run_loop.h" |
| |
| namespace mojo { |
| namespace examples { |
| |
| static const base::TimeDelta kWarmupTime = |
| base::TimeDelta::FromMilliseconds(1000); |
| |
| static const base::TimeDelta kDelayTime = base::TimeDelta::FromMicroseconds(50); |
| |
| class EchoClientDelegate; |
| |
| class EchoResponse { |
| public: |
| EchoResponse(EchoClientDelegate* echo, int idx, bool traced) |
| : echoDelegate_(echo), idx_(idx), traced_(traced) {} |
| |
| void Run(const String& value) const; |
| |
| private: |
| EchoClientDelegate* echoDelegate_; |
| int idx_; |
| bool traced_; |
| }; |
| |
| class EchoClientDelegate : public ApplicationDelegate { |
| public: |
| EchoClientDelegate() |
| : warmup_(true), |
| num_clients_(1), |
| num_active_clients_(1), |
| use_dart_server_(false), |
| ending_(false), |
| benchmark_duration_(base::TimeDelta::FromSeconds(10)) {} |
| |
| void Initialize(ApplicationImpl* app) override { |
| tracing_.Initialize(app->shell(), &app->args()); |
| |
| ParseArguments(app); |
| |
| for (int i = 0; i < num_clients_; i++) { |
| EchoPtr echo; |
| if (use_dart_server_) { |
| ConnectToService(app->shell(), "mojo:dart_echo_server", |
| GetProxy(&echo)); |
| } else { |
| ConnectToService(app->shell(), "mojo:echo_server", GetProxy(&echo)); |
| } |
| echoClients_.push_back(echo.Pass()); |
| } |
| BeginEcho(0); |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&EchoClientDelegate::EndWarmup, base::Unretained(this)), |
| kWarmupTime); |
| } |
| |
| void BeginEcho(int idx) { |
| if (ending_) return; |
| if (idx == num_active_clients_) { |
| idx = 0; |
| } |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&EchoClientDelegate::Run, base::Unretained(this), idx), |
| kDelayTime); |
| base::MessageLoop::current()->PostDelayedTask( |
| FROM_HERE, |
| base::Bind(&EchoClientDelegate::EndRun, base::Unretained(this)), |
| benchmark_duration_); |
| } |
| |
| void EndEcho(int idx, bool traced) { |
| if (traced) { |
| TRACE_EVENT_ASYNC_END0("echo_benchmark", "ping", echoClients_[idx].get()); |
| } |
| } |
| |
| private: |
| void Run(int idx) { |
| if (ending_) return; |
| if (warmup_) { |
| echoClients_[idx]->EchoString("ping", EchoResponse(this, idx, false)); |
| } else { |
| TRACE_EVENT_ASYNC_BEGIN0("echo_benchmark", "ping", |
| echoClients_[idx].get()); |
| echoClients_[idx]->EchoString("ping", EchoResponse(this, idx, true)); |
| } |
| } |
| |
| bool GetBoolArgument(const std::string& argument, |
| const std::string& flag, |
| bool* value) { |
| size_t start_pos = argument.find(flag); |
| if (start_pos != std::string::npos) { |
| *value = true; |
| return true; |
| } |
| return false; |
| } |
| |
| bool GetIntegerArgument(const std::string& argument, |
| const std::string& flag, |
| int* value) { |
| size_t start_pos = argument.find(flag); |
| if (start_pos != std::string::npos) { |
| size_t equals_pos = argument.find("=", start_pos); |
| if (equals_pos != std::string::npos) { |
| base::StringToInt(argument.substr(equals_pos + 1), value); |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| void ParseArguments(ApplicationImpl* app) { |
| int benchmark_duration_seconds = 0; |
| for (size_t i = 0; i < app->args().size(); i++) { |
| const std::string& argument = app->args()[i]; |
| if (GetBoolArgument(argument, "--dart-server", &use_dart_server_)) { |
| continue; |
| } |
| if (GetIntegerArgument(argument, "--num-clients", &num_clients_)) { |
| continue; |
| } |
| if (GetIntegerArgument(argument, "--num-active-clients", |
| &num_active_clients_)) { |
| continue; |
| } |
| if (GetIntegerArgument(argument, "--benchmark-duration", |
| &benchmark_duration_seconds)) { |
| benchmark_duration_ = |
| base::TimeDelta::FromSeconds(benchmark_duration_seconds); |
| continue; |
| } |
| } |
| } |
| |
| void EndRun() { ending_ = true; } |
| |
| void EndWarmup() { warmup_ = false; } |
| |
| bool warmup_; |
| int num_clients_; |
| int num_active_clients_; |
| bool use_dart_server_; |
| bool ending_; |
| base::TimeDelta benchmark_duration_; |
| std::vector<EchoPtr> echoClients_; |
| mojo::TracingImpl tracing_; |
| }; |
| |
| void EchoResponse::Run(const String& value) const { |
| echoDelegate_->EndEcho(idx_, traced_); |
| echoDelegate_->BeginEcho(idx_ + 1); |
| } |
| |
| } // namespace examples |
| } // namespace mojo |
| |
| MojoResult MojoMain(MojoHandle application_request) { |
| mojo::ApplicationRunnerChromium runner( |
| new mojo::examples::EchoClientDelegate); |
| return runner.Run(application_request); |
| } |