Movatterモバイル変換


[0]ホーム

URL:


Google Git
Sign in
chromium /chromium /src /refs/heads/main /. /ipc /ipc_cpu_perftest.cc
blob: e6c8cf57de3192edb611f01c7f057dc06caee8cb [file] [log] [blame] [edit]
// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include<memory>
#include<string_view>
#include<tuple>
#include"base/check_op.h"
#include"base/functional/bind.h"
#include"base/memory/raw_ptr.h"
#include"base/process/process_metrics.h"
#include"base/run_loop.h"
#include"base/strings/stringprintf.h"
#include"base/synchronization/waitable_event.h"
#include"base/task/single_thread_task_runner.h"
#include"base/test/perf_log.h"
#include"base/test/task_environment.h"
#include"base/timer/timer.h"
#include"base/types/expected.h"
#include"ipc/ipc_channel_proxy.h"
#include"ipc/ipc_perftest_messages.h"
#include"ipc/ipc_perftest_util.h"
#include"ipc/ipc_sync_channel.h"
#include"ipc/ipc_test.test-mojom.h"
#include"ipc/ipc_test_base.h"
#include"mojo/core/test/mojo_test_base.h"
#include"mojo/core/test/multiprocess_test_helper.h"
#include"mojo/public/cpp/bindings/pending_remote.h"
#include"mojo/public/cpp/bindings/remote.h"
#include"mojo/public/cpp/system/message_pipe.h"
namespace IPC{
namespace{
structTestParams{
TestParams()=default;
TestParams(size_t in_message_size,
size_t in_frames_per_second,
size_t in_messages_per_frame,
size_t in_duration_in_seconds)
: message_size(in_message_size),
frames_per_second(in_frames_per_second),
messages_per_frame(in_messages_per_frame),
duration_in_seconds(in_duration_in_seconds){}
size_t message_size;
size_t frames_per_second;
size_t messages_per_frame;
size_t duration_in_seconds;
};
std::vector<TestParams>GetDefaultTestParams(){
std::vector<TestParams>list;
list.push_back({144,20,10,10});
list.push_back({144,60,10,10});
returnlist;
}
std::stringGetLogTitle(const std::string& label,constTestParams& params){
return base::StringPrintf(
"%s_MsgSize_%zu_FrmPerSec_%zu_MsgPerFrm_%zu", label.c_str(),
params.message_size, params.frames_per_second, params.messages_per_frame);
}
base::TimeDeltaGetFrameTime(size_t frames_per_second){
return base::Seconds(1.0/ frames_per_second);
}
classPerfCpuLogger{
public:
explicitPerfCpuLogger(std::string_view test_name)
: test_name_(test_name),
process_metrics_(base::ProcessMetrics::CreateCurrentProcessMetrics()){
// Query the CPU usage once to start the recording interval.
constdouble inital_cpu_usage=
process_metrics_->GetPlatformIndependentCPUUsage().value_or(-1.0);
// This should have been the first call so the reported cpu usage should be
// exactly zero.
DCHECK_EQ(inital_cpu_usage,0.0);
}
PerfCpuLogger(constPerfCpuLogger&)=delete;
PerfCpuLogger&operator=(constPerfCpuLogger&)=delete;
~PerfCpuLogger(){
constdouble result=
process_metrics_->GetPlatformIndependentCPUUsage().value_or(-1.0);
base::LogPerfResult(test_name_.c_str(), result,"%");
}
private:
std::string test_name_;
std::unique_ptr<base::ProcessMetrics> process_metrics_;
};
MULTIPROCESS_TEST_MAIN(MojoPerfTestClientTestChildMain){
MojoPerfTestClient client;
int rv= mojo::core::test::MultiprocessTestHelper::RunClientMain(
base::BindOnce(&MojoPerfTestClient::Run, base::Unretained(&client)),
true/* pass_pipe_ownership_to_main */);
base::RunLoop run_loop;
run_loop.RunUntilIdle();
return rv;
}
classMojoSteadyPingPongTest:public mojo::core::test::MojoTestBase{
public:
MojoSteadyPingPongTest()=default;
MojoSteadyPingPongTest(constMojoSteadyPingPongTest&)=delete;
MojoSteadyPingPongTest&operator=(constMojoSteadyPingPongTest&)=delete;
protected:
voidRunPingPongServer(MojoHandle mp,const std::string& label,bool sync){
label_= label;
sync_= sync;
mojo::MessagePipeHandle mp_handle(mp);
mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
ping_receiver_.Bind(
mojo::PendingRemote<IPC::mojom::Reflector>(std::move(scoped_mp),0u));
LockThreadAffinity thread_locker(kSharedCore);
std::vector<TestParams> params_list=GetDefaultTestParams();
for(constauto& params: params_list){
params_= params;
payload_= std::string(params.message_size,'a');
ping_receiver_->Ping("hello",
base::BindOnce(&MojoSteadyPingPongTest::OnHello,
base::Unretained(this)));
base::RunLoop run_loop;
quit_closure_= run_loop.QuitWhenIdleClosure();
run_loop.Run();
}
ping_receiver_->Quit();
std::ignore= ping_receiver_.Unbind().PassPipe().release();
}
voidOnHello(const std::string& value){
cpu_logger_= std::make_unique<PerfCpuLogger>(GetLogTitle(label_, params_));
frame_count_down_= params_.frames_per_second* params_.duration_in_seconds;
timer_.Start(FROM_HERE,GetFrameTime(params_.frames_per_second),this,
&MojoSteadyPingPongTest::StartPingPong);
}
voidStartPingPong(){
if(sync_){
base::TimeTicks before= base::TimeTicks::Now();
for(count_down_= params_.messages_per_frame; count_down_>0;
--count_down_){
std::string response;
ping_receiver_->SyncPing(payload_,&response);
DCHECK_EQ(response, payload_);
}
if(base::TimeTicks::Now()- before>
GetFrameTime(params_.frames_per_second)){
LOG(ERROR)<<"Frame "<< frame_count_down_
<<" wasn't able to complete on time!";
}
CHECK_GT(frame_count_down_,0);
frame_count_down_--;
if(frame_count_down_==0)
StopPingPong();
}else{
if(count_down_!=0){
LOG(ERROR)<<"Frame "<< frame_count_down_
<<" wasn't able to complete on time!";
}else{
SendPing();
}
count_down_= params_.messages_per_frame;
}
}
voidStopPingPong(){
cpu_logger_.reset();
timer_.Stop();
std::move(quit_closure_).Run();
}
voidOnPong(const std::string& value){
// Include message deserialization in latency.
DCHECK_EQ(payload_.size(), value.size());
CHECK_GT(count_down_,0);
count_down_--;
if(count_down_>0){
SendPing();
}else{
CHECK_GT(frame_count_down_,0);
frame_count_down_--;
if(frame_count_down_==0)
StopPingPong();
}
}
voidSendPing(){
ping_receiver_->Ping(payload_,
base::BindOnce(&MojoSteadyPingPongTest::OnPong,
base::Unretained(this)));
}
staticintRunPingPongClient(MojoHandle mp){
mojo::MessagePipeHandle mp_handle(mp);
mojo::ScopedMessagePipeHandle scoped_mp(mp_handle);
LockThreadAffinity thread_locker(kSharedCore);
base::RunLoop run_loop;
ReflectorImpl impl(std::move(scoped_mp), run_loop.QuitWhenIdleClosure());
run_loop.Run();
return0;
}
private:
TestParams params_;
std::string payload_;
std::string label_;
bool sync_=false;
mojo::Remote<IPC::mojom::Reflector> ping_receiver_;
int count_down_=0;
int frame_count_down_=0;
base::RepeatingTimer timer_;
std::unique_ptr<PerfCpuLogger> cpu_logger_;
base::OnceClosure quit_closure_;
};
DEFINE_TEST_CLIENT_WITH_PIPE(PingPongClient,MojoSteadyPingPongTest, h){
base::test::SingleThreadTaskEnvironment task_environment;
base::test::ScopedRunLoopTimeout increased_timeout(
FROM_HERE,TestTimeouts::action_max_timeout());
returnRunPingPongClient(h);
}
TEST_F(MojoSteadyPingPongTest,AsyncPingPong){
RunTestClient("PingPongClient",[&](MojoHandle h){
base::test::SingleThreadTaskEnvironment task_environment;
base::test::ScopedRunLoopTimeout increased_timeout(
FROM_HERE,TestTimeouts::action_max_timeout());
RunPingPongServer(h,"Mojo_CPU_Async",false);
});
}
TEST_F(MojoSteadyPingPongTest,SyncPingPong){
RunTestClient("PingPongClient",[&](MojoHandle h){
base::test::SingleThreadTaskEnvironment task_environment;
base::test::ScopedRunLoopTimeout increased_timeout(
FROM_HERE,TestTimeouts::action_max_timeout());
RunPingPongServer(h,"Mojo_CPU_Sync",true);
});
}
}// namespace
}// namespace IPC

[8]ページ先頭

©2009-2025 Movatter.jp