12a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// found in the LICENSE file. 42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "build/build_config.h" 62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <algorithm> 82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include <string> 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/basictypes.h" 112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/logging.h" 122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h" 132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/pickle.h" 14868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "base/strings/stringprintf.h" 15d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)#include "base/test/perf_time_logger.h" 162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/threading/thread.h" 17eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_channel.h" 192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_channel_proxy.h" 20868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ipc/ipc_descriptors.h" 212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_message_utils.h" 222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_sender.h" 232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "ipc/ipc_test_base.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace { 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This test times the roundtrip IPC message cycle. 282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// 292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// TODO(brettw): Make this test run by default. 302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class IPCChannelPerfTest : public IPCTestBase { 322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This class simply collects stats about abstract "events" (each of which has a 352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// start time and an end time). 362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class EventTimeTracker { 372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) explicit EventTimeTracker(const char* name) 392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : name_(name), 402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_(0) { 412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void AddEvent(const base::TimeTicks& start, const base::TimeTicks& end) { 442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(end >= start); 452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_++; 462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta duration = end - start; 472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_duration_ += duration; 482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_duration_ = std::max(max_duration_, duration); 492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void ShowResults() const { 522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << name_ << " count: " << count_; 532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << name_ << " total duration: " 542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << total_duration_.InMillisecondsF() << " ms"; 552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << name_ << " average duration: " 562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << (total_duration_.InMillisecondsF() / static_cast<double>(count_)) 572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << " ms"; 582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << name_ << " maximum duration: " 592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) << max_duration_.InMillisecondsF() << " ms"; 602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Reset() { 632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_ = 0; 642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) total_duration_ = base::TimeDelta(); 652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) max_duration_ = base::TimeDelta(); 662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const std::string name_; 702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) uint64 count_; 722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta total_duration_; 732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeDelta max_duration_; 742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(EventTimeTracker); 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This channel listener just replies to all messages with the exact same 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// message. It assumes each message has one string parameter. When the string 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// "quit" is sent, it will exit. 812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class ChannelReflectorListener : public IPC::Listener { 822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChannelReflectorListener() 842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : channel_(NULL), 852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_("Client messages") { 862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Client listener up"; 872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~ChannelReflectorListener() { 902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Client listener down"; 912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.ShowResults(); 922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Init(IPC::Channel* channel) { 952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!channel_); 962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_ = channel; 972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 992a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 1002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(channel_); 1012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PickleIterator iter(message); 1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 time_internal; 1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadInt64(&time_internal)); 1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int msgid; 1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadInt(&msgid)); 1072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string payload; 1082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadString(&payload)); 1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Include message deserialization in latency. 1112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks now = base::TimeTicks::Now(); 1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (payload == "hello") { 1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.Reset(); 1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else if (payload == "quit") { 1162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.ShowResults(); 117c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->QuitWhenIdle(); 1182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1202a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Don't track hello and quit messages. 1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.AddEvent( 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::FromInternalValue(time_internal), now); 1232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1250f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* msg = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); 1262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); 1272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteInt(msgid); 1282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteString(payload); 1292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->Send(msg); 1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 1312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 1342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Channel* channel_; 1352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventTimeTracker latency_tracker_; 1362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 1372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)class PerformanceChannelListener : public IPC::Listener { 1392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) public: 1402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PerformanceChannelListener() 1412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) : channel_(NULL), 1422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_count_(0), 1432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_size_(0), 1442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_down_(0), 1452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_("Server messages") { 1462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Server listener up"; 1472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1492a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~PerformanceChannelListener() { 1502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) VLOG(1) << "Server listener down"; 1512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void Init(IPC::Channel* channel) { 1542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!channel_); 1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_ = channel; 1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Call this before running the message loop. 1592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) void SetTestParams(int msg_count, size_t msg_size) { 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(0, count_down_); 1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_count_ = msg_count; 1622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_size_ = msg_size; 1632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_down_ = msg_count_; 1642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) payload_ = std::string(msg_size_, 'a'); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE { 1682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(channel_); 1692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PickleIterator iter(message); 1712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int64 time_internal; 1722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadInt64(&time_internal)); 1732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int msgid; 1742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadInt(&msgid)); 1752a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string reflected_payload; 1762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(iter.ReadString(&reflected_payload)); 1772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Include message deserialization in latency. 1792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks now = base::TimeTicks::Now(); 1802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (reflected_payload == "hello") { 1822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Start timing on hello. 1832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.Reset(); 1842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK(!perf_logger_.get()); 1852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string test_name = base::StringPrintf( 1862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) "IPC_Perf_%dx_%u", msg_count_, static_cast<unsigned>(msg_size_)); 187d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) perf_logger_.reset(new base::PerfTimeLogger(test_name.c_str())); 1882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } else { 1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DCHECK_EQ(payload_.size(), reflected_payload.size()); 1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.AddEvent( 1922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base::TimeTicks::FromInternalValue(time_internal), now); 1932a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 1942a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(count_down_ > 0); 1952a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) count_down_--; 1962a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) if (count_down_ == 0) { 1972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) perf_logger_.reset(); // Stop the perf timer now. 1982a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) latency_tracker_.ShowResults(); 199c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->QuitWhenIdle(); 2002a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2012a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* msg = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); 2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteInt64(base::TimeTicks::Now().ToInternalValue()); 2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteInt(count_down_); 2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg->WriteString(payload_); 2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) channel_->Send(msg); 2092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return true; 2102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2112a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) private: 2132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Channel* channel_; 2142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int msg_count_; 2152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t msg_size_; 2162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int count_down_; 2182a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) std::string payload_; 2192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EventTimeTracker latency_tracker_; 220d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles) scoped_ptr<base::PerfTimeLogger> perf_logger_; 2212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}; 2222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2232a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(IPCChannelPerfTest, Performance) { 2242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) Init("PerformanceClient"); 2252a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Set up IPC channel and start client. 2272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) PerformanceChannelListener listener; 2282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CreateChannel(&listener); 2292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener.Init(channel()); 2302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(ConnectChannel()); 2312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ASSERT_TRUE(StartClient()); 2322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const size_t kMsgSizeBase = 12; 2342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) const int kMsgSizeMaxExp = 5; 2352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) int msg_count = 100000; 2362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) size_t msg_size = kMsgSizeBase; 2372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) for (int i = 1; i <= kMsgSizeMaxExp; i++) { 2382a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener.SetTestParams(msg_count, msg_size); 2392a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2402a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // This initial message will kick-start the ping-pong of messages. 2412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Message* message = 2420f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); 2432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); 2442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteInt(-1); 2452a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteString("hello"); 2462a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender()->Send(message); 2472a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2482a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Run message loop. 249c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2502a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2512a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) msg_size *= kMsgSizeBase; 2522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) } 2532a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // Send quit message. 2550f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles) IPC::Message* message = new IPC::Message(0, 2, IPC::Message::PRIORITY_NORMAL); 2562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteInt64(base::TimeTicks::Now().ToInternalValue()); 2572a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteInt(-1); 2582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) message->WriteString("quit"); 2592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) sender()->Send(message); 2602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) EXPECT_TRUE(WaitForClientShutdown()); 2622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) DestroyChannel(); 2632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)// This message loop bounces all messages back to the sender. 2662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)MULTIPROCESS_IPC_TEST_CLIENT_MAIN(PerformanceClient) { 267c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoopForIO main_message_loop; 2682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) ChannelReflectorListener listener; 2692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Channel channel(IPCTestBase::GetChannelName("PerformanceClient"), 2702a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) IPC::Channel::MODE_CLIENT, 2712a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) &listener); 2722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) listener.Init(&channel); 2732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) CHECK(channel.Connect()); 2742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 275c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) base::MessageLoop::current()->Run(); 2762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) return 0; 2772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} 2782a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 2792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)} // namespace 280