blob: 0f148ef965da75cf03cca1a7b7f94d28f7343043 [file] [log] [blame]
// Copyright 2020 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.
#ifndef SRC_ZIRCON_BIN_PISTRESS_TEST_THREAD_H_
#define SRC_ZIRCON_BIN_PISTRESS_TEST_THREAD_H_
#include <fuchsia/scheduler/cpp/fidl.h>
#include <lib/zx/profile.h>
#include <lib/zx/thread.h>
#include <zircon/assert.h>
#include <zircon/syscalls/profile.h>
#include <zircon/time.h>
#include <array>
#include <atomic>
#include <memory>
#include <thread>
#include <fbl/mutex.h>
#include "behavior.h"
#include "sync_obj.h"
// A class which implements the behavior of the test threads, as well as holding
// the state shared between all test threads (such as the collection of
// synchronization objects that they fight over).
class TestThread {
public:
static zx_status_t InitStatics();
static zx_status_t AddThread(const TestThreadBehavior& behavior);
static void Shutdown();
static const auto& threads() { return threads_; }
static TestThread& random_thread();
// No copy, no move.
TestThread(const TestThread&) = delete;
TestThread(TestThread&&) = delete;
TestThread& operator=(const TestThread&) = delete;
TestThread& operator=(TestThread&&) = delete;
void Start();
void ChangeProfile();
private:
friend class std::default_delete<TestThread>;
TestThread(const TestThreadBehavior& behavior, zx::profile profile);
~TestThread();
void Join();
void Run();
void HoldLocks(size_t deck_ndx = 0);
static inline constexpr size_t kNumMutexes = 28;
static inline constexpr size_t kNumCondVars = 4;
static inline constexpr size_t kNumSyncObjs = kNumMutexes + kNumCondVars;
static inline std::array<std::unique_ptr<SyncObj>, kNumSyncObjs> sync_objs_;
static inline std::atomic<bool> shutdown_now_{false};
static inline std::vector<std::unique_ptr<TestThread>> threads_;
static inline std::unique_ptr<fuchsia::scheduler::ProfileProvider_SyncProxy> profile_provider_;
static inline std::uniform_int_distribution<size_t> thread_dist_{0, 0};
std::optional<std::thread> thread_;
TestThreadBehavior behavior_;
const zx::profile profile_;
fbl::Mutex profile_lock_;
__TA_GUARDED(profile_lock_) bool profile_borrowed_{false};
__TA_GUARDED(profile_lock_) zx::unowned_thread self_;
std::array<size_t, kNumSyncObjs> sync_obj_deck_;
size_t path_len_ = 0;
};
#endif // SRC_ZIRCON_BIN_PISTRESS_TEST_THREAD_H_