kernel/event: Reference ReadableEvent from WritableEvent

This commit is contained in:
Zach Hilman
2018-11-27 09:18:29 -05:00
parent ff610103b5
commit a342bcc9b1
32 changed files with 175 additions and 317 deletions

View File

@ -53,8 +53,10 @@ SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
auto& kernel = Core::System::GetInstance().Kernel();
if (!writable_event || !readable_event) {
// Create event if not provided
std::tie(writable_event, readable_event) = WritableEvent::CreateEventPair(
kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason);
const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot,
"HLE Pause Event: " + reason);
writable_event = pair.writable;
readable_event = pair.readable;
}
writable_event->Clear();

View File

@ -177,10 +177,6 @@ struct KernelCore::Impl {
// allowing us to simply use a pool index or similar.
Kernel::HandleTable thread_wakeup_callback_handle_table;
/// Map of named events managed by the kernel, which are retrieved when HLE services need to
/// return an event to the system.
NamedEventTable named_events;
/// Map of named ports managed by the kernel, which can be retrieved using
/// the ConnectToPort SVC.
NamedPortTable named_ports;
@ -227,19 +223,6 @@ const Process* KernelCore::CurrentProcess() const {
return impl->current_process;
}
void KernelCore::AddNamedEvent(std::string name, SharedPtr<ReadableEvent> event) {
impl->named_events.emplace(std::move(name), std::move(event));
}
KernelCore::NamedEventTable::iterator KernelCore::FindNamedEvent(const std::string& name) {
return impl->named_events.find(name);
}
KernelCore::NamedEventTable::const_iterator KernelCore::FindNamedEvent(
const std::string& name) const {
return impl->named_events.find(name);
}
void KernelCore::AddNamedPort(std::string name, SharedPtr<ClientPort> port) {
impl->named_ports.emplace(std::move(name), std::move(port));
}

View File

@ -20,7 +20,6 @@ namespace Kernel {
class ClientPort;
class HandleTable;
class Process;
class ReadableEvent;
class ResourceLimit;
class Thread;
class Timer;
@ -28,7 +27,6 @@ class Timer;
/// Represents a single instance of the kernel.
class KernelCore {
private:
using NamedEventTable = std::unordered_map<std::string, SharedPtr<ReadableEvent>>;
using NamedPortTable = std::unordered_map<std::string, SharedPtr<ClientPort>>;
public:
@ -68,15 +66,6 @@ public:
/// Retrieves a const pointer to the current process.
const Process* CurrentProcess() const;
/// Adds an event to the named event table
void AddNamedEvent(std::string name, SharedPtr<ReadableEvent> event);
/// Finds an event within the named event table wit the given name.
NamedEventTable::iterator FindNamedEvent(const std::string& name);
/// Finds an event within the named event table wit the given name.
NamedEventTable::const_iterator FindNamedEvent(const std::string& name) const;
/// Adds a port to the named port table
void AddNamedPort(std::string name, SharedPtr<ClientPort> port);

View File

@ -15,34 +15,30 @@ ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {}
ReadableEvent::~ReadableEvent() = default;
bool ReadableEvent::ShouldWait(Thread* thread) const {
return !writable_event->IsSignaled();
return !signaled;
}
void ReadableEvent::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
writable_event->ResetOnAcquire();
}
void ReadableEvent::AddWaitingThread(SharedPtr<Thread> thread) {
writable_event->AddWaitingThread(thread);
}
void ReadableEvent::RemoveWaitingThread(Thread* thread) {
writable_event->RemoveWaitingThread(thread);
if (reset_type == ResetType::OneShot)
signaled = false;
}
void ReadableEvent::Signal() {
writable_event->Signal();
signaled = true;
WakeupAllWaitingThreads();
}
void ReadableEvent::Clear() {
writable_event->Clear();
signaled = false;
}
void ReadableEvent::WakeupAllWaitingThreads() {
writable_event->WakeupAllWaitingThreads();
writable_event->ResetOnWakeup();
WaitObject::WakeupAllWaitingThreads();
if (reset_type == ResetType::Pulse)
signaled = false;
}
} // namespace Kernel

View File

@ -25,6 +25,10 @@ public:
return name;
}
ResetType GetResetType() const {
return reset_type;
}
static const HandleType HANDLE_TYPE = HandleType::Event;
HandleType GetHandleType() const override {
return HANDLE_TYPE;
@ -35,20 +39,15 @@ public:
void WakeupAllWaitingThreads() override;
void AddWaitingThread(SharedPtr<Thread> thread) override;
void RemoveWaitingThread(Thread* thread) override;
void Signal();
void Clear();
SharedPtr<WritableEvent> PromoteToWritable() const {
return writable_event;
}
private:
explicit ReadableEvent(KernelCore& kernel);
SharedPtr<WritableEvent> writable_event; ///< WritableEvent associated with this ReadableEvent
void Signal();
ResetType reset_type;
bool signaled;
std::string name; ///< Name of event (optional)
};

