diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/k_readable_event.cpp | 1 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.cpp | 19 | ||||
| -rw-r--r-- | src/core/hle/kernel/process.h | 2 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 135 | ||||
| -rw-r--r-- | src/core/hle/kernel/svc_results.h | 1 |
5 files changed, 89 insertions, 69 deletions
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp index 0fa895c56..cd15aa529 100644 --- a/src/core/hle/kernel/k_readable_event.cpp +++ b/src/core/hle/kernel/k_readable_event.cpp | |||
| @@ -49,7 +49,6 @@ ResultCode KReadableEvent::Reset() { | |||
| 49 | R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState); | 49 | R_UNLESS_NOLOG(is_signaled, Svc::ResultInvalidState); |
| 50 | 50 | ||
| 51 | is_signaled = false; | 51 | is_signaled = false; |
| 52 | |||
| 53 | return RESULT_SUCCESS; | 52 | return RESULT_SUCCESS; |
| 54 | } | 53 | } |
| 55 | 54 | ||
diff --git a/src/core/hle/kernel/process.cpp b/src/core/hle/kernel/process.cpp index afdb27c54..2286b292d 100644 --- a/src/core/hle/kernel/process.cpp +++ b/src/core/hle/kernel/process.cpp | |||
| @@ -23,6 +23,7 @@ | |||
| 23 | #include "core/hle/kernel/memory/page_table.h" | 23 | #include "core/hle/kernel/memory/page_table.h" |
| 24 | #include "core/hle/kernel/memory/slab_heap.h" | 24 | #include "core/hle/kernel/memory/slab_heap.h" |
| 25 | #include "core/hle/kernel/process.h" | 25 | #include "core/hle/kernel/process.h" |
| 26 | #include "core/hle/kernel/svc_results.h" | ||
| 26 | #include "core/hle/lock.h" | 27 | #include "core/hle/lock.h" |
| 27 | #include "core/memory.h" | 28 | #include "core/memory.h" |
| 28 | #include "core/settings.h" | 29 | #include "core/settings.h" |
| @@ -241,18 +242,16 @@ void Process::UnregisterThread(const KThread* thread) { | |||
| 241 | thread_list.remove(thread); | 242 | thread_list.remove(thread); |
| 242 | } | 243 | } |
| 243 | 244 | ||
| 244 | ResultCode Process::ClearSignalState() { | 245 | ResultCode Process::Reset() { |
| 245 | KScopedSchedulerLock lock(system.Kernel()); | 246 | // Lock the process and the scheduler. |
| 246 | if (status == ProcessStatus::Exited) { | 247 | KScopedLightLock lk(state_lock); |
| 247 | LOG_ERROR(Kernel, "called on a terminated process instance."); | 248 | KScopedSchedulerLock sl{kernel}; |
| 248 | return ERR_INVALID_STATE; | ||
| 249 | } | ||
| 250 | 249 | ||
| 251 | if (!is_signaled) { | 250 | // Validate that we're in a state that we can reset. |
| 252 | LOG_ERROR(Kernel, "called on a process instance that isn't signaled."); | 251 | R_UNLESS(status != ProcessStatus::Exited, Svc::ResultInvalidState); |
| 253 | return ERR_INVALID_STATE; | 252 | R_UNLESS(is_signaled, Svc::ResultInvalidState); |
| 254 | } | ||
| 255 | 253 | ||
| 254 | // Clear signaled. | ||
| 256 | is_signaled = false; | 255 | is_signaled = false; |
| 257 | return RESULT_SUCCESS; | 256 | return RESULT_SUCCESS; |
| 258 | } | 257 | } |
diff --git a/src/core/hle/kernel/process.h b/src/core/hle/kernel/process.h index c8af76ce8..320b0f347 100644 --- a/src/core/hle/kernel/process.h +++ b/src/core/hle/kernel/process.h | |||
| @@ -312,7 +312,7 @@ public: | |||
| 312 | /// @pre The process must be in a signaled state. If this is called on a | 312 | /// @pre The process must be in a signaled state. If this is called on a |
| 313 | /// process instance that is not signaled, ERR_INVALID_STATE will be | 313 | /// process instance that is not signaled, ERR_INVALID_STATE will be |
| 314 | /// returned. | 314 | /// returned. |
| 315 | ResultCode ClearSignalState(); | 315 | ResultCode Reset(); |
| 316 | 316 | ||
| 317 | /** | 317 | /** |
| 318 | * Loads process-specifics configuration info with metadata provided | 318 | * Loads process-specifics configuration info with metadata provided |
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp index 9d036f45d..edf208eff 100644 --- a/src/core/hle/kernel/svc.cpp +++ b/src/core/hle/kernel/svc.cpp | |||
| @@ -14,6 +14,7 @@ | |||
| 14 | #include "common/fiber.h" | 14 | #include "common/fiber.h" |
| 15 | #include "common/logging/log.h" | 15 | #include "common/logging/log.h" |
| 16 | #include "common/microprofile.h" | 16 | #include "common/microprofile.h" |
| 17 | #include "common/scope_exit.h" | ||
| 17 | #include "common/string_util.h" | 18 | #include "common/string_util.h" |
| 18 | #include "core/arm/exclusive_monitor.h" | 19 | #include "core/arm/exclusive_monitor.h" |
| 19 | #include "core/core.h" | 20 | #include "core/core.h" |
| @@ -1726,20 +1727,28 @@ static ResultCode CloseHandle32(Core::System& system, Handle handle) { | |||
| 1726 | static ResultCode ResetSignal(Core::System& system, Handle handle) { | 1727 | static ResultCode ResetSignal(Core::System& system, Handle handle) { |
| 1727 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); | 1728 | LOG_DEBUG(Kernel_SVC, "called handle 0x{:08X}", handle); |
| 1728 | 1729 | ||
| 1730 | // Get the current handle table. | ||
| 1729 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1731 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1730 | 1732 | ||
| 1731 | auto event = handle_table.Get<KReadableEvent>(handle); | 1733 | // Try to reset as readable event. |
| 1732 | if (event) { | 1734 | { |
| 1733 | return event->Reset(); | 1735 | auto readable_event = handle_table.Get<KReadableEvent>(handle); |
| 1736 | if (readable_event) { | ||
| 1737 | return readable_event->Reset(); | ||
| 1738 | } | ||
| 1734 | } | 1739 | } |
| 1735 | 1740 | ||
| 1736 | auto process = handle_table.Get<Process>(handle); | 1741 | // Try to reset as process. |
| 1737 | if (process) { | 1742 | { |
| 1738 | return process->ClearSignalState(); | 1743 | auto process = handle_table.Get<Process>(handle); |
| 1744 | if (process) { | ||
| 1745 | return process->Reset(); | ||
| 1746 | } | ||
| 1739 | } | 1747 | } |
| 1740 | 1748 | ||
| 1741 | LOG_ERROR(Kernel_SVC, "Invalid handle (0x{:08X})", handle); | 1749 | LOG_ERROR(Kernel_SVC, "invalid handle (0x{:08X})", handle); |
| 1742 | return ERR_INVALID_HANDLE; | 1750 | |
| 1751 | return Svc::ResultInvalidHandle; | ||
| 1743 | } | 1752 | } |
| 1744 | 1753 | ||
| 1745 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { | 1754 | static ResultCode ResetSignal32(Core::System& system, Handle handle) { |
| @@ -1867,80 +1876,92 @@ static ResultCode SetThreadCoreMask32(Core::System& system, Handle thread_handle | |||
| 1867 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); | 1876 | return SetThreadCoreMask(system, thread_handle, core_id, affinity_mask); |
| 1868 | } | 1877 | } |
| 1869 | 1878 | ||
| 1870 | static ResultCode CreateEvent(Core::System& system, Handle* write_handle, Handle* read_handle) { | 1879 | static ResultCode SignalEvent(Core::System& system, Handle event_handle) { |
| 1871 | LOG_DEBUG(Kernel_SVC, "called"); | 1880 | LOG_DEBUG(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1872 | 1881 | ||
| 1873 | auto& kernel = system.Kernel(); | 1882 | // Get the current handle table. |
| 1874 | const auto event = KEvent::Create(kernel, "CreateEvent"); | 1883 | const HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1875 | event->Initialize(); | ||
| 1876 | 1884 | ||
| 1877 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | 1885 | // Get the writable event. |
| 1886 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); | ||
| 1887 | R_UNLESS(writable_event, Svc::ResultInvalidHandle); | ||
| 1878 | 1888 | ||
| 1879 | const auto write_create_result = handle_table.Create(event->GetWritableEvent()); | 1889 | return writable_event->Signal(); |
| 1880 | if (write_create_result.Failed()) { | ||
| 1881 | return write_create_result.Code(); | ||
| 1882 | } | ||
| 1883 | *write_handle = *write_create_result; | ||
| 1884 | |||
| 1885 | const auto read_create_result = handle_table.Create(event->GetReadableEvent()); | ||
| 1886 | if (read_create_result.Failed()) { | ||
| 1887 | handle_table.Close(*write_create_result); | ||
| 1888 | return read_create_result.Code(); | ||
| 1889 | } | ||
| 1890 | *read_handle = *read_create_result; | ||
| 1891 | |||
| 1892 | LOG_DEBUG(Kernel_SVC, | ||
| 1893 | "successful. Writable event handle=0x{:08X}, Readable event handle=0x{:08X}", | ||
| 1894 | *write_create_result, *read_create_result); | ||
| 1895 | return RESULT_SUCCESS; | ||
| 1896 | } | 1890 | } |
| 1897 | 1891 | ||
| 1898 | static ResultCode CreateEvent32(Core::System& system, Handle* write_handle, Handle* read_handle) { | 1892 | static ResultCode SignalEvent32(Core::System& system, Handle event_handle) { |
| 1899 | return CreateEvent(system, write_handle, read_handle); | 1893 | return SignalEvent(system, event_handle); |
| 1900 | } | 1894 | } |
| 1901 | 1895 | ||
| 1902 | static ResultCode ClearEvent(Core::System& system, Handle handle) { | 1896 | static ResultCode ClearEvent(Core::System& system, Handle event_handle) { |
| 1903 | LOG_TRACE(Kernel_SVC, "called, event=0x{:08X}", handle); | 1897 | LOG_TRACE(Kernel_SVC, "called, event_handle=0x{:08X}", event_handle); |
| 1904 | 1898 | ||
| 1899 | // Get the current handle table. | ||
| 1905 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1900 | const auto& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); |
| 1906 | 1901 | ||
| 1907 | auto writable_event = handle_table.Get<KWritableEvent>(handle); | 1902 | // Try to clear the writable event. |
| 1908 | if (writable_event) { | 1903 | { |
| 1909 | writable_event->Clear(); | 1904 | auto writable_event = handle_table.Get<KWritableEvent>(event_handle); |
| 1910 | return RESULT_SUCCESS; | 1905 | if (writable_event) { |
| 1906 | return writable_event->Clear(); | ||
| 1907 | } | ||
| 1911 | } | 1908 | } |
| 1912 | 1909 | ||
| 1913 | auto readable_event = handle_table.Get<KReadableEvent>(handle); | 1910 | // Try to clear the readable event. |
| 1914 | if (readable_event) { | 1911 | { |
| 1915 | readable_event->Clear(); | 1912 | auto readable_event = handle_table.Get<KReadableEvent>(event_handle); |
| 1916 | return RESULT_SUCCESS; | 1913 | if (readable_event) { |
| 1914 | return readable_event->Clear(); | ||
| 1915 | } | ||
| 1917 | } | 1916 | } |
| 1918 | 1917 | ||
| 1919 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, handle=0x{:08X}", handle); | 1918 | LOG_ERROR(Kernel_SVC, "Event handle does not exist, event_handle=0x{:08X}", event_handle); |
| 1920 | return ERR_INVALID_HANDLE; | 1919 | |
| 1920 | return Svc::ResultInvalidHandle; | ||
| 1921 | } | 1921 | } |
| 1922 | 1922 | ||
| 1923 | static ResultCode ClearEvent32(Core::System& system, Handle handle) { | 1923 | static ResultCode ClearEvent32(Core::System& system, Handle event_handle) { |
| 1924 | return ClearEvent(system, handle); | 1924 | return ClearEvent(system, event_handle); |
| 1925 | } | 1925 | } |
| 1926 | 1926 | ||
| 1927 | static ResultCode SignalEvent(Core::System& system, Handle handle) { | 1927 | static ResultCode CreateEvent(Core::System& system, Handle* out_write, Handle* out_read) { |
| 1928 | LOG_DEBUG(Kernel_SVC, "called. Handle=0x{:08X}", handle); | 1928 | LOG_DEBUG(Kernel_SVC, "called"); |
| 1929 | 1929 | ||
| 1930 | HandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); | 1930 | // Get the kernel reference and handle table. |
| 1931 | auto writable_event = handle_table.Get<KWritableEvent>(handle); | 1931 | auto& kernel = system.Kernel(); |
| 1932 | HandleTable& handle_table = kernel.CurrentProcess()->GetHandleTable(); | ||
| 1932 | 1933 | ||
| 1933 | if (!writable_event) { | 1934 | // Create a new event. |
| 1934 | LOG_ERROR(Kernel_SVC, "Non-existent writable event handle used (0x{:08X})", handle); | 1935 | const auto event = KEvent::Create(kernel, "CreateEvent"); |
| 1935 | return ERR_INVALID_HANDLE; | 1936 | R_UNLESS(event != nullptr, Svc::ResultOutOfResource); |
| 1937 | |||
| 1938 | // Initialize the event. | ||
| 1939 | event->Initialize(); | ||
| 1940 | |||
| 1941 | // Add the writable event to the handle table. | ||
| 1942 | const auto write_create_result = handle_table.Create(event->GetWritableEvent()); | ||
| 1943 | if (write_create_result.Failed()) { | ||
| 1944 | return write_create_result.Code(); | ||
| 1945 | } | ||
| 1946 | *out_write = *write_create_result; | ||
| 1947 | |||
| 1948 | // Add the writable event to the handle table. | ||
| 1949 | auto handle_guard = SCOPE_GUARD({ handle_table.Close(*write_create_result); }); | ||
| 1950 | |||
| 1951 | // Add the readable event to the handle table. | ||
| 1952 | const auto read_create_result = handle_table.Create(event->GetReadableEvent()); | ||
| 1953 | if (read_create_result.Failed()) { | ||
| 1954 | return read_create_result.Code(); | ||
| 1936 | } | 1955 | } |
| 1956 | *out_read = *read_create_result; | ||
| 1937 | 1957 | ||
| 1938 | writable_event->Signal(); | 1958 | // We succeeded. |
| 1959 | handle_guard.Cancel(); | ||
| 1939 | return RESULT_SUCCESS; | 1960 | return RESULT_SUCCESS; |
| 1940 | } | 1961 | } |
| 1941 | 1962 | ||
| 1942 | static ResultCode SignalEvent32(Core::System& system, Handle handle) { | 1963 | static ResultCode CreateEvent32(Core::System& system, Handle* out_write, Handle* out_read) { |
| 1943 | return SignalEvent(system, handle); | 1964 | return CreateEvent(system, out_write, out_read); |
| 1944 | } | 1965 | } |
| 1945 | 1966 | ||
| 1946 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { | 1967 | static ResultCode GetProcessInfo(Core::System& system, u64* out, Handle process_handle, u32 type) { |
diff --git a/src/core/hle/kernel/svc_results.h b/src/core/hle/kernel/svc_results.h index 7b897fbce..204cd989d 100644 --- a/src/core/hle/kernel/svc_results.h +++ b/src/core/hle/kernel/svc_results.h | |||
| @@ -11,6 +11,7 @@ namespace Kernel::Svc { | |||
| 11 | constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; | 11 | constexpr ResultCode ResultNoSynchronizationObject{ErrorModule::Kernel, 57}; |
| 12 | constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; | 12 | constexpr ResultCode ResultTerminationRequested{ErrorModule::Kernel, 59}; |
| 13 | constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; | 13 | constexpr ResultCode ResultInvalidAddress{ErrorModule::Kernel, 102}; |
| 14 | constexpr ResultCode ResultOutOfResource{ErrorModule::Kernel, 103}; | ||
| 14 | constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; | 15 | constexpr ResultCode ResultInvalidCurrentMemory{ErrorModule::Kernel, 106}; |
| 15 | constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; | 16 | constexpr ResultCode ResultInvalidPriority{ErrorModule::Kernel, 112}; |
| 16 | constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; | 17 | constexpr ResultCode ResultInvalidCoreId{ErrorModule::Kernel, 113}; |