15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved. 25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// found in the LICENSE file. 45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// This tests the performance of the C API. 65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 7effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/c/system/core.h" 85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <assert.h> 105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stddef.h> 115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdint.h> 125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <stdio.h> 135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 14effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/system/macros.h" 15e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_support.h" 16e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch#include "mojo/public/cpp/test_support/test_utils.h" 175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h" 185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// TODO(vtl): (here and below) crbug.com/342893 205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(WIN32) 215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include <time.h> 22effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "mojo/public/cpp/utility/thread.h" 235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(WIN32) 245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)namespace { 265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(WIN32) 285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MessagePipeWriterThread : public mojo::Thread { 295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MessagePipeWriterThread(MojoHandle handle, uint32_t num_bytes) 316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : handle_(handle), num_bytes_(num_bytes), num_writes_(0) {} 325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MessagePipeWriterThread() {} 335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Run() MOJO_OVERRIDE { 355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char buffer[10000]; 365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(num_bytes_ <= sizeof(buffer)); 375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // TODO(vtl): Should I throttle somehow? 395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (;;) { 406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MojoResult result = MojoWriteMessage( 416e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) handle_, buffer, num_bytes_, NULL, 0, MOJO_WRITE_MESSAGE_FLAG_NONE); 425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result == MOJO_RESULT_OK) { 435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_writes_++; 445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We failed to write. 485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Either |handle_| or its peer was closed. 495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_INVALID_ARGUMENT || 505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result == MOJO_RESULT_FAILED_PRECONDITION); 515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 545d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use only after joining the thread. 565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_writes() const { return num_writes_; } 575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MojoHandle handle_; 605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const uint32_t num_bytes_; 615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_writes_; 625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(MessagePipeWriterThread); 645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class MessagePipeReaderThread : public mojo::Thread { 675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) explicit MessagePipeReaderThread(MojoHandle handle) 696e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) : handle_(handle), num_reads_(0) {} 705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~MessagePipeReaderThread() {} 715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual void Run() MOJO_OVERRIDE { 735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char buffer[10000]; 745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (;;) { 765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t num_bytes = static_cast<uint32_t>(sizeof(buffer)); 776e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) MojoResult result = MojoReadMessage( 786e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) handle_, buffer, &num_bytes, NULL, NULL, MOJO_READ_MESSAGE_FLAG_NONE); 795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result == MOJO_RESULT_OK) { 805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_reads_++; 815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result == MOJO_RESULT_SHOULD_WAIT) { 856e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) result = MojoWait( 866e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) handle_, MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE); 875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (result == MOJO_RESULT_OK) { 885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Go to the top of the loop to read again. 895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) continue; 905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // We failed to read and possibly failed to wait. 945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Either |handle_| or its peer was closed. 955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_INVALID_ARGUMENT || 965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result == MOJO_RESULT_FAILED_PRECONDITION); 975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) break; 985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Use only after joining the thread. 1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_reads() const { return num_reads_; } 1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MojoHandle handle_; 1065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_reads_; 1075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(MessagePipeReaderThread); 1095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 1105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(WIN32) 1115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class CorePerftest : public testing::Test { 1135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) public: 1145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CorePerftest() : buffer_(NULL), num_bytes_(0) {} 1155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) virtual ~CorePerftest() {} 1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1176e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static void NoOp(void* /*closure*/) {} 1185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void MessagePipe_CreateAndClose(void* closure) { 1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CorePerftest* self = static_cast<CorePerftest*>(closure); 1215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 122f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = MojoCreateMessagePipe(NULL, &self->h0_, &self->h1_); 1235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(self->h0_); 1255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(self->h1_); 1275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void MessagePipe_WriteAndRead(void* closure) { 1315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CorePerftest* self = static_cast<CorePerftest*>(closure); 1325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 1335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoWriteMessage(self->h0_, 1346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self->buffer_, 1356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self->num_bytes_, 1366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) NULL, 1376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 0, 1385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_WRITE_MESSAGE_FLAG_NONE); 1395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t read_bytes = self->num_bytes_; 1415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoReadMessage(self->h1_, 1426e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self->buffer_, 1436e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) &read_bytes, 1446e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) NULL, 1456e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) NULL, 1465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_READ_MESSAGE_FLAG_NONE); 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static void MessagePipe_EmptyRead(void* closure) { 1515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) CorePerftest* self = static_cast<CorePerftest*>(closure); 1525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 1536e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) result = MojoReadMessage( 1546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) self->h0_, NULL, NULL, NULL, NULL, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD); 1555d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_SHOULD_WAIT); 1565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) protected: 1595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(WIN32) 1605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void DoMessagePipeThreadedTest(unsigned num_writers, 1615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) unsigned num_readers, 1625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t num_bytes) { 1635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) static const int64_t kPerftestTimeMicroseconds = 3 * 1000000; 1645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(num_writers > 0); 1665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(num_readers > 0); 1675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 169f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = MojoCreateMessagePipe(NULL, &h0_, &h1_); 1705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<MessagePipeWriterThread*> writers; 1735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_writers; i++) 1745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writers.push_back(new MessagePipeWriterThread(h0_, num_bytes)); 1755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) std::vector<MessagePipeReaderThread*> readers; 1775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_readers; i++) 1785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) readers.push_back(new MessagePipeReaderThread(h1_)); 1795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Start time here, just before we fire off the threads. 1815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) const MojoTimeTicks start_time = MojoGetTimeTicksNow(); 1825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Interleave the starts. 1845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_writers || i < num_readers; i++) { 1855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i < num_writers) 1865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writers[i]->Start(); 1875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (i < num_readers) 1885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) readers[i]->Start(); 1895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 1905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) Sleep(kPerftestTimeMicroseconds); 1925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Close both handles to make writers and readers stop immediately. 1945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h0_); 1955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h1_); 1975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 1985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 1995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Join everything. 2005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_writers; i++) 2015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writers[i]->Join(); 2025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_readers; i++) 2035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) readers[i]->Join(); 2045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Stop time here. 2065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoTimeTicks end_time = MojoGetTimeTicksNow(); 2075d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // Add up write and read counts, and destroy the threads. 2095d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_writes = 0; 2105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_writers; i++) { 2115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_writes += writers[i]->num_writes(); 2125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete writers[i]; 2135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) writers.clear(); 2155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int64_t num_reads = 0; 2165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) for (unsigned i = 0; i < num_readers; i++) { 2175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_reads += readers[i]->num_reads(); 2185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) delete readers[i]; 2195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) readers.clear(); 2215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) char test_name[200]; 2236e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sprintf(test_name, 2246e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MessagePipe_Threaded_Writes_%uw_%ur_%ubytes", 2256e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) num_writers, 2266e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) num_readers, 2276e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static_cast<unsigned>(num_bytes)); 2286e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mojo::test::LogPerfResult( 2296e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) test_name, 2306e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1000000.0 * static_cast<double>(num_writes) / (end_time - start_time), 2316e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "writes/second"); 2326e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) sprintf(test_name, 2336e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MessagePipe_Threaded_Reads_%uw_%ur_%ubytes", 2346e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) num_writers, 2356e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) num_readers, 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static_cast<unsigned>(num_bytes)); 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mojo::test::LogPerfResult( 2386e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) test_name, 2396e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) 1000000.0 * static_cast<double>(num_reads) / (end_time - start_time), 2406e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "reads/second"); 2415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(WIN32) 2435d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2445d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoHandle h0_; 2455d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoHandle h1_; 2465d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void* buffer_; 2485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) uint32_t num_bytes_; 2495d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) private: 2515d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(WIN32) 2525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) void Sleep(int64_t microseconds) { 2535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) struct timespec req = { 2546e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static_cast<time_t>(microseconds / 1000000), // Seconds. 2556e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) static_cast<long>(microseconds % 1000000) * 1000L // Nanoseconds. 2565d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) }; 2575d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) int rv MOJO_ALLOW_UNUSED; 2585d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) rv = nanosleep(&req, NULL); 2595d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(rv == 0); 2605d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) } 2615d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(WIN32) 2625d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2635d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MOJO_DISALLOW_COPY_AND_ASSIGN(CorePerftest); 2645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}; 2655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)// A no-op test so we can compare performance. 2675d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CorePerftest, NoOp) { 2685d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("NoOp", &CorePerftest::NoOp, this); 2695d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2705d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CorePerftest, MessagePipe_CreateAndClose) { 2725d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("MessagePipe_CreateAndClose", 2735d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CorePerftest::MessagePipe_CreateAndClose, 2745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 2765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 2775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CorePerftest, MessagePipe_WriteAndRead) { 2785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 279f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = MojoCreateMessagePipe(NULL, &h0_, &h1_); 2805d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 2816e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) char buffer[10000] = {0}; 2825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) buffer_ = buffer; 2835d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_bytes_ = 10u; 2845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("MessagePipe_WriteAndRead_10bytes", 2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CorePerftest::MessagePipe_WriteAndRead, 2865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_bytes_ = 100u; 2885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("MessagePipe_WriteAndRead_100bytes", 2895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CorePerftest::MessagePipe_WriteAndRead, 2905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2915d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_bytes_ = 1000u; 2925d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("MessagePipe_WriteAndRead_1000bytes", 2935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CorePerftest::MessagePipe_WriteAndRead, 2945d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2955d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) num_bytes_ = 10000u; 2965d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) mojo::test::IterateAndReportPerf("MessagePipe_WriteAndRead_10000bytes", 2975d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) &CorePerftest::MessagePipe_WriteAndRead, 2985d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) this); 2995d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h0_); 3005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 3015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h1_); 3025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 3035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3045d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CorePerftest, MessagePipe_EmptyRead) { 3065d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) MojoResult result MOJO_ALLOW_UNUSED; 307f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) result = MojoCreateMessagePipe(NULL, &h0_, &h1_); 3085d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 3096e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) mojo::test::IterateAndReportPerf( 3106e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) "MessagePipe_EmptyRead", &CorePerftest::MessagePipe_EmptyRead, this); 3115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h0_); 3125d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 3135d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) result = MojoClose(h1_); 3145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) assert(result == MOJO_RESULT_OK); 3155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3175d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#if !defined(WIN32) 3185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)TEST_F(CorePerftest, MessagePipe_Threaded) { 3195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(1u, 1u, 100u); 3205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(2u, 2u, 100u); 3215d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(3u, 3u, 100u); 3225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(10u, 10u, 100u); 3235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(10u, 1u, 100u); 3245d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(1u, 10u, 100u); 3255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // For comparison of overhead: 3275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(1u, 1u, 10u); 3285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 100 was done above. 3295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(1u, 1u, 1000u); 3305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(1u, 1u, 10000u); 3315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(3u, 3u, 10u); 3335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // 100 was done above. 3345d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(3u, 3u, 1000u); 3355d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) DoMessagePipeThreadedTest(3u, 3u, 10000u); 3365d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} 3375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#endif // !defined(WIN32) 3385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) 3395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)} // namespace 340