blob: b5f94dd6e61f4775fb3da2b9d6e47f1a28cc8b0d [file] [log] [blame]
// 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