summaryrefslogtreecommitdiff
path: root/src/core/hle/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'src/core/hle/kernel')
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp44
-rw-r--r--src/core/hle/kernel/k_readable_event.h42
-rw-r--r--src/core/hle/kernel/k_synchronization_object.cpp3
-rw-r--r--src/core/hle/kernel/k_synchronization_object.h1
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp34
-rw-r--r--src/core/hle/kernel/k_writable_event.h40
-rw-r--r--src/core/hle/kernel/object.cpp6
-rw-r--r--src/core/hle/kernel/object.h7
-rw-r--r--src/core/hle/kernel/svc.cpp9
9 files changed, 82 insertions, 104 deletions
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp
index e9e191bc6..0fa895c56 100644
--- a/src/core/hle/kernel/k_readable_event.cpp
+++ b/src/core/hle/kernel/k_readable_event.cpp
@@ -1,9 +1,10 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2021 yuzu emulator team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include <algorithm>
6#include "common/assert.h" 6#include "common/assert.h"
7#include "common/common_funcs.h"
7#include "common/logging/log.h" 8#include "common/logging/log.h"
8#include "core/hle/kernel/errors.h" 9#include "core/hle/kernel/errors.h"
9#include "core/hle/kernel/k_readable_event.h" 10#include "core/hle/kernel/k_readable_event.h"
@@ -11,40 +12,43 @@
11#include "core/hle/kernel/k_thread.h" 12#include "core/hle/kernel/k_thread.h"
12#include "core/hle/kernel/kernel.h" 13#include "core/hle/kernel/kernel.h"
13#include "core/hle/kernel/object.h" 14#include "core/hle/kernel/object.h"
15#include "core/hle/kernel/svc_results.h"
14 16
15namespace Kernel { 17namespace Kernel {
16 18
17KReadableEvent::KReadableEvent(KernelCore& kernel) : KSynchronizationObject{kernel} {} 19KReadableEvent::KReadableEvent(KernelCore& kernel, std::string&& name)
20 : KSynchronizationObject{kernel, std::move(name)} {}
18KReadableEvent::~KReadableEvent() = default; 21KReadableEvent::~KReadableEvent() = default;
19 22
20void KReadableEvent::Signal() {
21 if (is_signaled) {
22 return;
23 }
24
25 is_signaled = true;
26 NotifyAvailable();
27}
28
29bool KReadableEvent::IsSignaled() const { 23bool KReadableEvent::IsSignaled() const {
30 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 24 ASSERT(kernel.GlobalSchedulerContext().IsLocked());
31 25
32 return is_signaled; 26 return is_signaled;
33} 27}
34 28
35void KReadableEvent::Clear() { 29ResultCode KReadableEvent::Signal() {
36 is_signaled = false; 30 KScopedSchedulerLock lk{kernel};
37}
38 31
39ResultCode KReadableEvent::Reset() {
40 KScopedSchedulerLock lock(kernel);
41 if (!is_signaled) { 32 if (!is_signaled) {
42 LOG_TRACE(Kernel, "Handle is not signaled! object_id={}, object_type={}, object_name={}", 33 is_signaled = true;
43 GetObjectId(), GetTypeName(), GetName()); 34 NotifyAvailable();
44 return ERR_INVALID_STATE;
45 } 35 }
46 36
47 Clear(); 37 return RESULT_SUCCESS;
38}
39
40ResultCode KReadableEvent::Clear() {
41 Reset();
42
43 return RESULT_SUCCESS;
44}
45
46ResultCode KReadableEvent::Reset() {
47 KScopedSchedulerLock lk{kernel};
48
49 R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState);
50
51 is_signaled = false;
48 52
49 return RESULT_SUCCESS; 53 return RESULT_SUCCESS;
50} 54}
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index 39eedc411..e6f0fd900 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -1,4 +1,4 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2021 yuzu emulator team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
@@ -6,25 +6,20 @@
6 6
7#include "core/hle/kernel/k_synchronization_object.h" 7#include "core/hle/kernel/k_synchronization_object.h"
8#include "core/hle/kernel/object.h" 8#include "core/hle/kernel/object.h"
9 9#include "core/hle/result.h"
10union ResultCode;
11 10
12namespace Kernel { 11namespace Kernel {
13 12
14class KernelCore; 13class KernelCore;
15class KWritableEvent; 14class KEvent;
16 15
17class KReadableEvent final : public KSynchronizationObject { 16class KReadableEvent final : public KSynchronizationObject {
18 friend class KWritableEvent;
19
20public: 17public:
18 explicit KReadableEvent(KernelCore& kernel, std::string&& name);
21 ~KReadableEvent() override; 19 ~KReadableEvent() override;
22 20
23 std::string GetTypeName() const override { 21 std::string GetTypeName() const override {
24 return "ReadableEvent"; 22 return "KReadableEvent";
25 }
26 std::string GetName() const override {
27 return name;
28 } 23 }
29 24
30 static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent; 25 static constexpr HandleType HANDLE_TYPE = HandleType::ReadableEvent;
@@ -32,28 +27,25 @@ public:
32 return HANDLE_TYPE; 27 return HANDLE_TYPE;
33 } 28 }
34 29
35 /// Unconditionally clears the readable event's state. 30 KEvent* GetParent() const {
36 void Clear(); 31 return parent;
37 32 }
38 /// Clears the readable event's state if and only if it
39 /// has already been signaled.
40 ///
41 /// @pre The event must be in a signaled state. If this event
42 /// is in an unsignaled state and this function is called,
43 /// then ERR_INVALID_STATE will be returned.
44 ResultCode Reset();
45 33
46 void Signal(); 34 void Initialize(KEvent* parent_) {
35 is_signaled = false;
36 parent = parent_;
37 }
47 38
48 bool IsSignaled() const override; 39 bool IsSignaled() const override;
49
50 void Finalize() override {} 40 void Finalize() override {}
51 41
52private: 42 ResultCode Signal();
53 explicit KReadableEvent(KernelCore& kernel); 43 ResultCode Clear();
44 ResultCode Reset();
54 45
46private:
55 bool is_signaled{}; 47 bool is_signaled{};
56 std::string name; ///< Name of event (optional) 48 KEvent* parent{};
57}; 49};
58 50
59} // namespace Kernel 51} // namespace Kernel
diff --git a/src/core/hle/kernel/k_synchronization_object.cpp b/src/core/hle/kernel/k_synchronization_object.cpp
index a3b34f82f..140cc46a7 100644
--- a/src/core/hle/kernel/k_synchronization_object.cpp
+++ b/src/core/hle/kernel/k_synchronization_object.cpp
@@ -132,6 +132,9 @@ ResultCode KSynchronizationObject::Wait(KernelCore& kernel, s32* out_index,
132 132
133KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {} 133KSynchronizationObject::KSynchronizationObject(KernelCore& kernel) : Object{kernel} {}
134 134
135KSynchronizationObject::KSynchronizationObject(KernelCore& kernel, std::string&& name)
136 : Object{kernel, std::move(name)} {}
137
135KSynchronizationObject::~KSynchronizationObject() = default; 138KSynchronizationObject::~KSynchronizationObject() = default;
136 139
137void KSynchronizationObject::NotifyAvailable(ResultCode result) { 140void KSynchronizationObject::NotifyAvailable(ResultCode result) {
diff --git a/src/core/hle/kernel/k_synchronization_object.h b/src/core/hle/kernel/k_synchronization_object.h
index f65c71c28..5803718fd 100644
--- a/src/core/hle/kernel/k_synchronization_object.h
+++ b/src/core/hle/kernel/k_synchronization_object.h
@@ -33,6 +33,7 @@ public:
33 33
34protected: 34protected:
35 explicit KSynchronizationObject(KernelCore& kernel); 35 explicit KSynchronizationObject(KernelCore& kernel);
36 explicit KSynchronizationObject(KernelCore& kernel, std::string&& name);
36 virtual ~KSynchronizationObject(); 37 virtual ~KSynchronizationObject();
37 38
38 void NotifyAvailable(ResultCode result); 39 void NotifyAvailable(ResultCode result);
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
index d2857b4c3..25c52edb2 100644
--- a/src/core/hle/kernel/k_writable_event.cpp
+++ b/src/core/hle/kernel/k_writable_event.cpp
@@ -1,41 +1,27 @@
1// Copyright 2014 Citra Emulator Project 1// Copyright 2021 yuzu emulator team
2// Licensed under GPLv2 or any later version 2// Licensed under GPLv2 or any later version
3// Refer to the license.txt file included. 3// Refer to the license.txt file included.
4 4
5#include <algorithm> 5#include "core/hle/kernel/k_event.h"
6#include "common/assert.h"
7#include "core/hle/kernel/k_readable_event.h" 6#include "core/hle/kernel/k_readable_event.h"
8#include "core/hle/kernel/k_thread.h"
9#include "core/hle/kernel/k_writable_event.h" 7#include "core/hle/kernel/k_writable_event.h"
10#include "core/hle/kernel/kernel.h"
11#include "core/hle/kernel/object.h"
12 8
13namespace Kernel { 9namespace Kernel {
14 10
15KWritableEvent::KWritableEvent(KernelCore& kernel) : Object{kernel} {} 11KWritableEvent::KWritableEvent(KernelCore& kernel, std::string&& name)
12 : Object{kernel, std::move(name)} {}
16KWritableEvent::~KWritableEvent() = default; 13KWritableEvent::~KWritableEvent() = default;
17 14
18EventPair KWritableEvent::CreateEventPair(KernelCore& kernel, std::string name) { 15void KWritableEvent::Initialize(KEvent* parent_) {
19 std::shared_ptr<KWritableEvent> writable_event(new KWritableEvent(kernel)); 16 parent = parent_;
20 std::shared_ptr<KReadableEvent> readable_event(new KReadableEvent(kernel));
21
22 writable_event->name = name + ":Writable";
23 writable_event->readable = readable_event;
24 readable_event->name = name + ":Readable";
25
26 return {std::move(readable_event), std::move(writable_event)};
27}
28
29std::shared_ptr<KReadableEvent> KWritableEvent::GetReadableEvent() const {
30 return readable;
31} 17}
32 18
33void KWritableEvent::Signal() { 19ResultCode KWritableEvent::Signal() {
34 readable->Signal(); 20 return parent->GetReadableEvent()->Signal();
35} 21}
36 22
37void KWritableEvent::Clear() { 23ResultCode KWritableEvent::Clear() {
38 readable->Clear(); 24 return parent->GetReadableEvent()->Clear();
39} 25}
40 26
41} // namespace Kernel 27} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h
index ad5514b52..518f5448d 100644
--- a/src/core/hle/kernel/k_writable_event.h
+++ b/src/core/hle/kernel/k_writable_event.h
@@ -4,37 +4,21 @@
4 4
5#pragma once 5#pragma once
6 6
7#include <memory>
8
9#include "core/hle/kernel/object.h" 7#include "core/hle/kernel/object.h"
8#include "core/hle/result.h"
10 9
11namespace Kernel { 10namespace Kernel {
12 11
13class KernelCore; 12class KernelCore;
14class KReadableEvent; 13class KEvent;
15class KWritableEvent;
16
17struct EventPair {
18 std::shared_ptr<KReadableEvent> readable;
19 std::shared_ptr<KWritableEvent> writable;
20};
21 14
22class KWritableEvent final : public Object { 15class KWritableEvent final : public Object {
23public: 16public:
17 explicit KWritableEvent(KernelCore& kernel, std::string&& name);
24 ~KWritableEvent() override; 18 ~KWritableEvent() override;
25 19
26 /**
27 * Creates an event
28 * @param kernel The kernel instance to create this event under.
29 * @param name Optional name of event
30 */
31 static EventPair CreateEventPair(KernelCore& kernel, std::string name = "Unknown");
32
33 std::string GetTypeName() const override { 20 std::string GetTypeName() const override {
34 return "WritableEvent"; 21 return "KWritableEvent";
35 }
36 std::string GetName() const override {
37 return name;
38 } 22 }
39 23
40 static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent; 24 static constexpr HandleType HANDLE_TYPE = HandleType::WritableEvent;
@@ -42,19 +26,19 @@ public:
42 return HANDLE_TYPE; 26 return HANDLE_TYPE;
43 } 27 }
44 28
45 std::shared_ptr<KReadableEvent> GetReadableEvent() const; 29 void Initialize(KEvent* parent_);
46
47 void Signal();
48 void Clear();
49 30
50 void Finalize() override {} 31 void Finalize() override {}
51 32
52private: 33 ResultCode Signal();
53 explicit KWritableEvent(KernelCore& kernel); 34 ResultCode Clear();
54 35
55 std::shared_ptr<KReadableEvent> readable; 36 KEvent* GetParent() const {
37 return parent;
38 }
56 39
57 std::string name; ///< Name of event (optional) 40private:
41 KEvent* parent{};
58}; 42};
59 43
60} // namespace Kernel 44} // namespace Kernel
diff --git a/src/core/hle/kernel/object.cpp b/src/core/hle/kernel/object.cpp
index 2c571792b..d7f40c403 100644
--- a/src/core/hle/kernel/object.cpp
+++ b/src/core/hle/kernel/object.cpp
@@ -8,7 +8,10 @@
8 8
9namespace Kernel { 9namespace Kernel {
10 10
11Object::Object(KernelCore& kernel) : kernel{kernel}, object_id{kernel.CreateNewObjectID()} {} 11Object::Object(KernelCore& kernel_)
12 : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{"[UNKNOWN KERNEL OBJECT]"} {}
13Object::Object(KernelCore& kernel_, std::string&& name_)
14 : kernel{kernel_}, object_id{kernel_.CreateNewObjectID()}, name{std::move(name_)} {}
12Object::~Object() = default; 15Object::~Object() = default;
13 16
14bool Object::IsWaitable() const { 17bool Object::IsWaitable() const {
@@ -21,6 +24,7 @@ bool Object::IsWaitable() const {
21 return true; 24 return true;
22 25
23 case HandleType::Unknown: 26 case HandleType::Unknown:
27 case HandleType::Event:
24 case HandleType::WritableEvent: 28 case HandleType::WritableEvent:
25 case HandleType::SharedMemory: 29 case HandleType::SharedMemory:
26 case HandleType::TransferMemory: 30 case HandleType::TransferMemory:
diff --git a/src/core/hle/kernel/object.h b/src/core/hle/kernel/object.h
index be7fcb5fb..501e58b33 100644
--- a/src/core/hle/kernel/object.h
+++ b/src/core/hle/kernel/object.h
@@ -18,6 +18,7 @@ using Handle = u32;
18 18
19enum class HandleType : u32 { 19enum class HandleType : u32 {
20 Unknown, 20 Unknown,
21 Event,
21 WritableEvent, 22 WritableEvent,
22 ReadableEvent, 23 ReadableEvent,
23 SharedMemory, 24 SharedMemory,
@@ -34,7 +35,8 @@ enum class HandleType : u32 {
34 35
35class Object : NonCopyable, public std::enable_shared_from_this<Object> { 36class Object : NonCopyable, public std::enable_shared_from_this<Object> {
36public: 37public:
37 explicit Object(KernelCore& kernel); 38 explicit Object(KernelCore& kernel_);
39 explicit Object(KernelCore& kernel_, std::string&& name_);
38 virtual ~Object(); 40 virtual ~Object();
39 41
40 /// Returns a unique identifier for the object. For debugging purposes only. 42 /// Returns a unique identifier for the object. For debugging purposes only.
@@ -46,7 +48,7 @@ public:
46 return "[BAD KERNEL OBJECT TYPE]"; 48 return "[BAD KERNEL OBJECT TYPE]";
47 } 49 }
48 virtual std::string GetName() const { 50 virtual std::string GetName() const {
49 return "[UNKNOWN KERNEL OBJECT]"; 51 return name;
50 } 52 }
51 virtual HandleType GetHandleType() const = 0; 53 virtual HandleType GetHandleType() const = 0;
52 54
@@ -69,6 +71,7 @@ protected:
69 71
70private: 72private:
71 std::atomic<u32> object_id{0}; 73 std::atomic<u32> object_id{0};
74 std::string name;
72}; 75};
73 76
74template <typename T> 77template <typename T>
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index f94eecbb8..9d036f45d 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -26,6 +26,7 @@
26#include "core/hle/kernel/handle_table.h" 26#include "core/hle/kernel/handle_table.h"
27#include "core/hle/kernel/k_address_arbiter.h" 27#include "core/hle/kernel/k_address_arbiter.h"
28#include "core/hle/kernel/k_condition_variable.h" 28#include "core/hle/kernel/k_condition_variable.h"
29#include "core/hle/kernel/k_event.h"
29#include "core/hle/kernel/k_readable_event.h" 30#include "core/hle/kernel/k_readable_event.h"
30#include "core/hle/kernel/k_resource_limit.h" 31#include "core/hle/kernel/k_resource_limit.h"
31#include "core/hle/kernel/k_scheduler.h" 32#include "core/hle/kernel/k_scheduler.h"
@@ -1870,18 +1871,18 @@ static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle
1870 LOG_DEBUG(Kernel_SVC, "called"); 1871 LOG_DEBUG(Kernel_SVC, "called");
1871 1872
1872 auto& kernel = system.Kernel(); 1873 auto& kernel = system.Kernel();
1873 const auto [readable_event, writable_event] = 1874 const auto event = KEvent::Create(kernel, "CreateEvent");
1874 KWritableEvent::CreateEventPair(kernel, "CreateEvent"); 1875 event->Initialize();
1875 1876
1876 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); 1877 HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable();
1877 1878
1878 const auto write_create_result = handle_table.Create(writable_event); 1879 const auto write_create_result = handle_table.Create(event->GetWritableEvent());
1879 if (write_create_result.Failed()) { 1880 if (write_create_result.Failed()) {
1880 return write_create_result.Code(); 1881 return write_create_result.Code();
1881 } 1882 }
1882 *write_handle = *write_create_result; 1883 *write_handle = *write_create_result;
1883 1884
1884 const auto read_create_result = handle_table.Create(readable_event); 1885 const auto read_create_result = handle_table.Create(event->GetReadableEvent());
1885 if (read_create_result.Failed()) { 1886 if (read_create_result.Failed()) {
1886 handle_table.Close(*write_create_result); 1887 handle_table.Close(*write_create_result);
1887 return read_create_result.Code(); 1888 return read_create_result.Code();