| Index: mojo/public/c/environment/tests/async_waiter_perftest_helpers.cc
|
| diff --git a/mojo/public/c/environment/tests/async_waiter_perftest_helpers.cc b/mojo/public/c/environment/tests/async_waiter_perftest_helpers.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..626edbb8d320e213cf6d170ab481efc88e0e4386
|
| --- /dev/null
|
| +++ b/mojo/public/c/environment/tests/async_waiter_perftest_helpers.cc
|
| @@ -0,0 +1,136 @@
|
| +// Copyright 2016 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 "mojo/public/c/environment/tests/async_waiter_perftest_helpers.h"
|
| +
|
| +#include <assert.h>
|
| +
|
| +#include <vector>
|
| +
|
| +#include "mojo/public/c/system/handle.h"
|
| +#include "mojo/public/c/system/message_pipe.h"
|
| +#include "mojo/public/cpp/system/macros.h"
|
| +
|
| +#undef CHECK_OK
|
| +#ifdef NDEBUG
|
| +#define CHECK_OK(result) \
|
| + do { \
|
| + (void)result; \
|
| + } while (false)
|
| +#else
|
| +#define CHECK_OK(result) \
|
| + do { \
|
| + MojoResult result_internal = (result); \
|
| + assert(result_internal == MOJO_RESULT_OK); \
|
| + } while (false)
|
| +#endif
|
| +
|
| +namespace mojo {
|
| +namespace test {
|
| +namespace {
|
| +
|
| +class AsyncWaiterPerfTest {
|
| + public:
|
| + explicit AsyncWaiterPerfTest(const MojoAsyncWaiter* async_waiter,
|
| + uint32_t num_handles,
|
| + std::function<void()> run_loop_function)
|
| + : async_waiter_(async_waiter),
|
| + num_handles_(num_handles),
|
| + run_loop_function_(run_loop_function),
|
| + handle0s_(num_handles, MOJO_HANDLE_INVALID),
|
| + handle1s_(num_handles, MOJO_HANDLE_INVALID),
|
| + contexts_(num_handles) {}
|
| + ~AsyncWaiterPerfTest() {}
|
| +
|
| + uint64_t DoIt() {
|
| + for (uint32_t i = 0; i < num_handles_; i++) {
|
| + CHECK_OK(MojoCreateMessagePipe(nullptr, &handle0s_[i], &handle1s_[i]));
|
| + AddAsyncWaiter(i);
|
| + }
|
| +
|
| + // "Signal" the first async wait (i.e., write a message).
|
| + CHECK_OK(MojoWriteMessage(handle1s_[0], nullptr, 0, nullptr, 0,
|
| + MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| +
|
| + run_loop_function_();
|
| +
|
| + for (uint32_t i = 0; i < num_handles_; i++) {
|
| + CancelAsyncWaiter(i);
|
| + CHECK_OK(MojoClose(handle0s_[i]));
|
| + CHECK_OK(MojoClose(handle1s_[i]));
|
| + }
|
| +
|
| + return callback_count_;
|
| + }
|
| +
|
| + private:
|
| + struct Context {
|
| + AsyncWaiterPerfTest* thiz = nullptr;
|
| + uint32_t index = 0;
|
| + MojoAsyncWaitID id = 0;
|
| + };
|
| +
|
| + void AddAsyncWaiter(uint32_t index) {
|
| + assert(index < num_handles_);
|
| +
|
| + Context& context = contexts_[index];
|
| + context.thiz = this;
|
| + context.index = index;
|
| + context.id = async_waiter_->AsyncWait(
|
| + handle0s_[index], MOJO_HANDLE_SIGNAL_READABLE, MOJO_DEADLINE_INDEFINITE,
|
| + &AsyncWaiterPerfTest::AsyncWaitCallbackThunk, &context);
|
| + }
|
| +
|
| + void CancelAsyncWaiter(uint32_t index) {
|
| + async_waiter_->CancelWait(contexts_[index].id);
|
| + }
|
| +
|
| + static void AsyncWaitCallbackThunk(void* closure, MojoResult result) {
|
| + CHECK_OK(result);
|
| + auto context = static_cast<Context*>(closure);
|
| + context->thiz->AsyncWaitCallback(context);
|
| + }
|
| +
|
| + void AsyncWaitCallback(Context* context) {
|
| + callback_count_++;
|
| +
|
| + uint32_t index = context->index;
|
| +
|
| + // "Unsignal" (i.e., consume a message)).
|
| + CHECK_OK(MojoReadMessage(handle0s_[index], nullptr, nullptr, nullptr,
|
| + nullptr, MOJO_READ_MESSAGE_FLAG_MAY_DISCARD));
|
| +
|
| + // Replace ourself.
|
| + AddAsyncWaiter(index);
|
| +
|
| + // "Signal" the next one (i.e., write a message).
|
| + CHECK_OK(MojoWriteMessage(handle1s_[(index + 1) % num_handles_], nullptr, 0,
|
| + nullptr, 0, MOJO_WRITE_MESSAGE_FLAG_NONE));
|
| + }
|
| +
|
| + const MojoAsyncWaiter* const async_waiter_;
|
| + const uint32_t num_handles_;
|
| + const std::function<void()> run_loop_function_;
|
| +
|
| + // We'll always wait on the |handle0s_| and "signal" from the |handle1s_|.
|
| + std::vector<MojoHandle> handle0s_;
|
| + std::vector<MojoHandle> handle1s_;
|
| + std::vector<Context> contexts_;
|
| +
|
| + uint64_t callback_count_ = 0;
|
| +
|
| + MOJO_DISALLOW_COPY_AND_ASSIGN(AsyncWaiterPerfTest);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +uint64_t DoAsyncWaiterPerfTest(const MojoAsyncWaiter* async_waiter,
|
| + uint32_t num_handles,
|
| + std::function<void()> run_loop_function) {
|
| + return AsyncWaiterPerfTest(async_waiter, num_handles, run_loop_function)
|
| + .DoIt();
|
| +}
|
| +
|
| +} // namespace test
|
| +} // namespace mojo
|
|
|