| // Copyright 2019 The Fuchsia 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 <lib/zx/event.h> |
| |
| #include <thread> |
| #include <vector> |
| |
| #include <fbl/string_printf.h> |
| #include <perftest/perftest.h> |
| |
| #include "assert.h" |
| |
| namespace { |
| |
| // Helper function that will run in its own thread. Continuously calls get_info |
| // until told to stop via a shared variable. |
| void DoHandleValid(std::atomic<bool>* stop, zx::event* event) { |
| while (!stop->load(std::memory_order_relaxed)) { |
| ASSERT_OK(event->get_info(ZX_INFO_HANDLE_VALID, nullptr, 0, nullptr, nullptr)); |
| } |
| } |
| |
| // Measure how long a simple 'get_info' call takes whilst other cores are doing |
| // the same. This is measuring the scalability of |
| // get_info(ZX_INFO_HANDLE_INVALID), particularly the synchronization in the |
| // kernel on this syscall path. |
| // |
| // Should not be invoked with more threads than there are cpus otherwise there |
| // is a chance with the current scheduler that the main test thread does not get |
| // to run (or gets to run very sporadically) and makes the test hang (fxbug.dev/31453). |
| bool HandleValid(perftest::RepeatState* state, uint32_t num_threads) { |
| // Object so we have a handle to test validity of. |
| zx::event event; |
| ASSERT_OK(zx::event::create(0, &event)); |
| |
| // Shared variable for signaling worker threads to stop. |
| std::atomic<bool> stop(false); |
| |
| // Create our worker threads. |
| std::vector<std::thread> threads(num_threads - 1); |
| |
| for (auto& t : threads) { |
| t = std::thread(&DoHandleValid, &stop, &event); |
| } |
| |
| while (state->KeepRunning()) { |
| ASSERT_OK(event.get_info(ZX_INFO_HANDLE_VALID, nullptr, 0, nullptr, nullptr)); |
| } |
| |
| // Inform our worker threads to stop so we can nicely join them. |
| stop.store(true, std::memory_order_seq_cst); |
| |
| for (auto& t : threads) { |
| t.join(); |
| } |
| |
| return true; |
| } |
| |
| void RegisterTests() { |
| for (unsigned i = 1; i <= zx_system_get_num_cpus(); i++) { |
| auto name = fbl::StringPrintf("HandleValid/%uThreads", i); |
| perftest::RegisterTest(name.c_str(), HandleValid, i); |
| } |
| } |
| PERFTEST_CTOR(RegisterTests); |
| |
| } // namespace |