diff options
| author | 2021-01-31 16:55:11 -0800 | |
|---|---|---|
| committer | 2021-02-05 14:03:36 -0800 | |
| commit | eba3c59a611962a1b019a5edfbc16c8d6db58be9 (patch) | |
| tree | 01bf9363df380825ad1b13f22e8944ffbc460682 /src/core/hle/kernel/svc.cpp | |
| parent | common: scope_exit: Add a cancellable ScopeExit macro. (diff) | |
| download | yuzu-eba3c59a611962a1b019a5edfbc16c8d6db58be9.tar.gz yuzu-eba3c59a611962a1b019a5edfbc16c8d6db58be9.tar.xz yuzu-eba3c59a611962a1b019a5edfbc16c8d6db58be9.zip | |
hle: kernel: svc: Cleanup KEvent/KReadableEvent/KWritableEvent SVCs.
Diffstat (limited to 'src/core/hle/kernel/svc.cpp')
| -rw-r--r-- | src/core/hle/kernel/svc.cpp | 135 |
1 files changed, 78 insertions, 57 deletions
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) { |