mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-27 19:40:05 +00:00
c4c644b285
Some objects declare their handle type as const, while others declare it as constexpr. This makes the const ones constexpr for consistency, and prevent unexpected compilation errors if these happen to be attempted to be used within a constexpr context.
73 lines
2.2 KiB
C++
73 lines
2.2 KiB
C++
// Copyright 2014 Citra Emulator Project
|
|
// Licensed under GPLv2 or any later version
|
|
// Refer to the license.txt file included.
|
|
|
|
#pragma once
|
|
|
|
#include <memory>
|
|
#include <vector>
|
|
#include "common/common_types.h"
|
|
#include "core/hle/kernel/object.h"
|
|
#include "core/hle/result.h"
|
|
|
|
// Address arbiters are an underlying kernel synchronization object that can be created/used via
|
|
// supervisor calls (SVCs). They function as sort of a global lock. Typically, games/other CTR
|
|
// applications use them as an underlying mechanism to implement thread-safe barriers, events, and
|
|
// semaphores.
|
|
|
|
////////////////////////////////////////////////////////////////////////////////////////////////////
|
|
// Kernel namespace
|
|
|
|
namespace Kernel {
|
|
|
|
class Thread;
|
|
|
|
enum class ArbitrationType : u32 {
|
|
Signal,
|
|
WaitIfLessThan,
|
|
DecrementAndWaitIfLessThan,
|
|
WaitIfLessThanWithTimeout,
|
|
DecrementAndWaitIfLessThanWithTimeout,
|
|
};
|
|
|
|
class AddressArbiter final : public Object {
|
|
public:
|
|
explicit AddressArbiter(KernelSystem& kernel);
|
|
~AddressArbiter() override;
|
|
|
|
std::string GetTypeName() const override {
|
|
return "Arbiter";
|
|
}
|
|
std::string GetName() const override {
|
|
return name;
|
|
}
|
|
|
|
static constexpr HandleType HANDLE_TYPE = HandleType::AddressArbiter;
|
|
HandleType GetHandleType() const override {
|
|
return HANDLE_TYPE;
|
|
}
|
|
|
|
std::string name; ///< Name of address arbiter object (optional)
|
|
|
|
ResultCode ArbitrateAddress(std::shared_ptr<Thread> thread, ArbitrationType type, VAddr address,
|
|
s32 value, u64 nanoseconds);
|
|
|
|
private:
|
|
KernelSystem& kernel;
|
|
|
|
/// Puts the thread to wait on the specified arbitration address under this address arbiter.
|
|
void WaitThread(std::shared_ptr<Thread> thread, VAddr wait_address);
|
|
|
|
/// Resume all threads found to be waiting on the address under this address arbiter
|
|
void ResumeAllThreads(VAddr address);
|
|
|
|
/// Resume one thread found to be waiting on the address under this address arbiter and return
|
|
/// the resumed thread.
|
|
std::shared_ptr<Thread> ResumeHighestPriorityThread(VAddr address);
|
|
|
|
/// Threads waiting for the address arbiter to be signaled.
|
|
std::vector<std::shared_ptr<Thread>> waiting_threads;
|
|
};
|
|
|
|
} // namespace Kernel
|