1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ipc/ipdl/test/cxx/TestLatency.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,258 @@ 1.4 +#include "TestLatency.h" 1.5 + 1.6 +#include "IPDLUnitTests.h" // fail etc. 1.7 + 1.8 +// A ping/pong trial takes O(100us) or more, so if we don't have 10us 1.9 +// resolution or better, the results will not be terribly useful 1.10 +static const double kTimingResolutionCutoff = 0.00001; // 10us 1.11 + 1.12 +namespace mozilla { 1.13 +namespace _ipdltest { 1.14 + 1.15 +//----------------------------------------------------------------------------- 1.16 +// parent 1.17 + 1.18 +TestLatencyParent::TestLatencyParent() : 1.19 + mStart(), 1.20 + mPPTimeTotal(), 1.21 + mPP5TimeTotal(), 1.22 + mRpcTimeTotal(), 1.23 + mPPTrialsToGo(NR_TRIALS), 1.24 + mPP5TrialsToGo(NR_TRIALS), 1.25 + mNumChildProcessedCompressedSpams(0) 1.26 +{ 1.27 + MOZ_COUNT_CTOR(TestLatencyParent); 1.28 +} 1.29 + 1.30 +TestLatencyParent::~TestLatencyParent() 1.31 +{ 1.32 + MOZ_COUNT_DTOR(TestLatencyParent); 1.33 +} 1.34 + 1.35 +void 1.36 +TestLatencyParent::Main() 1.37 +{ 1.38 + TimeDuration resolution = TimeDuration::Resolution(); 1.39 + if (resolution.ToSeconds() > kTimingResolutionCutoff) { 1.40 + puts(" (skipping TestLatency, timing resolution is too poor)"); 1.41 + Close(); 1.42 + return; 1.43 + } 1.44 + 1.45 + printf(" timing resolution: %g seconds\n", 1.46 + resolution.ToSecondsSigDigits()); 1.47 + 1.48 + if (mozilla::ipc::LoggingEnabled()) 1.49 + NS_RUNTIMEABORT("you really don't want to log all IPC messages during this test, trust me"); 1.50 + 1.51 + PingPongTrial(); 1.52 +} 1.53 + 1.54 +void 1.55 +TestLatencyParent::PingPongTrial() 1.56 +{ 1.57 + mStart = TimeStamp::Now(); 1.58 + if (!SendPing()) 1.59 + fail("sending Ping()"); 1.60 +} 1.61 + 1.62 +void 1.63 +TestLatencyParent::Ping5Pong5Trial() 1.64 +{ 1.65 + mStart = TimeStamp::Now(); 1.66 + 1.67 + if (!SendPing5() || 1.68 + !SendPing5() || 1.69 + !SendPing5() || 1.70 + !SendPing5() || 1.71 + !SendPing5()) 1.72 + fail("sending Ping5()"); 1.73 +} 1.74 + 1.75 +bool 1.76 +TestLatencyParent::RecvPong() 1.77 +{ 1.78 + TimeDuration thisTrial = (TimeStamp::Now() - mStart); 1.79 + mPPTimeTotal += thisTrial; 1.80 + 1.81 + if (0 == (mPPTrialsToGo % 1000)) 1.82 + printf(" PP trial %d: %g\n", 1.83 + mPPTrialsToGo, thisTrial.ToSecondsSigDigits()); 1.84 + 1.85 + if (--mPPTrialsToGo > 0) 1.86 + PingPongTrial(); 1.87 + else 1.88 + Ping5Pong5Trial(); 1.89 + return true; 1.90 +} 1.91 + 1.92 +bool 1.93 +TestLatencyParent::RecvPong5() 1.94 +{ 1.95 + if (PTestLatency::PING5 != state()) 1.96 + return true; 1.97 + 1.98 + TimeDuration thisTrial = (TimeStamp::Now() - mStart); 1.99 + mPP5TimeTotal += thisTrial; 1.100 + 1.101 + if (0 == (mPP5TrialsToGo % 1000)) 1.102 + printf(" PP5 trial %d: %g\n", 1.103 + mPP5TrialsToGo, thisTrial.ToSecondsSigDigits()); 1.104 + 1.105 + if (0 < --mPP5TrialsToGo) 1.106 + Ping5Pong5Trial(); 1.107 + else 1.108 + RpcTrials(); 1.109 + 1.110 + return true; 1.111 +} 1.112 + 1.113 +void 1.114 +TestLatencyParent::RpcTrials() 1.115 +{ 1.116 + TimeStamp start = TimeStamp::Now(); 1.117 + for (int i = 0; i < NR_TRIALS; ++i) { 1.118 + if (!CallRpc()) 1.119 + fail("can't call Rpc()"); 1.120 + if (0 == (i % 1000)) 1.121 + printf(" Rpc trial %d\n", i); 1.122 + } 1.123 + mRpcTimeTotal = (TimeStamp::Now() - start); 1.124 + 1.125 + SpamTrial(); 1.126 +} 1.127 + 1.128 +void 1.129 +TestLatencyParent::SpamTrial() 1.130 +{ 1.131 + TimeStamp start = TimeStamp::Now(); 1.132 + for (int i = 0; i < NR_SPAMS - 1; ++i) { 1.133 + if (!SendSpam()) 1.134 + fail("sending Spam()"); 1.135 + if (0 == (i % 10000)) 1.136 + printf(" Spam trial %d\n", i); 1.137 + } 1.138 + 1.139 + // Synchronize with the child process to ensure all messages have 1.140 + // been processed. This adds the overhead of a reply message from 1.141 + // child-->here, but should be insignificant compared to >> 1.142 + // NR_SPAMS. 1.143 + if (!CallSynchro()) 1.144 + fail("calling Synchro()"); 1.145 + 1.146 + mSpamTimeTotal = (TimeStamp::Now() - start); 1.147 + 1.148 + CompressedSpamTrial(); 1.149 +} 1.150 + 1.151 +void 1.152 +TestLatencyParent::CompressedSpamTrial() 1.153 +{ 1.154 + for (int i = 0; i < NR_SPAMS; ++i) { 1.155 + if (!SendCompressedSpam(i + 1)) 1.156 + fail("sending CompressedSpam()"); 1.157 + if (0 == (i % 10000)) 1.158 + printf(" CompressedSpam trial %d\n", i); 1.159 + } 1.160 + 1.161 + uint32_t lastSeqno; 1.162 + if (!CallSynchro2(&lastSeqno, &mNumChildProcessedCompressedSpams)) 1.163 + fail("calling Synchro2()"); 1.164 + 1.165 + if (lastSeqno != NR_SPAMS) 1.166 + fail("last seqno was %u, expected %u", lastSeqno, NR_SPAMS); 1.167 + 1.168 + // NB: since this is testing an optimization, it's somewhat bogus. 1.169 + // Need to make a warning if it actually intermittently fails in 1.170 + // practice, which is doubtful. 1.171 + if (!(mNumChildProcessedCompressedSpams < NR_SPAMS)) 1.172 + fail("Didn't compress any messages?"); 1.173 + 1.174 + Exit(); 1.175 +} 1.176 + 1.177 +void 1.178 +TestLatencyParent::Exit() 1.179 +{ 1.180 + Close(); 1.181 +} 1.182 + 1.183 +//----------------------------------------------------------------------------- 1.184 +// child 1.185 + 1.186 +TestLatencyChild::TestLatencyChild() 1.187 + : mLastSeqno(0) 1.188 + , mNumProcessedCompressedSpams(0) 1.189 +{ 1.190 + MOZ_COUNT_CTOR(TestLatencyChild); 1.191 +} 1.192 + 1.193 +TestLatencyChild::~TestLatencyChild() 1.194 +{ 1.195 + MOZ_COUNT_DTOR(TestLatencyChild); 1.196 +} 1.197 + 1.198 +bool 1.199 +TestLatencyChild::RecvPing() 1.200 +{ 1.201 + SendPong(); 1.202 + return true; 1.203 +} 1.204 + 1.205 +bool 1.206 +TestLatencyChild::RecvPing5() 1.207 +{ 1.208 + if (PTestLatency::PONG1 != state()) 1.209 + return true; 1.210 + 1.211 + if (!SendPong5() || 1.212 + !SendPong5() || 1.213 + !SendPong5() || 1.214 + !SendPong5() || 1.215 + !SendPong5()) 1.216 + fail("sending Pong5()"); 1.217 + 1.218 + return true; 1.219 +} 1.220 + 1.221 +bool 1.222 +TestLatencyChild::AnswerRpc() 1.223 +{ 1.224 + return true; 1.225 +} 1.226 + 1.227 +bool 1.228 +TestLatencyChild::RecvSpam() 1.229 +{ 1.230 + // no-op 1.231 + return true; 1.232 +} 1.233 + 1.234 +bool 1.235 +TestLatencyChild::AnswerSynchro() 1.236 +{ 1.237 + return true; 1.238 +} 1.239 + 1.240 +bool 1.241 +TestLatencyChild::RecvCompressedSpam(const uint32_t& seqno) 1.242 +{ 1.243 + if (seqno <= mLastSeqno) 1.244 + fail("compressed seqnos must monotonically increase"); 1.245 + 1.246 + mLastSeqno = seqno; 1.247 + ++mNumProcessedCompressedSpams; 1.248 + return true; 1.249 +} 1.250 + 1.251 +bool 1.252 +TestLatencyChild::AnswerSynchro2(uint32_t* lastSeqno, 1.253 + uint32_t* numMessagesDispatched) 1.254 +{ 1.255 + *lastSeqno = mLastSeqno; 1.256 + *numMessagesDispatched = mNumProcessedCompressedSpams; 1.257 + return true; 1.258 +} 1.259 + 1.260 +} // namespace _ipdltest 1.261 +} // namespace mozilla