summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
authorGravatar bunnei2018-12-03 17:05:57 -0500
committerGravatar GitHub2018-12-03 17:05:57 -0500
commitef69b4b83050967732e6e977396111289c9e86ba (patch)
tree0f0908b21f5cec9dca4d2269cd724cfca81848db /src/core/hle/kernel
parentMerge pull request #1833 from lioncash/clean (diff)
parenthle_ipc: Refactor SleepClientThread to avoid ReadableEvent (diff)
downloadyuzu-ef69b4b83050967732e6e977396111289c9e86ba.tar.gz
yuzu-ef69b4b83050967732e6e977396111289c9e86ba.tar.xz
yuzu-ef69b4b83050967732e6e977396111289c9e86ba.zip
Merge pull request #1803 from DarkLordZach/k-able-event
kernel: Divide Event into ReadableEvent and WritableEvent
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/hle_ipc.cpp29
-rw-r--r--src/core/hle/kernel/hle_ipc.h12
-rw-r--r--src/core/hle/kernel/object.h6
-rw-r--r--src/core/hle/kernel/readable_event.cpp (renamed from src/core/hle/kernel/event.cpp)27
-rw-r--r--src/core/hle/kernel/readable_event.h55
-rw-r--r--src/core/hle/kernel/svc.cpp7
-rw-r--r--src/core/hle/kernel/writable_event.cpp52
-rw-r--r--src/core/hle/kernel/writable_event.h (renamed from src/core/hle/kernel/event.h)33
8 files changed, 163 insertions, 58 deletions
diff --git a/src/core/hle/kernel/hle_ipc.cpp b/src/core/hle/kernel/hle_ipc.cpp
index 68d5376cb..61ce7d7e4 100644
--- a/src/core/hle/kernel/hle_ipc.cpp
+++ b/src/core/hle/kernel/hle_ipc.cpp
@@ -15,13 +15,14 @@
15#include "common/logging/log.h" 15#include "common/logging/log.h"
16#include "core/core.h" 16#include "core/core.h"
17#include "core/hle/ipc_helpers.h" 17#include "core/hle/ipc_helpers.h"
18#include "core/hle/kernel/event.h"
19#include "core/hle/kernel/handle_table.h" 18#include "core/hle/kernel/handle_table.h"
20#include "core/hle/kernel/hle_ipc.h" 19#include "core/hle/kernel/hle_ipc.h"
21#include "core/hle/kernel/kernel.h" 20#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/object.h" 21#include "core/hle/kernel/object.h"
23#include "core/hle/kernel/process.h" 22#include "core/hle/kernel/process.h"
23#include "core/hle/kernel/readable_event.h"
24#include "core/hle/kernel/server_session.h" 24#include "core/hle/kernel/server_session.h"
25#include "core/hle/kernel/writable_event.h"
25#include "core/memory.h" 26#include "core/memory.h"
26 27
27namespace Kernel { 28namespace Kernel {
@@ -36,11 +37,9 @@ void SessionRequestHandler::ClientDisconnected(const SharedPtr<ServerSession>& s
36 boost::range::remove_erase(connected_sessions, server_session); 37 boost::range::remove_erase(connected_sessions, server_session);
37} 38}
38 39
39SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread, 40SharedPtr<WritableEvent> HLERequestContext::SleepClientThread(
40 const std::string& reason, u64 timeout, 41 SharedPtr<Thread> thread, const std::string& reason, u64 timeout, WakeupCallback&& callback,
41 WakeupCallback&& callback, 42 SharedPtr<WritableEvent> writable_event) {
42 Kernel::SharedPtr<Kernel::Event> event) {
43
44 // Put the client thread to sleep until the wait event is signaled or the timeout expires. 43 // Put the client thread to sleep until the wait event is signaled or the timeout expires.
45 thread->SetWakeupCallback([context = *this, callback]( 44 thread->SetWakeupCallback([context = *this, callback](
46 ThreadWakeupReason reason, SharedPtr<Thread> thread, 45 ThreadWakeupReason reason, SharedPtr<Thread> thread,
@@ -51,23 +50,25 @@ SharedPtr<Event> HLERequestContext::SleepClientThread(SharedPtr<Thread> thread,
51 return true; 50 return true;
52 }); 51 });
53 52
54 if (!event) { 53 auto& kernel = Core::System::GetInstance().Kernel();
54 if (!writable_event) {
55 // Create event if not provided 55 // Create event if not provided
56 auto& kernel = Core::System::GetInstance().Kernel(); 56 const auto pair = WritableEvent::CreateEventPair(kernel, Kernel::ResetType::OneShot,
57 event = 57 "HLE Pause Event: " + reason);
58 Kernel::Event::Create(kernel, Kernel::ResetType::OneShot, "HLE Pause Event: " + reason); 58 writable_event = pair.writable;
59 } 59 }
60 60
61 event->Clear(); 61 const auto readable_event{writable_event->GetReadableEvent()};
62 writable_event->Clear();
62 thread->SetStatus(ThreadStatus::WaitHLEEvent); 63 thread->SetStatus(ThreadStatus::WaitHLEEvent);
63 thread->SetWaitObjects({event}); 64 thread->SetWaitObjects({readable_event});
64 event->AddWaitingThread(thread); 65 readable_event->AddWaitingThread(thread);
65 66
66 if (timeout > 0) { 67 if (timeout > 0) {
67 thread->WakeAfterDelay(timeout); 68 thread->WakeAfterDelay(timeout);
68 } 69 }
69 70
70 return event; 71 return writable_event;
71} 72}
72 73
73HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session) 74HLERequestContext::HLERequestContext(SharedPtr<Kernel::ServerSession> server_session)
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index a38e34b74..e5c0610cd 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -24,10 +24,11 @@ class ServiceFrameworkBase;
24namespace Kernel { 24namespace Kernel {
25 25
26class Domain; 26class Domain;
27class Event;
28class HandleTable; 27class HandleTable;
29class HLERequestContext; 28class HLERequestContext;
30class Process; 29class Process;
30class ReadableEvent;
31class WritableEvent;
31 32
32/** 33/**
33 * Interface implemented by HLE Session handlers. 34 * Interface implemented by HLE Session handlers.
@@ -119,12 +120,13 @@ public:
119 * @param callback Callback to be invoked when the thread is resumed. This callback must write 120 * @param callback Callback to be invoked when the thread is resumed. This callback must write
120 * the entire command response once again, regardless of the state of it before this function 121 * the entire command response once again, regardless of the state of it before this function
121 * was called. 122 * was called.
122 * @param event Event to use to wake up the thread. If unspecified, an event will be created. 123 * @param writable_event Event to use to wake up the thread. If unspecified, an event will be
124 * created.
123 * @returns Event that when signaled will resume the thread and call the callback function. 125 * @returns Event that when signaled will resume the thread and call the callback function.
124 */ 126 */
125 SharedPtr<Event> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason, 127 SharedPtr<WritableEvent> SleepClientThread(SharedPtr<Thread> thread, const std::string& reason,
126 u64 timeout, WakeupCallback&& callback, 128 u64 timeout, WakeupCallback&& callback,
127 Kernel::SharedPtr<Kernel::Event> event = nullptr); 129 SharedPtr<WritableEvent> writable_event = nullptr);
128 130
129 /// Populates this context with data from the requesting process/thread. 131 /// Populates this context with data from the requesting process/thread.
130 ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table, 132 ResultCode PopulateFromIncomingCommandBuffer(const HandleTable& handle_table,
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index c9f4d0bb3..69082ce3e 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -33,9 +33,9 @@ enum class HandleType : u32 {
33}; 33};
34 34
35enum class ResetType { 35enum class ResetType {
36 OneShot, 36 OneShot, ///< Reset automatically on object acquisition
37 Sticky, 37 Sticky, ///< Never reset automatically
38 Pulse, 38 Pulse, ///< Reset automatically on wakeup
39}; 39};
40 40
41class Object : NonCopyable { 41class Object : NonCopyable {
diff --git a/src/core/hle/kernel/event.cpp b/src/core/hle/kernel/readable_event.cpp
index 8967e602e..92e16b4e6 100644
--- a/src/core/hle/kernel/event.cpp
+++ b/src/core/hle/kernel/readable_event.cpp
@@ -4,46 +4,37 @@
4 4
5#include <algorithm> 5#include <algorithm>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "core/hle/kernel/event.h"
8#include "core/hle/kernel/object.h" 7#include "core/hle/kernel/object.h"
8#include "core/hle/kernel/readable_event.h"
9#include "core/hle/kernel/thread.h" 9#include "core/hle/kernel/thread.h"
10#include "core/hle/kernel/writable_event.h"
10 11
11namespace Kernel { 12namespace Kernel {
12 13
13Event::Event(KernelCore& kernel) : WaitObject{kernel} {} 14ReadableEvent::ReadableEvent(KernelCore& kernel) : WaitObject{kernel} {}
14Event::~Event() = default; 15ReadableEvent::~ReadableEvent() = default;
15 16
16SharedPtr<Event> Event::Create(KernelCore& kernel, ResetType reset_type, std::string name) { 17bool ReadableEvent::ShouldWait(Thread* thread) const {
17 SharedPtr<Event> evt(new Event(kernel));
18
19 evt->signaled = false;
20 evt->reset_type = reset_type;
21 evt->name = std::move(name);
22
23 return evt;
24}
25
26bool Event::ShouldWait(Thread* thread) const {
27 return !signaled; 18 return !signaled;
28} 19}
29 20
30void Event::Acquire(Thread* thread) { 21void ReadableEvent::Acquire(Thread* thread) {
31 ASSERT_MSG(!ShouldWait(thread), "object unavailable!"); 22 ASSERT_MSG(!ShouldWait(thread), "object unavailable!");
32 23
33 if (reset_type == ResetType::OneShot) 24 if (reset_type == ResetType::OneShot)
34 signaled = false; 25 signaled = false;
35} 26}
36 27
37void Event::Signal() { 28void ReadableEvent::Signal() {
38 signaled = true; 29 signaled = true;
39 WakeupAllWaitingThreads(); 30 WakeupAllWaitingThreads();
40} 31}
41 32
42void Event::Clear() { 33void ReadableEvent::Clear() {
43 signaled = false; 34 signaled = false;
44} 35}
45 36
46void Event::WakeupAllWaitingThreads() { 37void ReadableEvent::WakeupAllWaitingThreads() {
47 WaitObject::WakeupAllWaitingThreads(); 38 WaitObject::WakeupAllWaitingThreads();
48 39
49 if (reset_type == ResetType::Pulse) 40 if (reset_type == ResetType::Pulse)
diff --git a/src/core/hle/kernel/readable_event.h b/src/core/hle/kernel/readable_event.h
new file mode 100644
index 000000000..b1f1f4871
--- /dev/null
+++ b/src/core/hle/kernel/readable_event.h
@@ -0,0 +1,55 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#pragma once
6
7#include "core/hle/kernel/object.h"
8#include "core/hle/kernel/wait_object.h"
9
10namespace Kernel {
11
12class KernelCore;
13class WritableEvent;
14
15class ReadableEvent final : public WaitObject {
16 friend class WritableEvent;
17
18public:
19 ~ReadableEvent() override;
20
21 std::string GetTypeName() const override {
22 return "ReadableEvent";
23 }
24 std::string GetName() const override {
25 return name;
26 }
27
28 ResetType GetResetType() const {
29 return reset_type;
30 }
31
32 static const HandleType HANDLE_TYPE = HandleType::Event;
33 HandleType GetHandleType() const override {
34 return HANDLE_TYPE;
35 }
36
37 bool ShouldWait(Thread* thread) const override;
38 void Acquire(Thread* thread) override;
39
40 void WakeupAllWaitingThreads() override;
41
42 void Clear();
43
44private:
45 explicit ReadableEvent(KernelCore& kernel);
46
47 void Signal();
48
49 ResetType reset_type;
50 bool signaled;
51
52 std::string name; ///< Name of event (optional)
53};
54
55} // namespace Kernel
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 3339777c1..051b09d00 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -20,17 +20,18 @@
20#include "core/hle/kernel/address_arbiter.h" 20#include "core/hle/kernel/address_arbiter.h"
21#include "core/hle/kernel/client_port.h" 21#include "core/hle/kernel/client_port.h"
22#include "core/hle/kernel/client_session.h" 22#include "core/hle/kernel/client_session.h"
23#include "core/hle/kernel/event.h"
24#include "core/hle/kernel/handle_table.h" 23#include "core/hle/kernel/handle_table.h"
25#include "core/hle/kernel/kernel.h" 24#include "core/hle/kernel/kernel.h"
26#include "core/hle/kernel/mutex.h" 25#include "core/hle/kernel/mutex.h"
27#include "core/hle/kernel/process.h" 26#include "core/hle/kernel/process.h"
27#include "core/hle/kernel/readable_event.h"
28#include "core/hle/kernel/resource_limit.h" 28#include "core/hle/kernel/resource_limit.h"
29#include "core/hle/kernel/scheduler.h" 29#include "core/hle/kernel/scheduler.h"
30#include "core/hle/kernel/shared_memory.h" 30#include "core/hle/kernel/shared_memory.h"
31#include "core/hle/kernel/svc.h" 31#include "core/hle/kernel/svc.h"
32#include "core/hle/kernel/svc_wrap.h" 32#include "core/hle/kernel/svc_wrap.h"
33#include "core/hle/kernel/thread.h" 33#include "core/hle/kernel/thread.h"
34#include "core/hle/kernel/writable_event.h"
34#include "core/hle/lock.h" 35#include "core/hle/lock.h"
35#include "core/hle/result.h" 36#include "core/hle/result.h"
36#include "core/hle/service/service.h" 37#include "core/hle/service/service.h"
@@ -1361,7 +1362,7 @@ static ResultCode ResetSignal(Handle handle) {
1361 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); 1362 LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle);
1362 1363
1363 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1364 const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
1364 auto event = handle_table.Get<Event>(handle); 1365 auto event = handle_table.Get<ReadableEvent>(handle);
1365 1366
1366 ASSERT(event != nullptr); 1367 ASSERT(event != nullptr);
1367 1368
@@ -1524,7 +1525,7 @@ static ResultCode ClearEvent(Handle handle) {
1524 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); 1525 LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle);
1525 1526
1526 const auto& handle_table = Core::CurrentProcess()->GetHandleTable(); 1527 const auto& handle_table = Core::CurrentProcess()->GetHandleTable();
1527 SharedPtr<Event> evt = handle_table.Get<Event>(handle); 1528 SharedPtr<ReadableEvent> evt = handle_table.Get<ReadableEvent>(handle);
1528 if (evt == nullptr) { 1529 if (evt == nullptr) {
1529 LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); 1530 LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle);
1530 return ERR_INVALID_HANDLE; 1531 return ERR_INVALID_HANDLE;
diff --git a/src/core/hle/kernel/writable_event.cpp b/src/core/hle/kernel/writable_event.cpp
new file mode 100644
index 000000000..a58ea6ec8
--- /dev/null
+++ b/src/core/hle/kernel/writable_event.cpp
@@ -0,0 +1,52 @@
1// Copyright 2014 Citra Emulator Project
2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included.
4
5#include <algorithm>
6#include "common/assert.h"
7#include "core/hle/kernel/kernel.h"
8#include "core/hle/kernel/object.h"
9#include "core/hle/kernel/readable_event.h"
10#include "core/hle/kernel/thread.h"
11#include "core/hle/kernel/writable_event.h"
12
13namespace Kernel {
14
15WritableEvent::WritableEvent(KernelCore& kernel) : Object{kernel} {}
16WritableEvent::~WritableEvent() = default;
17
18EventPair WritableEvent::CreateEventPair(KernelCore& kernel, ResetType reset_type,
19 std::string name) {
20 SharedPtr<WritableEvent> writable_event(new WritableEvent(kernel));
21 SharedPtr<ReadableEvent> readable_event(new ReadableEvent(kernel));
22
23 writable_event->name = name + ":Writable";
24 writable_event->readable = readable_event;
25 readable_event->name = name + ":Readable";
26 readable_event->signaled = false;
27 readable_event->reset_type = reset_type;
28
29 return {std::move(readable_event), std::move(writable_event)};
30}
31
32SharedPtr<ReadableEvent> WritableEvent::GetReadableEvent() const {
33 return readable;
34}
35
36ResetType WritableEvent::GetResetType() const {
37 return readable->reset_type;
38}
39
40void WritableEvent::Signal() {
41 readable->Signal();
42}
43
44void WritableEvent::Clear() {
45 readable->Clear();
46}
47
48bool WritableEvent::IsSignaled() const {
49 return readable->signaled;
50}
51
52} // namespace Kernel
diff --git a/src/core/hle/kernel/event.h b/src/core/hle/kernel/writable_event.h
index 27d6126b0..fc57d18d7 100644
--- a/src/core/hle/kernel/event.h
+++ b/src/core/hle/kernel/writable_event.h
@@ -11,20 +11,29 @@
11namespace Kernel { 11namespace Kernel {
12 12
13class KernelCore; 13class KernelCore;
14class ReadableEvent;
15class WritableEvent;
14 16
15class Event final : public WaitObject { 17struct EventPair {
18 SharedPtr<ReadableEvent> readable;
19 SharedPtr<WritableEvent> writable;
20};
21
22class WritableEvent final : public Object {
16public: 23public:
24 ~WritableEvent() override;
25
17 /** 26 /**
18 * Creates an event 27 * Creates an event
19 * @param kernel The kernel instance to create this event under. 28 * @param kernel The kernel instance to create this event under.
20 * @param reset_type ResetType describing how to create event 29 * @param reset_type ResetType describing how to create event
21 * @param name Optional name of event 30 * @param name Optional name of event
22 */ 31 */
23 static SharedPtr<Event> Create(KernelCore& kernel, ResetType reset_type, 32 static EventPair CreateEventPair(KernelCore& kernel, ResetType reset_type,
24 std::string name = "Unknown"); 33 std::string name = "Unknown");
25 34
26 std::string GetTypeName() const override { 35 std::string GetTypeName() const override {
27 return "Event"; 36 return "WritableEvent";
28 } 37 }
29 std::string GetName() const override { 38 std::string GetName() const override {
30 return name; 39 return name;
@@ -35,25 +44,19 @@ public:
35 return HANDLE_TYPE; 44 return HANDLE_TYPE;
36 } 45 }
37 46
38 ResetType GetResetType() const { 47 SharedPtr<ReadableEvent> GetReadableEvent() const;
39 return reset_type;
40 }
41
42 bool ShouldWait(Thread* thread) const override;
43 void Acquire(Thread* thread) override;
44 48
45 void WakeupAllWaitingThreads() override; 49 ResetType GetResetType() const;
46 50
47 void Signal(); 51 void Signal();
48 void Clear(); 52 void Clear();
53 bool IsSignaled() const;
49 54
50private: 55private:
51 explicit Event(KernelCore& kernel); 56 explicit WritableEvent(KernelCore& kernel);
52 ~Event() override;
53 57
54 ResetType reset_type; ///< Current ResetType 58 SharedPtr<ReadableEvent> readable;
55 59
56 bool signaled; ///< Whether the event has already been signaled
57 std::string name; ///< Name of event (optional) 60 std::string name; ///< Name of event (optional)
58}; 61};
59 62