View File

@ -1366,7 +1366,7 @@ static ResultCode ResetSignal(Handle handle) {
ASSERT(event != nullptr);
event->PromoteToWritable()->Clear();
event->Clear();
return RESULT_SUCCESS;
}
@ -1531,7 +1531,7 @@ static ResultCode ClearEvent(Handle handle) {
return ERR_INVALID_HANDLE;
}
evt->PromoteToWritable()->Clear();
evt->Clear();
return RESULT_SUCCESS;
}

View File

@ -12,70 +12,37 @@
namespace Kernel {
WritableEvent::WritableEvent(KernelCore& kernel) : WaitObject{kernel} {}
WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
WritableEvent::~WritableEvent() = default;
std::tuple<SharedPtr<WritableEvent>, SharedPtr<ReadableEvent>> WritableEvent::CreateEventPair(
KernelCore& kernel, ResetType reset_type, std::string name) {
EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type,
std::string name) {
SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
writable_event->name = name + ":Writable";
writable_event->signaled = false;
writable_event->reset_type = reset_type;
writable_event->readable = readable_event;
readable_event->name = name + ":Readable";
readable_event->writable_event = writable_event;
readable_event->signaled = false;
readable_event->reset_type = reset_type;
return std::make_tuple(std::move(writable_event), std::move(readable_event));
return {std::move(readable_event), std::move(writable_event)};
}
SharedPtr<WritableEvent> WritableEvent::CreateRegisteredEventPair(KernelCore& kernel,
ResetType reset_type,
std::string name) {
auto [writable_event, readable_event] = CreateEventPair(kernel, reset_type, name);
kernel.AddNamedEvent(name, std::move(readable_event));
return std::move(writable_event);
}
bool WritableEvent::ShouldWait(Thread* thread) const {
return !signaled;
}
void WritableEvent::Acquire(Thread* thread) {
ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
if (reset_type == ResetType::OneShot)
signaled = false;
ResetType WritableEvent::GetResetType() const {
return readable->reset_type;
}
void WritableEvent::Signal() {
signaled = true;
WakeupAllWaitingThreads();
readable->Signal();
}
void WritableEvent::Clear() {
signaled = false;
}
void WritableEvent::ResetOnAcquire() {
if (reset_type == ResetType::OneShot)
Clear();
}
void WritableEvent::ResetOnWakeup() {
if (reset_type == ResetType::Pulse)
Clear();
readable->Clear();
}
bool WritableEvent::IsSignaled() const {
return signaled;
}
void WritableEvent::WakeupAllWaitingThreads() {
WaitObject::WakeupAllWaitingThreads();
if (reset_type == ResetType::Pulse)
signaled = false;
return readable->signaled;
}
} // namespace Kernel

View File

@ -12,8 +12,14 @@ namespace Kernel {
class KernelCore;
class ReadableEvent;
class WritableEvent;
class WritableEvent final : public WaitObject {
struct EventPair {
SharedPtr<ReadableEvent> readable;
SharedPtr<WritableEvent> writable;
};
class WritableEvent final : public Object {
public:
~WritableEvent() override;
@ -23,18 +29,8 @@ public:
* @param reset_type ResetType describing how to create event
* @param name Optional name of event
*/
static std::tuple<SharedPtr<WritableEvent>, SharedPtr<ReadableEvent>> CreateEventPair(
KernelCore& kernel, ResetType reset_type, std::string name = "Unknown");
/**
* Creates an event and registers it in the kernel's named event table
* @param kernel The kernel instance to create this event under.
* @param reset_type ResetType describing how to create event
* @param name name of event
*/
static SharedPtr<WritableEvent> CreateRegisteredEventPair(KernelCore& kernel,
ResetType reset_type,
std::string name);
static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type,
std::string name = "Unknown");
std::string GetTypeName() const override {
return "WritableEvent";
@ -48,27 +44,17 @@ public:
return HANDLE_TYPE;
}
ResetType GetResetType() const {
return reset_type;
}
bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;
void WakeupAllWaitingThreads() override;
ResetType GetResetType() const;
void Signal();
void Clear();
void ResetOnAcquire();
void ResetOnWakeup();
bool IsSignaled() const;
private:
explicit WritableEvent(KernelCore& kernel);
ResetType reset_type; ///< Current ResetType
SharedPtr<ReadableEvent> readable;
bool signaled; ///< Whether the event has already been signaled
std::string name; ///< Name of event (optional)
};