summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/audio_core/in/audio_in_system.cpp6
-rw-r--r--src/audio_core/out/audio_out_system.cpp6
-rw-r--r--src/audio_core/renderer/system.cpp4
-rw-r--r--src/audio_core/sink/sdl2_sink.cpp4
-rw-r--r--src/audio_core/sink/sink_details.cpp4
-rw-r--r--src/common/CMakeLists.txt6
-rw-r--r--src/common/fixed_point.h97
-rw-r--r--src/core/CMakeLists.txt2
-rw-r--r--src/core/arm/dynarmic/arm_dynarmic_64.cpp1
-rw-r--r--src/core/hid/irs_types.h20
-rw-r--r--src/core/hle/ipc_helpers.h3
-rw-r--r--src/core/hle/kernel/hle_ipc.h2
-rw-r--r--src/core/hle/kernel/k_class_token.cpp12
-rw-r--r--src/core/hle/kernel/k_class_token.h1
-rw-r--r--src/core/hle/kernel/k_client_session.cpp5
-rw-r--r--src/core/hle/kernel/k_client_session.h3
-rw-r--r--src/core/hle/kernel/k_event.cpp44
-rw-r--r--src/core/hle/kernel/k_event.h31
-rw-r--r--src/core/hle/kernel/k_readable_event.cpp33
-rw-r--r--src/core/hle/kernel/k_readable_event.h17
-rw-r--r--src/core/hle/kernel/k_server_session.cpp243
-rw-r--r--src/core/hle/kernel/k_server_session.h37
-rw-r--r--src/core/hle/kernel/k_writable_event.cpp35
-rw-r--r--src/core/hle/kernel/k_writable_event.h39
-rw-r--r--src/core/hle/kernel/kernel.h4
-rw-r--r--src/core/hle/kernel/svc.cpp195
-rw-r--r--src/core/hle/kernel/svc_wrap.h32
-rw-r--r--src/core/hle/service/acc/async_context.cpp2
-rw-r--r--src/core/hle/service/am/am.cpp12
-rw-r--r--src/core/hle/service/am/applets/applets.cpp10
-rw-r--r--src/core/hle/service/audio/audren_u.cpp4
-rw-r--r--src/core/hle/service/bcat/backend/backend.cpp2
-rw-r--r--src/core/hle/service/hid/controllers/npad.cpp5
-rw-r--r--src/core/hle/service/hid/controllers/palma.cpp16
-rw-r--r--src/core/hle/service/hid/hid.cpp2
-rw-r--r--src/core/hle/service/hid/hidbus/ringcon.cpp8
-rw-r--r--src/core/hle/service/hid/irsensor/pointing_processor.h4
-rw-r--r--src/core/hle/service/kernel_helpers.cpp5
-rw-r--r--src/core/hle/service/ldn/ldn.cpp2
-rw-r--r--src/core/hle/service/nfp/nfp_device.cpp6
-rw-r--r--src/core/hle/service/nim/nim.cpp4
-rw-r--r--src/core/hle/service/ns/ns.cpp30
-rw-r--r--src/core/hle/service/ns/ns.h3
-rw-r--r--src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp5
-rw-r--r--src/core/hle/service/nvdrv/nvdrv.cpp1
-rw-r--r--src/core/hle/service/nvdrv/nvdrv_interface.h4
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.cpp9
-rw-r--r--src/core/hle/service/nvflinger/buffer_queue_producer.h1
-rw-r--r--src/core/hle/service/nvflinger/nvflinger.h1
-rw-r--r--src/core/hle/service/ptm/psm.cpp6
-rw-r--r--src/core/hle/service/ptm/ts.cpp15
-rw-r--r--src/core/hle/service/ptm/ts.h1
-rw-r--r--src/core/hle/service/set/set_sys.cpp79
-rw-r--r--src/core/hle/service/set/set_sys.h2
-rw-r--r--src/core/hle/service/sm/sm.cpp3
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.cpp10
-rw-r--r--src/core/hle/service/time/system_clock_context_update_callback.h6
-rw-r--r--src/core/hle/service/vi/display/vi_display.cpp3
-rw-r--r--src/core/hle/service/vi/vi_results.h2
-rw-r--r--src/video_core/texture_cache/descriptor_table.h2
-rw-r--r--src/video_core/texture_cache/texture_cache.h8
-rw-r--r--src/yuzu/main.cpp2
62 files changed, 797 insertions, 364 deletions
diff --git a/src/audio_core/in/audio_in_system.cpp b/src/audio_core/in/audio_in_system.cpp
index e7f918a47..6b7e6715c 100644
--- a/src/audio_core/in/audio_in_system.cpp
+++ b/src/audio_core/in/audio_in_system.cpp
@@ -23,7 +23,7 @@ System::~System() {
23void System::Finalize() { 23void System::Finalize() {
24 Stop(); 24 Stop();
25 session->Finalize(); 25 session->Finalize();
26 buffer_event->GetWritableEvent().Signal(); 26 buffer_event->Signal();
27} 27}
28 28
29void System::StartSession() { 29void System::StartSession() {
@@ -142,7 +142,7 @@ void System::ReleaseBuffers() {
142 142
143 if (signal) { 143 if (signal) {
144 // Signal if any buffer was released, or if none are registered, we need more. 144 // Signal if any buffer was released, or if none are registered, we need more.
145 buffer_event->GetWritableEvent().Signal(); 145 buffer_event->Signal();
146 } 146 }
147} 147}
148 148
@@ -159,7 +159,7 @@ bool System::FlushAudioInBuffers() {
159 buffers.FlushBuffers(buffers_released); 159 buffers.FlushBuffers(buffers_released);
160 160
161 if (buffers_released > 0) { 161 if (buffers_released > 0) {
162 buffer_event->GetWritableEvent().Signal(); 162 buffer_event->Signal();
163 } 163 }
164 return true; 164 return true;
165} 165}
diff --git a/src/audio_core/out/audio_out_system.cpp b/src/audio_core/out/audio_out_system.cpp
index 8b907590a..48a801923 100644
--- a/src/audio_core/out/audio_out_system.cpp
+++ b/src/audio_core/out/audio_out_system.cpp
@@ -24,7 +24,7 @@ System::~System() {
24void System::Finalize() { 24void System::Finalize() {
25 Stop(); 25 Stop();
26 session->Finalize(); 26 session->Finalize();
27 buffer_event->GetWritableEvent().Signal(); 27 buffer_event->Signal();
28} 28}
29 29
30std::string_view System::GetDefaultOutputDeviceName() const { 30std::string_view System::GetDefaultOutputDeviceName() const {
@@ -141,7 +141,7 @@ void System::ReleaseBuffers() {
141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)}; 141 bool signal{buffers.ReleaseBuffers(system.CoreTiming(), *session)};
142 if (signal) { 142 if (signal) {
143 // Signal if any buffer was released, or if none are registered, we need more. 143 // Signal if any buffer was released, or if none are registered, we need more.
144 buffer_event->GetWritableEvent().Signal(); 144 buffer_event->Signal();
145 } 145 }
146} 146}
147 147
@@ -158,7 +158,7 @@ bool System::FlushAudioOutBuffers() {
158 buffers.FlushBuffers(buffers_released); 158 buffers.FlushBuffers(buffers_released);
159 159
160 if (buffers_released > 0) { 160 if (buffers_released > 0) {
161 buffer_event->GetWritableEvent().Signal(); 161 buffer_event->Signal();
162 } 162 }
163 return true; 163 return true;
164} 164}
diff --git a/src/audio_core/renderer/system.cpp b/src/audio_core/renderer/system.cpp
index 7a217969e..bde794cd1 100644
--- a/src/audio_core/renderer/system.cpp
+++ b/src/audio_core/renderer/system.cpp
@@ -534,7 +534,7 @@ Result System::Update(std::span<const u8> input, std::span<u8> performance, std:
534 return result; 534 return result;
535 } 535 }
536 536
537 adsp_rendered_event->GetWritableEvent().Clear(); 537 adsp_rendered_event->Clear();
538 num_times_updated++; 538 num_times_updated++;
539 539
540 const auto end_time{core.CoreTiming().GetClockTicks()}; 540 const auto end_time{core.CoreTiming().GetClockTicks()};
@@ -625,7 +625,7 @@ void System::SendCommandToDsp() {
625 reset_command_buffers = false; 625 reset_command_buffers = false;
626 command_buffer_size = command_size; 626 command_buffer_size = command_size;
627 if (remaining_command_count == 0) { 627 if (remaining_command_count == 0) {
628 adsp_rendered_event->GetWritableEvent().Signal(); 628 adsp_rendered_event->Signal();
629 } 629 }
630 } else { 630 } else {
631 adsp.ClearRemainCount(session_id); 631 adsp.ClearRemainCount(session_id);
diff --git a/src/audio_core/sink/sdl2_sink.cpp b/src/audio_core/sink/sdl2_sink.cpp
index f12ebf7fe..c138dc628 100644
--- a/src/audio_core/sink/sdl2_sink.cpp
+++ b/src/audio_core/sink/sdl2_sink.cpp
@@ -230,7 +230,9 @@ std::vector<std::string> ListSDLSinkDevices(bool capture) {
230 230
231 const int device_count = SDL_GetNumAudioDevices(capture); 231 const int device_count = SDL_GetNumAudioDevices(capture);
232 for (int i = 0; i < device_count; ++i) { 232 for (int i = 0; i < device_count; ++i) {
233 device_list.emplace_back(SDL_GetAudioDeviceName(i, 0)); 233 if (const char* name = SDL_GetAudioDeviceName(i, capture)) {
234 device_list.emplace_back(name);
235 }
234 } 236 }
235 237
236 return device_list; 238 return device_list;
diff --git a/src/audio_core/sink/sink_details.cpp b/src/audio_core/sink/sink_details.cpp
index b878bf23f..39ea6d91b 100644
--- a/src/audio_core/sink/sink_details.cpp
+++ b/src/audio_core/sink/sink_details.cpp
@@ -47,7 +47,7 @@ constexpr SinkDetails sink_details[] = {
47#endif 47#endif
48#ifdef HAVE_SDL2 48#ifdef HAVE_SDL2
49 SinkDetails{ 49 SinkDetails{
50 "sdl", 50 "sdl2",
51 [](std::string_view device_id) -> std::unique_ptr<Sink> { 51 [](std::string_view device_id) -> std::unique_ptr<Sink> {
52 return std::make_unique<SDLSink>(device_id); 52 return std::make_unique<SDLSink>(device_id);
53 }, 53 },
@@ -76,7 +76,7 @@ const SinkDetails& GetOutputSinkDetails(std::string_view sink_id) {
76#if defined(HAVE_CUBEB) && defined(HAVE_SDL2) 76#if defined(HAVE_CUBEB) && defined(HAVE_SDL2)
77 iter = find_backend("cubeb"); 77 iter = find_backend("cubeb");
78 if (iter->latency() > TargetSampleCount * 3) { 78 if (iter->latency() > TargetSampleCount * 3) {
79 iter = find_backend("sdl"); 79 iter = find_backend("sdl2");
80 } 80 }
81#else 81#else
82 iter = std::begin(sink_details); 82 iter = std::begin(sink_details);
diff --git a/src/common/CMakeLists.txt b/src/common/CMakeLists.txt
index a02696873..46cf75fde 100644
--- a/src/common/CMakeLists.txt
+++ b/src/common/CMakeLists.txt
@@ -169,7 +169,11 @@ endif()
169create_target_directory_groups(common) 169create_target_directory_groups(common)
170 170
171target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads) 171target_link_libraries(common PUBLIC ${Boost_LIBRARIES} fmt::fmt microprofile Threads::Threads)
172target_link_libraries(common PRIVATE lz4::lz4) 172if (TARGET lz4::lz4)
173 target_link_libraries(common PRIVATE lz4::lz4)
174else()
175 target_link_libraries(common PRIVATE LZ4::lz4_shared)
176endif()
173if (TARGET zstd::zstd) 177if (TARGET zstd::zstd)
174 target_link_libraries(common PRIVATE zstd::zstd) 178 target_link_libraries(common PRIVATE zstd::zstd)
175else() 179else()
diff --git a/src/common/fixed_point.h b/src/common/fixed_point.h
index 4a0f72cc9..6eb6afe2f 100644
--- a/src/common/fixed_point.h
+++ b/src/common/fixed_point.h
@@ -4,14 +4,7 @@
4// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h 4// From: https://github.com/eteran/cpp-utilities/blob/master/fixed/include/cpp-utilities/fixed.h
5// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math 5// See also: http://stackoverflow.com/questions/79677/whats-the-best-way-to-do-fixed-point-math
6 6
7#ifndef FIXED_H_ 7#pragma once
8#define FIXED_H_
9
10#if __cplusplus >= 201402L
11#define CONSTEXPR14 constexpr
12#else
13#define CONSTEXPR14
14#endif
15 8
16#include <cstddef> // for size_t 9#include <cstddef> // for size_t
17#include <cstdint> 10#include <cstdint>
@@ -106,7 +99,7 @@ constexpr B next_to_base(N rhs) {
106struct divide_by_zero : std::exception {}; 99struct divide_by_zero : std::exception {};
107 100
108template <size_t I, size_t F> 101template <size_t I, size_t F>
109CONSTEXPR14 FixedPoint<I, F> divide( 102constexpr FixedPoint<I, F> divide(
110 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 103 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
111 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 104 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
112 105
@@ -126,7 +119,7 @@ CONSTEXPR14 FixedPoint<I, F> divide(
126} 119}
127 120
128template <size_t I, size_t F> 121template <size_t I, size_t F>
129CONSTEXPR14 FixedPoint<I, F> divide( 122constexpr FixedPoint<I, F> divide(
130 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder, 123 FixedPoint<I, F> numerator, FixedPoint<I, F> denominator, FixedPoint<I, F>& remainder,
131 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 124 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
132 125
@@ -196,7 +189,7 @@ CONSTEXPR14 FixedPoint<I, F> divide(
196 189
197// this is the usual implementation of multiplication 190// this is the usual implementation of multiplication
198template <size_t I, size_t F> 191template <size_t I, size_t F>
199CONSTEXPR14 FixedPoint<I, F> multiply( 192constexpr FixedPoint<I, F> multiply(
200 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 193 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
201 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 194 typename std::enable_if<type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
202 195
@@ -215,7 +208,7 @@ CONSTEXPR14 FixedPoint<I, F> multiply(
215// it is slightly slower, but is more robust since it doesn't 208// it is slightly slower, but is more robust since it doesn't
216// require and upgraded type 209// require and upgraded type
217template <size_t I, size_t F> 210template <size_t I, size_t F>
218CONSTEXPR14 FixedPoint<I, F> multiply( 211constexpr FixedPoint<I, F> multiply(
219 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs, 212 FixedPoint<I, F> lhs, FixedPoint<I, F> rhs,
220 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) { 213 typename std::enable_if<!type_from_size<I + F>::next_size::is_specialized>::type* = nullptr) {
221 214
@@ -284,7 +277,7 @@ public: // constructors
284 277
285public: // conversion 278public: // conversion
286 template <size_t I2, size_t F2> 279 template <size_t I2, size_t F2>
287 CONSTEXPR14 explicit FixedPoint(FixedPoint<I2, F2> other) { 280 constexpr explicit FixedPoint(FixedPoint<I2, F2> other) {
288 static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types"); 281 static_assert(I2 <= I && F2 <= F, "Scaling conversion can only upgrade types");
289 using T = FixedPoint<I2, F2>; 282 using T = FixedPoint<I2, F2>;
290 283
@@ -353,81 +346,81 @@ public: // unary operators
353 return FixedPoint::from_base(+data_); 346 return FixedPoint::from_base(+data_);
354 } 347 }
355 348
356 CONSTEXPR14 FixedPoint& operator++() { 349 constexpr FixedPoint& operator++() {
357 data_ += one; 350 data_ += one;
358 return *this; 351 return *this;
359 } 352 }
360 353
361 CONSTEXPR14 FixedPoint& operator--() { 354 constexpr FixedPoint& operator--() {
362 data_ -= one; 355 data_ -= one;
363 return *this; 356 return *this;
364 } 357 }
365 358
366 CONSTEXPR14 FixedPoint operator++(int) { 359 constexpr FixedPoint operator++(int) {
367 FixedPoint tmp(*this); 360 FixedPoint tmp(*this);
368 data_ += one; 361 data_ += one;
369 return tmp; 362 return tmp;
370 } 363 }
371 364
372 CONSTEXPR14 FixedPoint operator--(int) { 365 constexpr FixedPoint operator--(int) {
373 FixedPoint tmp(*this); 366 FixedPoint tmp(*this);
374 data_ -= one; 367 data_ -= one;
375 return tmp; 368 return tmp;
376 } 369 }
377 370
378public: // basic math operators 371public: // basic math operators
379 CONSTEXPR14 FixedPoint& operator+=(FixedPoint n) { 372 constexpr FixedPoint& operator+=(FixedPoint n) {
380 data_ += n.data_; 373 data_ += n.data_;
381 return *this; 374 return *this;
382 } 375 }
383 376
384 CONSTEXPR14 FixedPoint& operator-=(FixedPoint n) { 377 constexpr FixedPoint& operator-=(FixedPoint n) {
385 data_ -= n.data_; 378 data_ -= n.data_;
386 return *this; 379 return *this;
387 } 380 }
388 381
389 CONSTEXPR14 FixedPoint& operator*=(FixedPoint n) { 382 constexpr FixedPoint& operator*=(FixedPoint n) {
390 return assign(detail::multiply(*this, n)); 383 return assign(detail::multiply(*this, n));
391 } 384 }
392 385
393 CONSTEXPR14 FixedPoint& operator/=(FixedPoint n) { 386 constexpr FixedPoint& operator/=(FixedPoint n) {
394 FixedPoint temp; 387 FixedPoint temp;
395 return assign(detail::divide(*this, n, temp)); 388 return assign(detail::divide(*this, n, temp));
396 } 389 }
397 390
398private: 391private:
399 CONSTEXPR14 FixedPoint& assign(FixedPoint rhs) { 392 constexpr FixedPoint& assign(FixedPoint rhs) {
400 data_ = rhs.data_; 393 data_ = rhs.data_;
401 return *this; 394 return *this;
402 } 395 }
403 396
404public: // binary math operators, effects underlying bit pattern since these 397public: // binary math operators, effects underlying bit pattern since these
405 // don't really typically make sense for non-integer values 398 // don't really typically make sense for non-integer values
406 CONSTEXPR14 FixedPoint& operator&=(FixedPoint n) { 399 constexpr FixedPoint& operator&=(FixedPoint n) {
407 data_ &= n.data_; 400 data_ &= n.data_;
408 return *this; 401 return *this;
409 } 402 }
410 403
411 CONSTEXPR14 FixedPoint& operator|=(FixedPoint n) { 404 constexpr FixedPoint& operator|=(FixedPoint n) {
412 data_ |= n.data_; 405 data_ |= n.data_;
413 return *this; 406 return *this;
414 } 407 }
415 408
416 CONSTEXPR14 FixedPoint& operator^=(FixedPoint n) { 409 constexpr FixedPoint& operator^=(FixedPoint n) {
417 data_ ^= n.data_; 410 data_ ^= n.data_;
418 return *this; 411 return *this;
419 } 412 }
420 413
421 template <class Integer, 414 template <class Integer,
422 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 415 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
423 CONSTEXPR14 FixedPoint& operator>>=(Integer n) { 416 constexpr FixedPoint& operator>>=(Integer n) {
424 data_ >>= n; 417 data_ >>= n;
425 return *this; 418 return *this;
426 } 419 }
427 420
428 template <class Integer, 421 template <class Integer,
429 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 422 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
430 CONSTEXPR14 FixedPoint& operator<<=(Integer n) { 423 constexpr FixedPoint& operator<<=(Integer n) {
431 data_ <<= n; 424 data_ <<= n;
432 return *this; 425 return *this;
433 } 426 }
@@ -485,7 +478,7 @@ public: // conversion to basic types
485 } 478 }
486 479
487public: 480public:
488 CONSTEXPR14 void swap(FixedPoint& rhs) { 481 constexpr void swap(FixedPoint& rhs) {
489 using std::swap; 482 using std::swap;
490 swap(data_, rhs.data_); 483 swap(data_, rhs.data_);
491 } 484 }
@@ -497,8 +490,8 @@ public:
497// if we have the same fractional portion, but differing integer portions, we trivially upgrade the 490// if we have the same fractional portion, but differing integer portions, we trivially upgrade the
498// smaller type 491// smaller type
499template <size_t I1, size_t I2, size_t F> 492template <size_t I1, size_t I2, size_t F>
500CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 493constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator+(
501operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 494 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
502 495
503 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 496 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
504 497
@@ -508,8 +501,8 @@ operator+(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
508} 501}
509 502
510template <size_t I1, size_t I2, size_t F> 503template <size_t I1, size_t I2, size_t F>
511CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 504constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator-(
512operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 505 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
513 506
514 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 507 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
515 508
@@ -519,8 +512,8 @@ operator-(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
519} 512}
520 513
521template <size_t I1, size_t I2, size_t F> 514template <size_t I1, size_t I2, size_t F>
522CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 515constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator*(
523operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 516 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
524 517
525 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 518 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
526 519
@@ -530,8 +523,8 @@ operator*(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
530} 523}
531 524
532template <size_t I1, size_t I2, size_t F> 525template <size_t I1, size_t I2, size_t F>
533CONSTEXPR14 typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type 526constexpr typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type operator/(
534operator/(FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) { 527 FixedPoint<I1, F> lhs, FixedPoint<I2, F> rhs) {
535 528
536 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type; 529 using T = typename std::conditional<I1 >= I2, FixedPoint<I1, F>, FixedPoint<I2, F>>::type;
537 530
@@ -548,75 +541,75 @@ std::ostream& operator<<(std::ostream& os, FixedPoint<I, F> f) {
548 541
549// basic math operators 542// basic math operators
550template <size_t I, size_t F> 543template <size_t I, size_t F>
551CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 544constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
552 lhs += rhs; 545 lhs += rhs;
553 return lhs; 546 return lhs;
554} 547}
555template <size_t I, size_t F> 548template <size_t I, size_t F>
556CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 549constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
557 lhs -= rhs; 550 lhs -= rhs;
558 return lhs; 551 return lhs;
559} 552}
560template <size_t I, size_t F> 553template <size_t I, size_t F>
561CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 554constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
562 lhs *= rhs; 555 lhs *= rhs;
563 return lhs; 556 return lhs;
564} 557}
565template <size_t I, size_t F> 558template <size_t I, size_t F>
566CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) { 559constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, FixedPoint<I, F> rhs) {
567 lhs /= rhs; 560 lhs /= rhs;
568 return lhs; 561 return lhs;
569} 562}
570 563
571template <size_t I, size_t F, class Number, 564template <size_t I, size_t F, class Number,
572 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 565 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
573CONSTEXPR14 FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) { 566constexpr FixedPoint<I, F> operator+(FixedPoint<I, F> lhs, Number rhs) {
574 lhs += FixedPoint<I, F>(rhs); 567 lhs += FixedPoint<I, F>(rhs);
575 return lhs; 568 return lhs;
576} 569}
577template <size_t I, size_t F, class Number, 570template <size_t I, size_t F, class Number,
578 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 571 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
579CONSTEXPR14 FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) { 572constexpr FixedPoint<I, F> operator-(FixedPoint<I, F> lhs, Number rhs) {
580 lhs -= FixedPoint<I, F>(rhs); 573 lhs -= FixedPoint<I, F>(rhs);
581 return lhs; 574 return lhs;
582} 575}
583template <size_t I, size_t F, class Number, 576template <size_t I, size_t F, class Number,
584 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 577 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
585CONSTEXPR14 FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) { 578constexpr FixedPoint<I, F> operator*(FixedPoint<I, F> lhs, Number rhs) {
586 lhs *= FixedPoint<I, F>(rhs); 579 lhs *= FixedPoint<I, F>(rhs);
587 return lhs; 580 return lhs;
588} 581}
589template <size_t I, size_t F, class Number, 582template <size_t I, size_t F, class Number,
590 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 583 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
591CONSTEXPR14 FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) { 584constexpr FixedPoint<I, F> operator/(FixedPoint<I, F> lhs, Number rhs) {
592 lhs /= FixedPoint<I, F>(rhs); 585 lhs /= FixedPoint<I, F>(rhs);
593 return lhs; 586 return lhs;
594} 587}
595 588
596template <size_t I, size_t F, class Number, 589template <size_t I, size_t F, class Number,
597 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 590 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
598CONSTEXPR14 FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) { 591constexpr FixedPoint<I, F> operator+(Number lhs, FixedPoint<I, F> rhs) {
599 FixedPoint<I, F> tmp(lhs); 592 FixedPoint<I, F> tmp(lhs);
600 tmp += rhs; 593 tmp += rhs;
601 return tmp; 594 return tmp;
602} 595}
603template <size_t I, size_t F, class Number, 596template <size_t I, size_t F, class Number,
604 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 597 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
605CONSTEXPR14 FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) { 598constexpr FixedPoint<I, F> operator-(Number lhs, FixedPoint<I, F> rhs) {
606 FixedPoint<I, F> tmp(lhs); 599 FixedPoint<I, F> tmp(lhs);
607 tmp -= rhs; 600 tmp -= rhs;
608 return tmp; 601 return tmp;
609} 602}
610template <size_t I, size_t F, class Number, 603template <size_t I, size_t F, class Number,
611 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 604 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
612CONSTEXPR14 FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) { 605constexpr FixedPoint<I, F> operator*(Number lhs, FixedPoint<I, F> rhs) {
613 FixedPoint<I, F> tmp(lhs); 606 FixedPoint<I, F> tmp(lhs);
614 tmp *= rhs; 607 tmp *= rhs;
615 return tmp; 608 return tmp;
616} 609}
617template <size_t I, size_t F, class Number, 610template <size_t I, size_t F, class Number,
618 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type> 611 class = typename std::enable_if<std::is_arithmetic<Number>::value>::type>
619CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) { 612constexpr FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
620 FixedPoint<I, F> tmp(lhs); 613 FixedPoint<I, F> tmp(lhs);
621 tmp /= rhs; 614 tmp /= rhs;
622 return tmp; 615 return tmp;
@@ -625,13 +618,13 @@ CONSTEXPR14 FixedPoint<I, F> operator/(Number lhs, FixedPoint<I, F> rhs) {
625// shift operators 618// shift operators
626template <size_t I, size_t F, class Integer, 619template <size_t I, size_t F, class Integer,
627 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 620 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
628CONSTEXPR14 FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) { 621constexpr FixedPoint<I, F> operator<<(FixedPoint<I, F> lhs, Integer rhs) {
629 lhs <<= rhs; 622 lhs <<= rhs;
630 return lhs; 623 return lhs;
631} 624}
632template <size_t I, size_t F, class Integer, 625template <size_t I, size_t F, class Integer,
633 class = typename std::enable_if<std::is_integral<Integer>::value>::type> 626 class = typename std::enable_if<std::is_integral<Integer>::value>::type>
634CONSTEXPR14 FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) { 627constexpr FixedPoint<I, F> operator>>(FixedPoint<I, F> lhs, Integer rhs) {
635 lhs >>= rhs; 628 lhs >>= rhs;
636 return lhs; 629 return lhs;
637} 630}
@@ -700,7 +693,3 @@ constexpr bool operator!=(Number lhs, FixedPoint<I, F> rhs) {
700} 693}
701 694
702} // namespace Common 695} // namespace Common
703
704#undef CONSTEXPR14
705
706#endif
diff --git a/src/core/CMakeLists.txt b/src/core/CMakeLists.txt
index 95302c419..abeb5859b 100644
--- a/src/core/CMakeLists.txt
+++ b/src/core/CMakeLists.txt
@@ -261,8 +261,6 @@ add_library(core STATIC
261 hle/kernel/k_worker_task.h 261 hle/kernel/k_worker_task.h
262 hle/kernel/k_worker_task_manager.cpp 262 hle/kernel/k_worker_task_manager.cpp
263 hle/kernel/k_worker_task_manager.h 263 hle/kernel/k_worker_task_manager.h
264 hle/kernel/k_writable_event.cpp
265 hle/kernel/k_writable_event.h
266 hle/kernel/kernel.cpp 264 hle/kernel/kernel.cpp
267 hle/kernel/kernel.h 265 hle/kernel/kernel.h
268 hle/kernel/memory_types.h 266 hle/kernel/memory_types.h
diff --git a/src/core/arm/dynarmic/arm_dynarmic_64.cpp b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
index 1d46f6d40..22b5d5656 100644
--- a/src/core/arm/dynarmic/arm_dynarmic_64.cpp
+++ b/src/core/arm/dynarmic/arm_dynarmic_64.cpp
@@ -111,6 +111,7 @@ public:
111 LOG_ERROR(Core_ARM, 111 LOG_ERROR(Core_ARM,
112 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc, 112 "Unimplemented instruction @ 0x{:X} for {} instructions (instr = {:08X})", pc,
113 num_instructions, memory.Read32(pc)); 113 num_instructions, memory.Read32(pc));
114 ReturnException(pc, ARM_Interface::no_execute);
114 } 115 }
115 116
116 void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op, 117 void InstructionCacheOperationRaised(Dynarmic::A64::InstructionCacheOperation op,
diff --git a/src/core/hid/irs_types.h b/src/core/hid/irs_types.h
index 88c5b016d..0d1bfe53f 100644
--- a/src/core/hid/irs_types.h
+++ b/src/core/hid/irs_types.h
@@ -14,7 +14,7 @@ enum class CameraAmbientNoiseLevel : u32 {
14 Low, 14 Low,
15 Medium, 15 Medium,
16 High, 16 High,
17 Unkown3, // This level can't be reached 17 Unknown3, // This level can't be reached
18}; 18};
19 19
20// This is nn::irsensor::CameraLightTarget 20// This is nn::irsensor::CameraLightTarget
@@ -75,9 +75,9 @@ enum class IrCameraStatus : u32 {
75enum class IrCameraInternalStatus : u32 { 75enum class IrCameraInternalStatus : u32 {
76 Stopped, 76 Stopped,
77 FirmwareUpdateNeeded, 77 FirmwareUpdateNeeded,
78 Unkown2, 78 Unknown2,
79 Unkown3, 79 Unknown3,
80 Unkown4, 80 Unknown4,
81 FirmwareVersionRequested, 81 FirmwareVersionRequested,
82 FirmwareVersionIsInvalid, 82 FirmwareVersionIsInvalid,
83 Ready, 83 Ready,
@@ -121,20 +121,20 @@ enum class IrSensorFunctionLevel : u8 {
121 121
122// This is nn::irsensor::MomentProcessorPreprocess 122// This is nn::irsensor::MomentProcessorPreprocess
123enum class MomentProcessorPreprocess : u32 { 123enum class MomentProcessorPreprocess : u32 {
124 Unkown0, 124 Unknown0,
125 Unkown1, 125 Unknown1,
126}; 126};
127 127
128// This is nn::irsensor::PackedMomentProcessorPreprocess 128// This is nn::irsensor::PackedMomentProcessorPreprocess
129enum class PackedMomentProcessorPreprocess : u8 { 129enum class PackedMomentProcessorPreprocess : u8 {
130 Unkown0, 130 Unknown0,
131 Unkown1, 131 Unknown1,
132}; 132};
133 133
134// This is nn::irsensor::PointingStatus 134// This is nn::irsensor::PointingStatus
135enum class PointingStatus : u32 { 135enum class PointingStatus : u32 {
136 Unkown0, 136 Unknown0,
137 Unkown1, 137 Unknown1,
138}; 138};
139 139
140struct IrsRect { 140struct IrsRect {
diff --git a/src/core/hle/ipc_helpers.h b/src/core/hle/ipc_helpers.h
index d631c0357..0cc26a211 100644
--- a/src/core/hle/ipc_helpers.h
+++ b/src/core/hle/ipc_helpers.h
@@ -152,7 +152,8 @@ public:
152 Kernel::LimitableResource::Sessions, 1); 152 Kernel::LimitableResource::Sessions, 1);
153 153
154 auto* session = Kernel::KSession::Create(kernel); 154 auto* session = Kernel::KSession::Create(kernel);
155 session->Initialize(nullptr, iface->GetServiceName()); 155 session->Initialize(nullptr, iface->GetServiceName(),
156 std::make_shared<Kernel::SessionRequestManager>(kernel));
156 157
157 context->AddMoveObject(&session->GetClientSession()); 158 context->AddMoveObject(&session->GetClientSession());
158 iface->ClientConnected(&session->GetServerSession()); 159 iface->ClientConnected(&session->GetServerSession());
diff --git a/src/core/hle/kernel/hle_ipc.h b/src/core/hle/kernel/hle_ipc.h
index 99265ce90..e258e2cdf 100644
--- a/src/core/hle/kernel/hle_ipc.h
+++ b/src/core/hle/kernel/hle_ipc.h
@@ -43,13 +43,13 @@ class Domain;
43class HLERequestContext; 43class HLERequestContext;
44class KAutoObject; 44class KAutoObject;
45class KernelCore; 45class KernelCore;
46class KEvent;
46class KHandleTable; 47class KHandleTable;
47class KProcess; 48class KProcess;
48class KServerSession; 49class KServerSession;
49class KThread; 50class KThread;
50class KReadableEvent; 51class KReadableEvent;
51class KSession; 52class KSession;
52class KWritableEvent;
53class ServiceThread; 53class ServiceThread;
54 54
55enum class ThreadWakeupReason; 55enum class ThreadWakeupReason;
diff --git a/src/core/hle/kernel/k_class_token.cpp b/src/core/hle/kernel/k_class_token.cpp
index cc2a0f7ca..10265c23c 100644
--- a/src/core/hle/kernel/k_class_token.cpp
+++ b/src/core/hle/kernel/k_class_token.cpp
@@ -18,7 +18,6 @@
18#include "core/hle/kernel/k_synchronization_object.h" 18#include "core/hle/kernel/k_synchronization_object.h"
19#include "core/hle/kernel/k_thread.h" 19#include "core/hle/kernel/k_thread.h"
20#include "core/hle/kernel/k_transfer_memory.h" 20#include "core/hle/kernel/k_transfer_memory.h"
21#include "core/hle/kernel/k_writable_event.h"
22 21
23namespace Kernel { 22namespace Kernel {
24 23
@@ -42,13 +41,12 @@ static_assert(ClassToken<KPort> == 0b10000101'00000000);
42static_assert(ClassToken<KSession> == 0b00011001'00000000); 41static_assert(ClassToken<KSession> == 0b00011001'00000000);
43static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000); 42static_assert(ClassToken<KSharedMemory> == 0b00101001'00000000);
44static_assert(ClassToken<KEvent> == 0b01001001'00000000); 43static_assert(ClassToken<KEvent> == 0b01001001'00000000);
45static_assert(ClassToken<KWritableEvent> == 0b10001001'00000000);
46// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000); 44// static_assert(ClassToken<KLightClientSession> == 0b00110001'00000000);
47// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000); 45// static_assert(ClassToken<KLightServerSession> == 0b01010001'00000000);
48static_assert(ClassToken<KTransferMemory> == 0b10010001'00000000); 46static_assert(ClassToken<KTransferMemory> == 0b01010001'00000000);
49// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000); 47// static_assert(ClassToken<KDeviceAddressSpace> == 0b01100001'00000000);
50// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000); 48// static_assert(ClassToken<KSessionRequest> == 0b10100001'00000000);
51static_assert(ClassToken<KCodeMemory> == 0b11000001'00000000); 49static_assert(ClassToken<KCodeMemory> == 0b10100001'00000000);
52 50
53// Ensure that the token hierarchy is correct. 51// Ensure that the token hierarchy is correct.
54 52
@@ -73,13 +71,12 @@ static_assert(ClassToken<KPort> == ((0b10000101 << 8) | ClassToken<KAutoObject>)
73static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>)); 71static_assert(ClassToken<KSession> == ((0b00011001 << 8) | ClassToken<KAutoObject>));
74static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>)); 72static_assert(ClassToken<KSharedMemory> == ((0b00101001 << 8) | ClassToken<KAutoObject>));
75static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>)); 73static_assert(ClassToken<KEvent> == ((0b01001001 << 8) | ClassToken<KAutoObject>));
76static_assert(ClassToken<KWritableEvent> == ((0b10001001 << 8) | ClassToken<KAutoObject>));
77// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>)); 74// static_assert(ClassToken<KLightClientSession> == ((0b00110001 << 8) | ClassToken<KAutoObject>));
78// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>)); 75// static_assert(ClassToken<KLightServerSession> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
79static_assert(ClassToken<KTransferMemory> == ((0b10010001 << 8) | ClassToken<KAutoObject>)); 76static_assert(ClassToken<KTransferMemory> == ((0b01010001 << 8) | ClassToken<KAutoObject>));
80// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>)); 77// static_assert(ClassToken<KDeviceAddressSpace> == ((0b01100001 << 8) | ClassToken<KAutoObject>));
81// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>)); 78// static_assert(ClassToken<KSessionRequest> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
82static_assert(ClassToken<KCodeMemory> == ((0b11000001 << 8) | ClassToken<KAutoObject>)); 79static_assert(ClassToken<KCodeMemory> == ((0b10100001 << 8) | ClassToken<KAutoObject>));
83 80
84// Ensure that the token hierarchy reflects the class hierarchy. 81// Ensure that the token hierarchy reflects the class hierarchy.
85 82
@@ -110,7 +107,6 @@ static_assert(std::is_final_v<KPort> && std::is_base_of_v<KAutoObject, KPort>);
110static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>); 107static_assert(std::is_final_v<KSession> && std::is_base_of_v<KAutoObject, KSession>);
111static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>); 108static_assert(std::is_final_v<KSharedMemory> && std::is_base_of_v<KAutoObject, KSharedMemory>);
112static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>); 109static_assert(std::is_final_v<KEvent> && std::is_base_of_v<KAutoObject, KEvent>);
113static_assert(std::is_final_v<KWritableEvent> && std::is_base_of_v<KAutoObject, KWritableEvent>);
114// static_assert(std::is_final_v<KLightClientSession> && 110// static_assert(std::is_final_v<KLightClientSession> &&
115// std::is_base_of_v<KAutoObject, KLightClientSession>); 111// std::is_base_of_v<KAutoObject, KLightClientSession>);
116// static_assert(std::is_final_v<KLightServerSession> && 112// static_assert(std::is_final_v<KLightServerSession> &&
diff --git a/src/core/hle/kernel/k_class_token.h b/src/core/hle/kernel/k_class_token.h
index c9001ae3d..ab20e00ff 100644
--- a/src/core/hle/kernel/k_class_token.h
+++ b/src/core/hle/kernel/k_class_token.h
@@ -101,7 +101,6 @@ public:
101 KSession, 101 KSession,
102 KSharedMemory, 102 KSharedMemory,
103 KEvent, 103 KEvent,
104 KWritableEvent,
105 KLightClientSession, 104 KLightClientSession,
106 KLightServerSession, 105 KLightServerSession,
107 KTransferMemory, 106 KTransferMemory,
diff --git a/src/core/hle/kernel/k_client_session.cpp b/src/core/hle/kernel/k_client_session.cpp
index b2a887b14..8892c5b7c 100644
--- a/src/core/hle/kernel/k_client_session.cpp
+++ b/src/core/hle/kernel/k_client_session.cpp
@@ -21,10 +21,9 @@ void KClientSession::Destroy() {
21 21
22void KClientSession::OnServerClosed() {} 22void KClientSession::OnServerClosed() {}
23 23
24Result KClientSession::SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, 24Result KClientSession::SendSyncRequest() {
25 Core::Timing::CoreTiming& core_timing) {
26 // Signal the server session that new data is available 25 // Signal the server session that new data is available
27 return parent->GetServerSession().HandleSyncRequest(thread, memory, core_timing); 26 return parent->GetServerSession().OnRequest();
28} 27}
29 28
30} // namespace Kernel 29} // namespace Kernel
diff --git a/src/core/hle/kernel/k_client_session.h b/src/core/hle/kernel/k_client_session.h
index 0c750d756..b4a19c546 100644
--- a/src/core/hle/kernel/k_client_session.h
+++ b/src/core/hle/kernel/k_client_session.h
@@ -46,8 +46,7 @@ public:
46 return parent; 46 return parent;
47 } 47 }
48 48
49 Result SendSyncRequest(KThread* thread, Core::Memory::Memory& memory, 49 Result SendSyncRequest();
50 Core::Timing::CoreTiming& core_timing);
51 50
52 void OnServerClosed(); 51 void OnServerClosed();
53 52
diff --git a/src/core/hle/kernel/k_event.cpp b/src/core/hle/kernel/k_event.cpp
index e52fafbc7..78ca59463 100644
--- a/src/core/hle/kernel/k_event.cpp
+++ b/src/core/hle/kernel/k_event.cpp
@@ -8,39 +8,45 @@
8namespace Kernel { 8namespace Kernel {
9 9
10KEvent::KEvent(KernelCore& kernel_) 10KEvent::KEvent(KernelCore& kernel_)
11 : KAutoObjectWithSlabHeapAndContainer{kernel_}, readable_event{kernel_}, writable_event{ 11 : KAutoObjectWithSlabHeapAndContainer{kernel_}, m_readable_event{kernel_} {}
12 kernel_} {}
13 12
14KEvent::~KEvent() = default; 13KEvent::~KEvent() = default;
15 14
16void KEvent::Initialize(std::string&& name_, KProcess* owner_) { 15void KEvent::Initialize(KProcess* owner) {
17 // Increment reference count. 16 // Create our readable event.
18 // Because reference count is one on creation, this will result 17 KAutoObject::Create(std::addressof(m_readable_event));
19 // in a reference count of two. Thus, when both readable and
20 // writable events are closed this object will be destroyed.
21 Open();
22 18
23 // Create our sub events. 19 // Initialize our readable event.
24 KAutoObject::Create(std::addressof(readable_event)); 20 m_readable_event.Initialize(this);
25 KAutoObject::Create(std::addressof(writable_event));
26
27 // Initialize our sub sessions.
28 readable_event.Initialize(this, name_ + ":Readable");
29 writable_event.Initialize(this, name_ + ":Writable");
30 21
31 // Set our owner process. 22 // Set our owner process.
32 owner = owner_; 23 m_owner = owner;
33 owner->Open(); 24 m_owner->Open();
34 25
35 // Mark initialized. 26 // Mark initialized.
36 name = std::move(name_); 27 m_initialized = true;
37 initialized = true;
38} 28}
39 29
40void KEvent::Finalize() { 30void KEvent::Finalize() {
41 KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize(); 31 KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList>::Finalize();
42} 32}
43 33
34Result KEvent::Signal() {
35 KScopedSchedulerLock sl{kernel};
36
37 R_SUCCEED_IF(m_readable_event_destroyed);
38
39 return m_readable_event.Signal();
40}
41
42Result KEvent::Clear() {
43 KScopedSchedulerLock sl{kernel};
44
45 R_SUCCEED_IF(m_readable_event_destroyed);
46
47 return m_readable_event.Clear();
48}
49
44void KEvent::PostDestroy(uintptr_t arg) { 50void KEvent::PostDestroy(uintptr_t arg) {
45 // Release the event count resource the owner process holds. 51 // Release the event count resource the owner process holds.
46 KProcess* owner = reinterpret_cast<KProcess*>(arg); 52 KProcess* owner = reinterpret_cast<KProcess*>(arg);
diff --git a/src/core/hle/kernel/k_event.h b/src/core/hle/kernel/k_event.h
index 2ff828feb..48ce7d9a0 100644
--- a/src/core/hle/kernel/k_event.h
+++ b/src/core/hle/kernel/k_event.h
@@ -4,14 +4,12 @@
4#pragma once 4#pragma once
5 5
6#include "core/hle/kernel/k_readable_event.h" 6#include "core/hle/kernel/k_readable_event.h"
7#include "core/hle/kernel/k_writable_event.h"
8#include "core/hle/kernel/slab_helpers.h" 7#include "core/hle/kernel/slab_helpers.h"
9 8
10namespace Kernel { 9namespace Kernel {
11 10
12class KernelCore; 11class KernelCore;
13class KReadableEvent; 12class KReadableEvent;
14class KWritableEvent;
15class KProcess; 13class KProcess;
16 14
17class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> { 15class KEvent final : public KAutoObjectWithSlabHeapAndContainer<KEvent, KAutoObjectWithList> {
@@ -21,37 +19,40 @@ public:
21 explicit KEvent(KernelCore& kernel_); 19 explicit KEvent(KernelCore& kernel_);
22 ~KEvent() override; 20 ~KEvent() override;
23 21
24 void Initialize(std::string&& name, KProcess* owner_); 22 void Initialize(KProcess* owner);
25 23
26 void Finalize() override; 24 void Finalize() override;
27 25
28 bool IsInitialized() const override { 26 bool IsInitialized() const override {
29 return initialized; 27 return m_initialized;
30 } 28 }
31 29
32 uintptr_t GetPostDestroyArgument() const override { 30 uintptr_t GetPostDestroyArgument() const override {
33 return reinterpret_cast<uintptr_t>(owner); 31 return reinterpret_cast<uintptr_t>(m_owner);
34 } 32 }
35 33
36 KProcess* GetOwner() const override { 34 KProcess* GetOwner() const override {
37 return owner; 35 return m_owner;
38 } 36 }
39 37
40 KReadableEvent& GetReadableEvent() { 38 KReadableEvent& GetReadableEvent() {
41 return readable_event; 39 return m_readable_event;
42 }
43
44 KWritableEvent& GetWritableEvent() {
45 return writable_event;
46 } 40 }
47 41
48 static void PostDestroy(uintptr_t arg); 42 static void PostDestroy(uintptr_t arg);
49 43
44 Result Signal();
45 Result Clear();
46
47 void OnReadableEventDestroyed() {
48 m_readable_event_destroyed = true;
49 }
50
50private: 51private:
51 KReadableEvent readable_event; 52 KReadableEvent m_readable_event;
52 KWritableEvent writable_event; 53 KProcess* m_owner{};
53 KProcess* owner{}; 54 bool m_initialized{};
54 bool initialized{}; 55 bool m_readable_event_destroyed{};
55}; 56};
56 57
57} // namespace Kernel 58} // namespace Kernel
diff --git a/src/core/hle/kernel/k_readable_event.cpp b/src/core/hle/kernel/k_readable_event.cpp
index 94c5464fe..5c942d47c 100644
--- a/src/core/hle/kernel/k_readable_event.cpp
+++ b/src/core/hle/kernel/k_readable_event.cpp
@@ -15,31 +15,44 @@ KReadableEvent::KReadableEvent(KernelCore& kernel_) : KSynchronizationObject{ker
15 15
16KReadableEvent::~KReadableEvent() = default; 16KReadableEvent::~KReadableEvent() = default;
17 17
18void KReadableEvent::Initialize(KEvent* parent) {
19 m_is_signaled = false;
20 m_parent = parent;
21
22 if (m_parent != nullptr) {
23 m_parent->Open();
24 }
25}
26
18bool KReadableEvent::IsSignaled() const { 27bool KReadableEvent::IsSignaled() const {
19 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 28 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
20 29
21 return is_signaled; 30 return m_is_signaled;
22} 31}
23 32
24void KReadableEvent::Destroy() { 33void KReadableEvent::Destroy() {
25 if (parent) { 34 if (m_parent) {
26 parent->Close(); 35 {
36 KScopedSchedulerLock sl{kernel};
37 m_parent->OnReadableEventDestroyed();
38 }
39 m_parent->Close();
27 } 40 }
28} 41}
29 42
30Result KReadableEvent::Signal() { 43Result KReadableEvent::Signal() {
31 KScopedSchedulerLock lk{kernel}; 44 KScopedSchedulerLock lk{kernel};
32 45
33 if (!is_signaled) { 46 if (!m_is_signaled) {
34 is_signaled = true; 47 m_is_signaled = true;
35 NotifyAvailable(); 48 this->NotifyAvailable();
36 } 49 }
37 50
38 return ResultSuccess; 51 return ResultSuccess;
39} 52}
40 53
41Result KReadableEvent::Clear() { 54Result KReadableEvent::Clear() {
42 Reset(); 55 this->Reset();
43 56
44 return ResultSuccess; 57 return ResultSuccess;
45} 58}
@@ -47,11 +60,11 @@ Result KReadableEvent::Clear() {
47Result KReadableEvent::Reset() { 60Result KReadableEvent::Reset() {
48 KScopedSchedulerLock lk{kernel}; 61 KScopedSchedulerLock lk{kernel};
49 62
50 if (!is_signaled) { 63 if (!m_is_signaled) {
51 return ResultInvalidState; 64 return ResultInvalidState;
52 } 65 }
53 66
54 is_signaled = false; 67 m_is_signaled = false;
55 return ResultSuccess; 68 return ResultSuccess;
56} 69}
57 70
diff --git a/src/core/hle/kernel/k_readable_event.h b/src/core/hle/kernel/k_readable_event.h
index 18dcad289..743f96bf5 100644
--- a/src/core/hle/kernel/k_readable_event.h
+++ b/src/core/hle/kernel/k_readable_event.h
@@ -20,26 +20,23 @@ public:
20 explicit KReadableEvent(KernelCore& kernel_); 20 explicit KReadableEvent(KernelCore& kernel_);
21 ~KReadableEvent() override; 21 ~KReadableEvent() override;
22 22
23 void Initialize(KEvent* parent_event_, std::string&& name_) { 23 void Initialize(KEvent* parent);
24 is_signaled = false;
25 parent = parent_event_;
26 name = std::move(name_);
27 }
28 24
29 KEvent* GetParent() const { 25 KEvent* GetParent() const {
30 return parent; 26 return m_parent;
31 } 27 }
32 28
29 Result Signal();
30 Result Clear();
31
33 bool IsSignaled() const override; 32 bool IsSignaled() const override;
34 void Destroy() override; 33 void Destroy() override;
35 34
36 Result Signal();
37 Result Clear();
38 Result Reset(); 35 Result Reset();
39 36
40private: 37private:
41 bool is_signaled{}; 38 bool m_is_signaled{};
42 KEvent* parent{}; 39 KEvent* m_parent{};
43}; 40};
44 41
45} // namespace Kernel 42} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.cpp b/src/core/hle/kernel/k_server_session.cpp
index 802c646a6..4252c9adb 100644
--- a/src/core/hle/kernel/k_server_session.cpp
+++ b/src/core/hle/kernel/k_server_session.cpp
@@ -7,6 +7,8 @@
7#include "common/assert.h" 7#include "common/assert.h"
8#include "common/common_types.h" 8#include "common/common_types.h"
9#include "common/logging/log.h" 9#include "common/logging/log.h"
10#include "common/scope_exit.h"
11#include "core/core.h"
10#include "core/core_timing.h" 12#include "core/core_timing.h"
11#include "core/hle/ipc_helpers.h" 13#include "core/hle/ipc_helpers.h"
12#include "core/hle/kernel/hle_ipc.h" 14#include "core/hle/kernel/hle_ipc.h"
@@ -18,13 +20,19 @@
18#include "core/hle/kernel/k_server_session.h" 20#include "core/hle/kernel/k_server_session.h"
19#include "core/hle/kernel/k_session.h" 21#include "core/hle/kernel/k_session.h"
20#include "core/hle/kernel/k_thread.h" 22#include "core/hle/kernel/k_thread.h"
23#include "core/hle/kernel/k_thread_queue.h"
21#include "core/hle/kernel/kernel.h" 24#include "core/hle/kernel/kernel.h"
22#include "core/hle/kernel/service_thread.h" 25#include "core/hle/kernel/service_thread.h"
23#include "core/memory.h" 26#include "core/memory.h"
24 27
25namespace Kernel { 28namespace Kernel {
26 29
27KServerSession::KServerSession(KernelCore& kernel_) : KSynchronizationObject{kernel_} {} 30using ThreadQueueImplForKServerSessionRequest = KThreadQueue;
31
32static constexpr u32 MessageBufferSize = 0x100;
33
34KServerSession::KServerSession(KernelCore& kernel_)
35 : KSynchronizationObject{kernel_}, m_lock{kernel_} {}
28 36
29KServerSession::~KServerSession() = default; 37KServerSession::~KServerSession() = default;
30 38
@@ -33,17 +41,14 @@ void KServerSession::Initialize(KSession* parent_session_, std::string&& name_,
33 // Set member variables. 41 // Set member variables.
34 parent = parent_session_; 42 parent = parent_session_;
35 name = std::move(name_); 43 name = std::move(name_);
36 44 manager = manager_;
37 if (manager_) {
38 manager = manager_;
39 } else {
40 manager = std::make_shared<SessionRequestManager>(kernel);
41 }
42} 45}
43 46
44void KServerSession::Destroy() { 47void KServerSession::Destroy() {
45 parent->OnServerClosed(); 48 parent->OnServerClosed();
46 49
50 this->CleanupRequests();
51
47 parent->Close(); 52 parent->Close();
48 53
49 // Release host emulation members. 54 // Release host emulation members.
@@ -54,13 +59,13 @@ void KServerSession::Destroy() {
54} 59}
55 60
56void KServerSession::OnClientClosed() { 61void KServerSession::OnClientClosed() {
57 if (manager->HasSessionHandler()) { 62 if (manager && manager->HasSessionHandler()) {
58 manager->SessionHandler().ClientDisconnected(this); 63 manager->SessionHandler().ClientDisconnected(this);
59 } 64 }
60} 65}
61 66
62bool KServerSession::IsSignaled() const { 67bool KServerSession::IsSignaled() const {
63 ASSERT(kernel.GlobalSchedulerContext().IsLocked()); 68 ASSERT(KScheduler::IsSchedulerLockedByCurrentThread(kernel));
64 69
65 // If the client is closed, we're always signaled. 70 // If the client is closed, we're always signaled.
66 if (parent->IsClientClosed()) { 71 if (parent->IsClientClosed()) {
@@ -68,7 +73,7 @@ bool KServerSession::IsSignaled() const {
68 } 73 }
69 74
70 // Otherwise, we're signaled if we have a request and aren't handling one. 75 // Otherwise, we're signaled if we have a request and aren't handling one.
71 return false; 76 return !m_thread_request_list.empty() && m_current_thread_request == nullptr;
72} 77}
73 78
74void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) { 79void KServerSession::AppendDomainHandler(SessionRequestHandlerPtr handler) {
@@ -173,9 +178,221 @@ Result KServerSession::CompleteSyncRequest(HLERequestContext& context) {
173 return result; 178 return result;
174} 179}
175 180
176Result KServerSession::HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory, 181Result KServerSession::OnRequest() {
177 Core::Timing::CoreTiming& core_timing) { 182 // Create the wait queue.
178 return QueueSyncRequest(thread, memory); 183 ThreadQueueImplForKServerSessionRequest wait_queue{kernel};
184
185 {
186 // Lock the scheduler.
187 KScopedSchedulerLock sl{kernel};
188
189 // Ensure that we can handle new requests.
190 R_UNLESS(!parent->IsServerClosed(), ResultSessionClosed);
191
192 // Check that we're not terminating.
193 R_UNLESS(!GetCurrentThread(kernel).IsTerminationRequested(), ResultTerminationRequested);
194
195 if (manager) {
196 // HLE request.
197 auto& memory{kernel.System().Memory()};
198 this->QueueSyncRequest(GetCurrentThreadPointer(kernel), memory);
199 } else {
200 // Non-HLE request.
201 auto* thread{GetCurrentThreadPointer(kernel)};
202
203 // Get whether we're empty.
204 const bool was_empty = m_thread_request_list.empty();
205
206 // Add the thread to the list.
207 thread->Open();
208 m_thread_request_list.push_back(thread);
209
210 // If we were empty, signal.
211 if (was_empty) {
212 this->NotifyAvailable();
213 }
214 }
215
216 // This is a synchronous request, so we should wait for our request to complete.
217 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
218 GetCurrentThread(kernel).BeginWait(&wait_queue);
219 }
220
221 return GetCurrentThread(kernel).GetWaitResult();
222}
223
224Result KServerSession::SendReply() {
225 // Lock the session.
226 KScopedLightLock lk(m_lock);
227
228 // Get the request.
229 KThread* client_thread;
230 {
231 KScopedSchedulerLock sl{kernel};
232
233 // Get the current request.
234 client_thread = m_current_thread_request;
235 R_UNLESS(client_thread != nullptr, ResultInvalidState);
236
237 // Clear the current request, since we're processing it.
238 m_current_thread_request = nullptr;
239 if (!m_thread_request_list.empty()) {
240 this->NotifyAvailable();
241 }
242 }
243
244 // Close reference to the request once we're done processing it.
245 SCOPE_EXIT({ client_thread->Close(); });
246
247 // Extract relevant information from the request.
248 // const uintptr_t client_message = request->GetAddress();
249 // const size_t client_buffer_size = request->GetSize();
250 // KThread *client_thread = request->GetThread();
251 // KEvent *event = request->GetEvent();
252
253 // Check whether we're closed.
254 const bool closed = (client_thread == nullptr || parent->IsClientClosed());
255
256 Result result = ResultSuccess;
257 if (!closed) {
258 // If we're not closed, send the reply.
259 Core::Memory::Memory& memory{kernel.System().Memory()};
260 KThread* server_thread{GetCurrentThreadPointer(kernel)};
261 UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
262
263 auto* src_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
264 auto* dst_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress());
265 std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize);
266 } else {
267 result = ResultSessionClosed;
268 }
269
270 // Select a result for the client.
271 Result client_result = result;
272 if (closed && R_SUCCEEDED(result)) {
273 result = ResultSessionClosed;
274 client_result = ResultSessionClosed;
275 } else {
276 result = ResultSuccess;
277 }
278
279 // If there's a client thread, update it.
280 if (client_thread != nullptr) {
281 // End the client thread's wait.
282 KScopedSchedulerLock sl{kernel};
283
284 if (!client_thread->IsTerminationRequested()) {
285 client_thread->EndWait(client_result);
286 }
287 }
288
289 return result;
290}
291
292Result KServerSession::ReceiveRequest() {
293 // Lock the session.
294 KScopedLightLock lk(m_lock);
295
296 // Get the request and client thread.
297 // KSessionRequest *request;
298 KThread* client_thread;
299
300 {
301 KScopedSchedulerLock sl{kernel};
302
303 // Ensure that we can service the request.
304 R_UNLESS(!parent->IsClientClosed(), ResultSessionClosed);
305
306 // Ensure we aren't already servicing a request.
307 R_UNLESS(m_current_thread_request == nullptr, ResultNotFound);
308
309 // Ensure we have a request to service.
310 R_UNLESS(!m_thread_request_list.empty(), ResultNotFound);
311
312 // Pop the first request from the list.
313 client_thread = m_thread_request_list.front();
314 m_thread_request_list.pop_front();
315
316 // Get the thread for the request.
317 R_UNLESS(client_thread != nullptr, ResultSessionClosed);
318
319 // Open the client thread.
320 client_thread->Open();
321 }
322
323 // SCOPE_EXIT({ client_thread->Close(); });
324
325 // Set the request as our current.
326 m_current_thread_request = client_thread;
327
328 // Receive the message.
329 Core::Memory::Memory& memory{kernel.System().Memory()};
330 KThread* server_thread{GetCurrentThreadPointer(kernel)};
331 UNIMPLEMENTED_IF(server_thread->GetOwnerProcess() != client_thread->GetOwnerProcess());
332
333 auto* src_msg_buffer = memory.GetPointer(client_thread->GetTLSAddress());
334 auto* dst_msg_buffer = memory.GetPointer(server_thread->GetTLSAddress());
335 std::memcpy(dst_msg_buffer, src_msg_buffer, MessageBufferSize);
336
337 // We succeeded.
338 return ResultSuccess;
339}
340
341void KServerSession::CleanupRequests() {
342 KScopedLightLock lk(m_lock);
343
344 // Clean up any pending requests.
345 while (true) {
346 // Get the next request.
347 // KSessionRequest *request = nullptr;
348 KThread* client_thread = nullptr;
349 {
350 KScopedSchedulerLock sl{kernel};
351
352 if (m_current_thread_request) {
353 // Choose the current request if we have one.
354 client_thread = m_current_thread_request;
355 m_current_thread_request = nullptr;
356 } else if (!m_thread_request_list.empty()) {
357 // Pop the request from the front of the list.
358 client_thread = m_thread_request_list.front();
359 m_thread_request_list.pop_front();
360 }
361 }
362
363 // If there's no request, we're done.
364 if (client_thread == nullptr) {
365 break;
366 }
367
368 // Close a reference to the request once it's cleaned up.
369 SCOPE_EXIT({ client_thread->Close(); });
370
371 // Extract relevant information from the request.
372 // const uintptr_t client_message = request->GetAddress();
373 // const size_t client_buffer_size = request->GetSize();
374 // KThread *client_thread = request->GetThread();
375 // KEvent *event = request->GetEvent();
376
377 // KProcess *server_process = request->GetServerProcess();
378 // KProcess *client_process = (client_thread != nullptr) ?
379 // client_thread->GetOwnerProcess() : nullptr;
380 // KProcessPageTable *client_page_table = (client_process != nullptr) ?
381 // &client_process->GetPageTable() : nullptr;
382
383 // Cleanup the mappings.
384 // Result result = CleanupMap(request, server_process, client_page_table);
385
386 // If there's a client thread, update it.
387 if (client_thread != nullptr) {
388 // End the client thread's wait.
389 KScopedSchedulerLock sl{kernel};
390
391 if (!client_thread->IsTerminationRequested()) {
392 client_thread->EndWait(ResultSessionClosed);
393 }
394 }
395 }
179} 396}
180 397
181} // namespace Kernel 398} // namespace Kernel
diff --git a/src/core/hle/kernel/k_server_session.h b/src/core/hle/kernel/k_server_session.h
index 6d0821945..748d52826 100644
--- a/src/core/hle/kernel/k_server_session.h
+++ b/src/core/hle/kernel/k_server_session.h
@@ -3,6 +3,7 @@
3 3
4#pragma once 4#pragma once
5 5
6#include <list>
6#include <memory> 7#include <memory>
7#include <string> 8#include <string>
8#include <utility> 9#include <utility>
@@ -10,6 +11,7 @@
10#include <boost/intrusive/list.hpp> 11#include <boost/intrusive/list.hpp>
11 12
12#include "core/hle/kernel/hle_ipc.h" 13#include "core/hle/kernel/hle_ipc.h"
14#include "core/hle/kernel/k_light_lock.h"
13#include "core/hle/kernel/k_synchronization_object.h" 15#include "core/hle/kernel/k_synchronization_object.h"
14#include "core/hle/result.h" 16#include "core/hle/result.h"
15 17
@@ -59,25 +61,15 @@ public:
59 void OnClientClosed(); 61 void OnClientClosed();
60 62
61 void ClientConnected(SessionRequestHandlerPtr handler) { 63 void ClientConnected(SessionRequestHandlerPtr handler) {
62 manager->SetSessionHandler(std::move(handler)); 64 if (manager) {
65 manager->SetSessionHandler(std::move(handler));
66 }
63 } 67 }
64 68
65 void ClientDisconnected() { 69 void ClientDisconnected() {
66 manager = nullptr; 70 manager = nullptr;
67 } 71 }
68 72
69 /**
70 * Handle a sync request from the emulated application.
71 *
72 * @param thread Thread that initiated the request.
73 * @param memory Memory context to handle the sync request under.
74 * @param core_timing Core timing context to schedule the request event under.
75 *
76 * @returns Result from the operation.
77 */
78 Result HandleSyncRequest(KThread* thread, Core::Memory::Memory& memory,
79 Core::Timing::CoreTiming& core_timing);
80
81 /// Adds a new domain request handler to the collection of request handlers within 73 /// Adds a new domain request handler to the collection of request handlers within
82 /// this ServerSession instance. 74 /// this ServerSession instance.
83 void AppendDomainHandler(SessionRequestHandlerPtr handler); 75 void AppendDomainHandler(SessionRequestHandlerPtr handler);
@@ -88,7 +80,7 @@ public:
88 80
89 /// Returns true if the session has been converted to a domain, otherwise False 81 /// Returns true if the session has been converted to a domain, otherwise False
90 bool IsDomain() const { 82 bool IsDomain() const {
91 return manager->IsDomain(); 83 return manager && manager->IsDomain();
92 } 84 }
93 85
94 /// Converts the session to a domain at the end of the current command 86 /// Converts the session to a domain at the end of the current command
@@ -101,7 +93,15 @@ public:
101 return manager; 93 return manager;
102 } 94 }
103 95
96 /// TODO: flesh these out to match the real kernel
97 Result OnRequest();
98 Result SendReply();
99 Result ReceiveRequest();
100
104private: 101private:
102 /// Frees up waiting client sessions when this server session is about to die
103 void CleanupRequests();
104
105 /// Queues a sync request from the emulated application. 105 /// Queues a sync request from the emulated application.
106 Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory); 106 Result QueueSyncRequest(KThread* thread, Core::Memory::Memory& memory);
107 107
@@ -112,7 +112,7 @@ private:
112 /// object handle. 112 /// object handle.
113 Result HandleDomainSyncRequest(Kernel::HLERequestContext& context); 113 Result HandleDomainSyncRequest(Kernel::HLERequestContext& context);
114 114
115 /// This session's HLE request handlers 115 /// This session's HLE request handlers; if nullptr, this is not an HLE server
116 std::shared_ptr<SessionRequestManager> manager; 116 std::shared_ptr<SessionRequestManager> manager;
117 117
118 /// When set to True, converts the session to a domain at the end of the command 118 /// When set to True, converts the session to a domain at the end of the command
@@ -120,6 +120,13 @@ private:
120 120
121 /// KSession that owns this KServerSession 121 /// KSession that owns this KServerSession
122 KSession* parent{}; 122 KSession* parent{};
123
124 /// List of threads which are pending a reply.
125 /// FIXME: KSessionRequest
126 std::list<KThread*> m_thread_request_list;
127 KThread* m_current_thread_request{};
128
129 KLightLock m_lock;
123}; 130};
124 131
125} // namespace Kernel 132} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.cpp b/src/core/hle/kernel/k_writable_event.cpp
deleted file mode 100644
index ff88c5acd..000000000
--- a/src/core/hle/kernel/k_writable_event.cpp
+++ /dev/null
@@ -1,35 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#include "core/hle/kernel/k_event.h"
5#include "core/hle/kernel/k_readable_event.h"
6#include "core/hle/kernel/k_writable_event.h"
7
8namespace Kernel {
9
10KWritableEvent::KWritableEvent(KernelCore& kernel_)
11 : KAutoObjectWithSlabHeapAndContainer{kernel_} {}
12
13KWritableEvent::~KWritableEvent() = default;
14
15void KWritableEvent::Initialize(KEvent* parent_event_, std::string&& name_) {
16 parent = parent_event_;
17 name = std::move(name_);
18 parent->GetReadableEvent().Open();
19}
20
21Result KWritableEvent::Signal() {
22 return parent->GetReadableEvent().Signal();
23}
24
25Result KWritableEvent::Clear() {
26 return parent->GetReadableEvent().Clear();
27}
28
29void KWritableEvent::Destroy() {
30 // Close our references.
31 parent->GetReadableEvent().Close();
32 parent->Close();
33}
34
35} // namespace Kernel
diff --git a/src/core/hle/kernel/k_writable_event.h b/src/core/hle/kernel/k_writable_event.h
deleted file mode 100644
index 3fd0c7d0a..000000000
--- a/src/core/hle/kernel/k_writable_event.h
+++ /dev/null
@@ -1,39 +0,0 @@
1// SPDX-FileCopyrightText: Copyright 2021 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later
3
4#pragma once
5
6#include "core/hle/kernel/k_auto_object.h"
7#include "core/hle/kernel/slab_helpers.h"
8#include "core/hle/result.h"
9
10namespace Kernel {
11
12class KernelCore;
13class KEvent;
14
15class KWritableEvent final
16 : public KAutoObjectWithSlabHeapAndContainer<KWritableEvent, KAutoObjectWithList> {
17 KERNEL_AUTOOBJECT_TRAITS(KWritableEvent, KAutoObject);
18
19public:
20 explicit KWritableEvent(KernelCore& kernel_);
21 ~KWritableEvent() override;
22
23 void Destroy() override;
24
25 static void PostDestroy([[maybe_unused]] uintptr_t arg) {}
26
27 void Initialize(KEvent* parent_, std::string&& name_);
28 Result Signal();
29 Result Clear();
30
31 KEvent* GetParent() const {
32 return parent;
33 }
34
35private:
36 KEvent* parent{};
37};
38
39} // namespace Kernel
diff --git a/src/core/hle/kernel/kernel.h b/src/core/hle/kernel/kernel.h
index bcf016a97..0847cbcbf 100644
--- a/src/core/hle/kernel/kernel.h
+++ b/src/core/hle/kernel/kernel.h
@@ -52,7 +52,6 @@ class KThread;
52class KThreadLocalPage; 52class KThreadLocalPage;
53class KTransferMemory; 53class KTransferMemory;
54class KWorkerTaskManager; 54class KWorkerTaskManager;
55class KWritableEvent;
56class KCodeMemory; 55class KCodeMemory;
57class PhysicalCore; 56class PhysicalCore;
58class ServiceThread; 57class ServiceThread;
@@ -345,8 +344,6 @@ public:
345 return slab_heap_container->thread; 344 return slab_heap_container->thread;
346 } else if constexpr (std::is_same_v<T, KTransferMemory>) { 345 } else if constexpr (std::is_same_v<T, KTransferMemory>) {
347 return slab_heap_container->transfer_memory; 346 return slab_heap_container->transfer_memory;
348 } else if constexpr (std::is_same_v<T, KWritableEvent>) {
349 return slab_heap_container->writeable_event;
350 } else if constexpr (std::is_same_v<T, KCodeMemory>) { 347 } else if constexpr (std::is_same_v<T, KCodeMemory>) {
351 return slab_heap_container->code_memory; 348 return slab_heap_container->code_memory;
352 } else if constexpr (std::is_same_v<T, KPageBuffer>) { 349 } else if constexpr (std::is_same_v<T, KPageBuffer>) {
@@ -412,7 +409,6 @@ private:
412 KSlabHeap<KSharedMemoryInfo> shared_memory_info; 409 KSlabHeap<KSharedMemoryInfo> shared_memory_info;
413 KSlabHeap<KThread> thread; 410 KSlabHeap<KThread> thread;
414 KSlabHeap<KTransferMemory> transfer_memory; 411 KSlabHeap<KTransferMemory> transfer_memory;
415 KSlabHeap<KWritableEvent> writeable_event;
416 KSlabHeap<KCodeMemory> code_memory; 412 KSlabHeap<KCodeMemory> code_memory;
417 KSlabHeap<KPageBuffer> page_buffer; 413 KSlabHeap<KPageBuffer> page_buffer;
418 KSlabHeap<KThreadLocalPage> thread_local_page; 414 KSlabHeap<KThreadLocalPage> thread_local_page;
diff --git a/src/core/hle/kernel/svc.cpp b/src/core/hle/kernel/svc.cpp
index 27e5a805d..1d145ea91 100644
--- a/src/core/hle/kernel/svc.cpp
+++ b/src/core/hle/kernel/svc.cpp
@@ -29,12 +29,12 @@
29#include "core/hle/kernel/k_resource_limit.h" 29#include "core/hle/kernel/k_resource_limit.h"
30#include "core/hle/kernel/k_scheduler.h" 30#include "core/hle/kernel/k_scheduler.h"
31#include "core/hle/kernel/k_scoped_resource_reservation.h" 31#include "core/hle/kernel/k_scoped_resource_reservation.h"
32#include "core/hle/kernel/k_session.h"
32#include "core/hle/kernel/k_shared_memory.h" 33#include "core/hle/kernel/k_shared_memory.h"
33#include "core/hle/kernel/k_synchronization_object.h" 34#include "core/hle/kernel/k_synchronization_object.h"
34#include "core/hle/kernel/k_thread.h" 35#include "core/hle/kernel/k_thread.h"
35#include "core/hle/kernel/k_thread_queue.h" 36#include "core/hle/kernel/k_thread_queue.h"
36#include "core/hle/kernel/k_transfer_memory.h" 37#include "core/hle/kernel/k_transfer_memory.h"
37#include "core/hle/kernel/k_writable_event.h"
38#include "core/hle/kernel/kernel.h" 38#include "core/hle/kernel/kernel.h"
39#include "core/hle/kernel/physical_core.h" 39#include "core/hle/kernel/physical_core.h"
40#include "core/hle/kernel/svc.h" 40#include "core/hle/kernel/svc.h"
@@ -256,6 +256,93 @@ static Result UnmapMemory32(Core::System& system, u32 dst_addr, u32 src_addr, u3
256 return UnmapMemory(system, dst_addr, src_addr, size); 256 return UnmapMemory(system, dst_addr, src_addr, size);
257} 257}
258 258
259template <typename T>
260Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client, u64 name) {
261 auto& process = *system.CurrentProcess();
262 auto& handle_table = process.GetHandleTable();
263
264 // Declare the session we're going to allocate.
265 T* session;
266
267 // Reserve a new session from the process resource limit.
268 // FIXME: LimitableResource_SessionCountMax
269 KScopedResourceReservation session_reservation(&process, LimitableResource::Sessions);
270 if (session_reservation.Succeeded()) {
271 session = T::Create(system.Kernel());
272 } else {
273 return ResultLimitReached;
274
275 // // We couldn't reserve a session. Check that we support dynamically expanding the
276 // // resource limit.
277 // R_UNLESS(process.GetResourceLimit() ==
278 // &system.Kernel().GetSystemResourceLimit(), ResultLimitReached);
279 // R_UNLESS(KTargetSystem::IsDynamicResourceLimitsEnabled(), ResultLimitReached());
280
281 // // Try to allocate a session from unused slab memory.
282 // session = T::CreateFromUnusedSlabMemory();
283 // R_UNLESS(session != nullptr, ResultLimitReached);
284 // ON_RESULT_FAILURE { session->Close(); };
285
286 // // If we're creating a KSession, we want to add two KSessionRequests to the heap, to
287 // // prevent request exhaustion.
288 // // NOTE: Nintendo checks if session->DynamicCast<KSession *>() != nullptr, but there's
289 // // no reason to not do this statically.
290 // if constexpr (std::same_as<T, KSession>) {
291 // for (size_t i = 0; i < 2; i++) {
292 // KSessionRequest* request = KSessionRequest::CreateFromUnusedSlabMemory();
293 // R_UNLESS(request != nullptr, ResultLimitReached);
294 // request->Close();
295 // }
296 // }
297
298 // We successfully allocated a session, so add the object we allocated to the resource
299 // limit.
300 // system.Kernel().GetSystemResourceLimit().Reserve(LimitableResource::Sessions, 1);
301 }
302
303 // Check that we successfully created a session.
304 R_UNLESS(session != nullptr, ResultOutOfResource);
305
306 // Initialize the session.
307 session->Initialize(nullptr, fmt::format("{}", name));
308
309 // Commit the session reservation.
310 session_reservation.Commit();
311
312 // Ensure that we clean up the session (and its only references are handle table) on function
313 // end.
314 SCOPE_EXIT({
315 session->GetClientSession().Close();
316 session->GetServerSession().Close();
317 });
318
319 // Register the session.
320 T::Register(system.Kernel(), session);
321
322 // Add the server session to the handle table.
323 R_TRY(handle_table.Add(out_server, &session->GetServerSession()));
324
325 // Add the client session to the handle table.
326 const auto result = handle_table.Add(out_client, &session->GetClientSession());
327
328 if (!R_SUCCEEDED(result)) {
329 // Ensure that we maintaing a clean handle state on exit.
330 handle_table.Remove(*out_server);
331 }
332
333 return result;
334}
335
336static Result CreateSession(Core::System& system, Handle* out_server, Handle* out_client,
337 u32 is_light, u64 name) {
338 if (is_light) {
339 // return CreateSession<KLightSession>(system, out_server, out_client, name);
340 return ResultUnknown;
341 } else {
342 return CreateSession<KSession>(system, out_server, out_client, name);
343 }
344}
345
259/// Connect to an OS service given the port name, returns the handle to the port to out 346/// Connect to an OS service given the port name, returns the handle to the port to out
260static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) { 347static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_name_address) {
261 auto& memory = system.Memory(); 348 auto& memory = system.Memory();
@@ -295,7 +382,8 @@ static Result ConnectToNamedPort(Core::System& system, Handle* out, VAddr port_n
295 382
296 // Create a session. 383 // Create a session.
297 KClientSession* session{}; 384 KClientSession* session{};
298 R_TRY(port->CreateSession(std::addressof(session))); 385 R_TRY(port->CreateSession(std::addressof(session),
386 std::make_shared<SessionRequestManager>(kernel)));
299 port->Close(); 387 port->Close();
300 388
301 // Register the session in the table, close the extra reference. 389 // Register the session in the table, close the extra reference.
@@ -313,7 +401,7 @@ static Result ConnectToNamedPort32(Core::System& system, Handle* out_handle,
313 return ConnectToNamedPort(system, out_handle, port_name_address); 401 return ConnectToNamedPort(system, out_handle, port_name_address);
314} 402}
315 403
316/// Makes a blocking IPC call to an OS service. 404/// Makes a blocking IPC call to a service.
317static Result SendSyncRequest(Core::System& system, Handle handle) { 405static Result SendSyncRequest(Core::System& system, Handle handle) {
318 auto& kernel = system.Kernel(); 406 auto& kernel = system.Kernel();
319 407
@@ -327,22 +415,75 @@ static Result SendSyncRequest(Core::System& system, Handle handle) {
327 415
328 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName()); 416 LOG_TRACE(Kernel_SVC, "called handle=0x{:08X}({})", handle, session->GetName());
329 417
330 { 418 return session->SendSyncRequest();
331 KScopedSchedulerLock lock(kernel);
332
333 // This is a synchronous request, so we should wait for our request to complete.
334 GetCurrentThread(kernel).BeginWait(std::addressof(wait_queue));
335 GetCurrentThread(kernel).SetWaitReasonForDebugging(ThreadWaitReasonForDebugging::IPC);
336 session->SendSyncRequest(&GetCurrentThread(kernel), system.Memory(), system.CoreTiming());
337 }
338
339 return GetCurrentThread(kernel).GetWaitResult();
340} 419}
341 420
342static Result SendSyncRequest32(Core::System& system, Handle handle) { 421static Result SendSyncRequest32(Core::System& system, Handle handle) {
343 return SendSyncRequest(system, handle); 422 return SendSyncRequest(system, handle);
344} 423}
345 424
425static Result ReplyAndReceive(Core::System& system, s32* out_index, Handle* handles,
426 s32 num_handles, Handle reply_target, s64 timeout_ns) {
427 auto& kernel = system.Kernel();
428 auto& handle_table = GetCurrentThread(kernel).GetOwnerProcess()->GetHandleTable();
429
430 // Convert handle list to object table.
431 std::vector<KSynchronizationObject*> objs(num_handles);
432 R_UNLESS(
433 handle_table.GetMultipleObjects<KSynchronizationObject>(objs.data(), handles, num_handles),
434 ResultInvalidHandle);
435
436 // Ensure handles are closed when we're done.
437 SCOPE_EXIT({
438 for (auto i = 0; i < num_handles; ++i) {
439 objs[i]->Close();
440 }
441 });
442
443 // Reply to the target, if one is specified.
444 if (reply_target != InvalidHandle) {
445 KScopedAutoObject session = handle_table.GetObject<KServerSession>(reply_target);
446 R_UNLESS(session.IsNotNull(), ResultInvalidHandle);
447
448 // If we fail to reply, we want to set the output index to -1.
449 // ON_RESULT_FAILURE { *out_index = -1; };
450
451 // Send the reply.
452 // R_TRY(session->SendReply());
453
454 Result rc = session->SendReply();
455 if (!R_SUCCEEDED(rc)) {
456 *out_index = -1;
457 return rc;
458 }
459 }
460
461 // Wait for a message.
462 while (true) {
463 // Wait for an object.
464 s32 index;
465 Result result = KSynchronizationObject::Wait(kernel, &index, objs.data(),
466 static_cast<s32>(objs.size()), timeout_ns);
467 if (result == ResultTimedOut) {
468 return result;
469 }
470
471 // Receive the request.
472 if (R_SUCCEEDED(result)) {
473 KServerSession* session = objs[index]->DynamicCast<KServerSession*>();
474 if (session != nullptr) {
475 result = session->ReceiveRequest();
476 if (result == ResultNotFound) {
477 continue;
478 }
479 }
480 }
481
482 *out_index = index;
483 return result;
484 }
485}
486
346/// Get the ID for the specified thread. 487/// Get the ID for the specified thread.
347static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) { 488static Result GetThreadId(Core::System& system, u64* out_thread_id, Handle thread_handle) {
348 // Get the thread from its handle. 489 // Get the thread from its handle.
@@ -2303,11 +2444,11 @@ static Result SignalEvent(Core::System& system, Handle event_handle) {
2303 // Get the current handle table. 2444 // Get the current handle table.
2304 const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable(); 2445 const KHandleTable& handle_table = system.Kernel().CurrentProcess()->GetHandleTable();
2305 2446
2306 // Get the writable event. 2447 // Get the event.
2307 KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); 2448 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
2308 R_UNLESS(writable_event.IsNotNull(), ResultInvalidHandle); 2449 R_UNLESS(event.IsNotNull(), ResultInvalidHandle);
2309 2450
2310 return writable_event->Signal(); 2451 return event->Signal();
2311} 2452}
2312 2453
2313static Result SignalEvent32(Core::System& system, Handle event_handle) { 2454static Result SignalEvent32(Core::System& system, Handle event_handle) {
@@ -2322,9 +2463,9 @@ static Result ClearEvent(Core::System& system, Handle event_handle) {
2322 2463
2323 // Try to clear the writable event. 2464 // Try to clear the writable event.
2324 { 2465 {
2325 KScopedAutoObject writable_event = handle_table.GetObject<KWritableEvent>(event_handle); 2466 KScopedAutoObject event = handle_table.GetObject<KEvent>(event_handle);
2326 if (writable_event.IsNotNull()) { 2467 if (event.IsNotNull()) {
2327 return writable_event->Clear(); 2468 return event->Clear();
2328 } 2469 }
2329 } 2470 }
2330 2471
@@ -2362,24 +2503,24 @@ static Result CreateEvent(Core::System& system, Handle* out_write, Handle* out_r
2362 R_UNLESS(event != nullptr, ResultOutOfResource); 2503 R_UNLESS(event != nullptr, ResultOutOfResource);
2363 2504
2364 // Initialize the event. 2505 // Initialize the event.
2365 event->Initialize("CreateEvent", kernel.CurrentProcess()); 2506 event->Initialize(kernel.CurrentProcess());
2366 2507
2367 // Commit the thread reservation. 2508 // Commit the thread reservation.
2368 event_reservation.Commit(); 2509 event_reservation.Commit();
2369 2510
2370 // Ensure that we clean up the event (and its only references are handle table) on function end. 2511 // Ensure that we clean up the event (and its only references are handle table) on function end.
2371 SCOPE_EXIT({ 2512 SCOPE_EXIT({
2372 event->GetWritableEvent().Close();
2373 event->GetReadableEvent().Close(); 2513 event->GetReadableEvent().Close();
2514 event->Close();
2374 }); 2515 });
2375 2516
2376 // Register the event. 2517 // Register the event.
2377 KEvent::Register(kernel, event); 2518 KEvent::Register(kernel, event);
2378 2519
2379 // Add the writable event to the handle table. 2520 // Add the event to the handle table.
2380 R_TRY(handle_table.Add(out_write, std::addressof(event->GetWritableEvent()))); 2521 R_TRY(handle_table.Add(out_write, event));
2381 2522
2382 // Add the writable event to the handle table. 2523 // Ensure that we maintaing a clean handle state on exit.
2383 auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); }); 2524 auto handle_guard = SCOPE_GUARD({ handle_table.Remove(*out_write); });
2384 2525
2385 // Add the readable event to the handle table. 2526 // Add the readable event to the handle table.
@@ -2860,10 +3001,10 @@ static const FunctionDef SVC_Table_64[] = {
2860 {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"}, 3001 {0x3D, SvcWrap64<ChangeKernelTraceState>, "ChangeKernelTraceState"},
2861 {0x3E, nullptr, "Unknown3e"}, 3002 {0x3E, nullptr, "Unknown3e"},
2862 {0x3F, nullptr, "Unknown3f"}, 3003 {0x3F, nullptr, "Unknown3f"},
2863 {0x40, nullptr, "CreateSession"}, 3004 {0x40, SvcWrap64<CreateSession>, "CreateSession"},
2864 {0x41, nullptr, "AcceptSession"}, 3005 {0x41, nullptr, "AcceptSession"},
2865 {0x42, nullptr, "ReplyAndReceiveLight"}, 3006 {0x42, nullptr, "ReplyAndReceiveLight"},
2866 {0x43, nullptr, "ReplyAndReceive"}, 3007 {0x43, SvcWrap64<ReplyAndReceive>, "ReplyAndReceive"},
2867 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"}, 3008 {0x44, nullptr, "ReplyAndReceiveWithUserBuffer"},
2868 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"}, 3009 {0x45, SvcWrap64<CreateEvent>, "CreateEvent"},
2869 {0x46, nullptr, "MapIoRegion"}, 3010 {0x46, nullptr, "MapIoRegion"},
diff --git a/src/core/hle/kernel/svc_wrap.h b/src/core/hle/kernel/svc_wrap.h
index 4bc49087e..272c54cf7 100644
--- a/src/core/hle/kernel/svc_wrap.h
+++ b/src/core/hle/kernel/svc_wrap.h
@@ -8,6 +8,7 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/kernel/svc_types.h" 9#include "core/hle/kernel/svc_types.h"
10#include "core/hle/result.h" 10#include "core/hle/result.h"
11#include "core/memory.h"
11 12
12namespace Kernel { 13namespace Kernel {
13 14
@@ -346,6 +347,37 @@ void SvcWrap64(Core::System& system) {
346 FuncReturn(system, retval); 347 FuncReturn(system, retval);
347} 348}
348 349
350// Used by CreateSession
351template <Result func(Core::System&, Handle*, Handle*, u32, u64)>
352void SvcWrap64(Core::System& system) {
353 Handle param_1 = 0;
354 Handle param_2 = 0;
355 const u32 retval = func(system, &param_1, &param_2, static_cast<u32>(Param(system, 2)),
356 static_cast<u32>(Param(system, 3)))
357 .raw;
358
359 system.CurrentArmInterface().SetReg(1, param_1);
360 system.CurrentArmInterface().SetReg(2, param_2);
361 FuncReturn(system, retval);
362}
363
364// Used by ReplyAndReceive
365template <Result func(Core::System&, s32*, Handle*, s32, Handle, s64)>
366void SvcWrap64(Core::System& system) {
367 s32 param_1 = 0;
368 s32 num_handles = static_cast<s32>(Param(system, 2));
369
370 std::vector<Handle> handles(num_handles);
371 system.Memory().ReadBlock(Param(system, 1), handles.data(), num_handles * sizeof(Handle));
372
373 const u32 retval = func(system, &param_1, handles.data(), num_handles,
374 static_cast<s32>(Param(system, 3)), static_cast<s64>(Param(system, 4)))
375 .raw;
376
377 system.CurrentArmInterface().SetReg(1, param_1);
378 FuncReturn(system, retval);
379}
380
349// Used by WaitForAddress 381// Used by WaitForAddress
350template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)> 382template <Result func(Core::System&, u64, Svc::ArbitrationType, s32, s64)>
351void SvcWrap64(Core::System& system) { 383void SvcWrap64(Core::System& system) {
diff --git a/src/core/hle/service/acc/async_context.cpp b/src/core/hle/service/acc/async_context.cpp
index c85b2e43a..713689d8f 100644
--- a/src/core/hle/service/acc/async_context.cpp
+++ b/src/core/hle/service/acc/async_context.cpp
@@ -64,7 +64,7 @@ void IAsyncContext::GetResult(Kernel::HLERequestContext& ctx) {
64 64
65void IAsyncContext::MarkComplete() { 65void IAsyncContext::MarkComplete() {
66 is_complete.store(true); 66 is_complete.store(true);
67 completion_event->GetWritableEvent().Signal(); 67 completion_event->Signal();
68} 68}
69 69
70} // namespace Service::Account 70} // namespace Service::Account
diff --git a/src/core/hle/service/am/am.cpp b/src/core/hle/service/am/am.cpp
index 6fb7e198e..e55233054 100644
--- a/src/core/hle/service/am/am.cpp
+++ b/src/core/hle/service/am/am.cpp
@@ -316,7 +316,7 @@ ISelfController::ISelfController(Core::System& system_, NVFlinger::NVFlinger& nv
316 316
317 accumulated_suspended_tick_changed_event = 317 accumulated_suspended_tick_changed_event =
318 service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent"); 318 service_context.CreateEvent("ISelfController:AccumulatedSuspendedTickChangedEvent");
319 accumulated_suspended_tick_changed_event->GetWritableEvent().Signal(); 319 accumulated_suspended_tick_changed_event->Signal();
320} 320}
321 321
322ISelfController::~ISelfController() { 322ISelfController::~ISelfController() {
@@ -378,7 +378,7 @@ void ISelfController::LeaveFatalSection(Kernel::HLERequestContext& ctx) {
378void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) { 378void ISelfController::GetLibraryAppletLaunchableEvent(Kernel::HLERequestContext& ctx) {
379 LOG_WARNING(Service_AM, "(STUBBED) called"); 379 LOG_WARNING(Service_AM, "(STUBBED) called");
380 380
381 launchable_event->GetWritableEvent().Signal(); 381 launchable_event->Signal();
382 382
383 IPC::ResponseBuilder rb{ctx, 2, 1}; 383 IPC::ResponseBuilder rb{ctx, 2, 1};
384 rb.Push(ResultSuccess); 384 rb.Push(ResultSuccess);
@@ -618,18 +618,18 @@ Kernel::KReadableEvent& AppletMessageQueue::GetOperationModeChangedEvent() {
618 618
619void AppletMessageQueue::PushMessage(AppletMessage msg) { 619void AppletMessageQueue::PushMessage(AppletMessage msg) {
620 messages.push(msg); 620 messages.push(msg);
621 on_new_message->GetWritableEvent().Signal(); 621 on_new_message->Signal();
622} 622}
623 623
624AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() { 624AppletMessageQueue::AppletMessage AppletMessageQueue::PopMessage() {
625 if (messages.empty()) { 625 if (messages.empty()) {
626 on_new_message->GetWritableEvent().Clear(); 626 on_new_message->Clear();
627 return AppletMessage::None; 627 return AppletMessage::None;
628 } 628 }
629 auto msg = messages.front(); 629 auto msg = messages.front();
630 messages.pop(); 630 messages.pop();
631 if (messages.empty()) { 631 if (messages.empty()) {
632 on_new_message->GetWritableEvent().Clear(); 632 on_new_message->Clear();
633 } 633 }
634 return msg; 634 return msg;
635} 635}
@@ -653,7 +653,7 @@ void AppletMessageQueue::FocusStateChanged() {
653void AppletMessageQueue::OperationModeChanged() { 653void AppletMessageQueue::OperationModeChanged() {
654 PushMessage(AppletMessage::OperationModeChanged); 654 PushMessage(AppletMessage::OperationModeChanged);
655 PushMessage(AppletMessage::PerformanceModeChanged); 655 PushMessage(AppletMessage::PerformanceModeChanged);
656 on_operation_mode_changed->GetWritableEvent().Signal(); 656 on_operation_mode_changed->Signal();
657} 657}
658 658
659ICommonStateGetter::ICommonStateGetter(Core::System& system_, 659ICommonStateGetter::ICommonStateGetter(Core::System& system_,
diff --git a/src/core/hle/service/am/applets/applets.cpp b/src/core/hle/service/am/applets/applets.cpp
index b5b8e4cad..7062df21c 100644
--- a/src/core/hle/service/am/applets/applets.cpp
+++ b/src/core/hle/service/am/applets/applets.cpp
@@ -65,7 +65,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopNormalDataToGame() {
65 65
66 auto out = std::move(out_channel.front()); 66 auto out = std::move(out_channel.front());
67 out_channel.pop_front(); 67 out_channel.pop_front();
68 pop_out_data_event->GetWritableEvent().Clear(); 68 pop_out_data_event->Clear();
69 return out; 69 return out;
70} 70}
71 71
@@ -84,7 +84,7 @@ std::shared_ptr<IStorage> AppletDataBroker::PopInteractiveDataToGame() {
84 84
85 auto out = std::move(out_interactive_channel.front()); 85 auto out = std::move(out_interactive_channel.front());
86 out_interactive_channel.pop_front(); 86 out_interactive_channel.pop_front();
87 pop_interactive_out_data_event->GetWritableEvent().Clear(); 87 pop_interactive_out_data_event->Clear();
88 return out; 88 return out;
89} 89}
90 90
@@ -103,7 +103,7 @@ void AppletDataBroker::PushNormalDataFromGame(std::shared_ptr<IStorage>&& storag
103 103
104void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) { 104void AppletDataBroker::PushNormalDataFromApplet(std::shared_ptr<IStorage>&& storage) {
105 out_channel.emplace_back(std::move(storage)); 105 out_channel.emplace_back(std::move(storage));
106 pop_out_data_event->GetWritableEvent().Signal(); 106 pop_out_data_event->Signal();
107} 107}
108 108
109void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) { 109void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& storage) {
@@ -112,11 +112,11 @@ void AppletDataBroker::PushInteractiveDataFromGame(std::shared_ptr<IStorage>&& s
112 112
113void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) { 113void AppletDataBroker::PushInteractiveDataFromApplet(std::shared_ptr<IStorage>&& storage) {
114 out_interactive_channel.emplace_back(std::move(storage)); 114 out_interactive_channel.emplace_back(std::move(storage));
115 pop_interactive_out_data_event->GetWritableEvent().Signal(); 115 pop_interactive_out_data_event->Signal();
116} 116}
117 117
118void AppletDataBroker::SignalStateChanged() { 118void AppletDataBroker::SignalStateChanged() {
119 state_changed_event->GetWritableEvent().Signal(); 119 state_changed_event->Signal();
120 120
121 switch (applet_mode) { 121 switch (applet_mode) {
122 case LibraryAppletMode::AllForeground: 122 case LibraryAppletMode::AllForeground:
diff --git a/src/core/hle/service/audio/audren_u.cpp b/src/core/hle/service/audio/audren_u.cpp
index 6fb07c37d..60c30cd5b 100644
--- a/src/core/hle/service/audio/audren_u.cpp
+++ b/src/core/hle/service/audio/audren_u.cpp
@@ -239,7 +239,7 @@ public:
239 }; 239 };
240 RegisterHandlers(functions); 240 RegisterHandlers(functions);
241 241
242 event->GetWritableEvent().Signal(); 242 event->Signal();
243 } 243 }
244 244
245 ~IAudioDevice() override { 245 ~IAudioDevice() override {
@@ -325,7 +325,7 @@ private:
325 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) { 325 void QueryAudioDeviceSystemEvent(Kernel::HLERequestContext& ctx) {
326 LOG_DEBUG(Service_Audio, "(STUBBED) called"); 326 LOG_DEBUG(Service_Audio, "(STUBBED) called");
327 327
328 event->GetWritableEvent().Signal(); 328 event->Signal();
329 329
330 IPC::ResponseBuilder rb{ctx, 2, 1}; 330 IPC::ResponseBuilder rb{ctx, 2, 1};
331 rb.Push(ResultSuccess); 331 rb.Push(ResultSuccess);
diff --git a/src/core/hle/service/bcat/backend/backend.cpp b/src/core/hle/service/bcat/backend/backend.cpp
index cd0b405ff..847f76987 100644
--- a/src/core/hle/service/bcat/backend/backend.cpp
+++ b/src/core/hle/service/bcat/backend/backend.cpp
@@ -82,7 +82,7 @@ void ProgressServiceBackend::FinishDownload(Result result) {
82} 82}
83 83
84void ProgressServiceBackend::SignalUpdate() { 84void ProgressServiceBackend::SignalUpdate() {
85 update_event->GetWritableEvent().Signal(); 85 update_event->Signal();
86} 86}
87 87
88Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {} 88Backend::Backend(DirectoryGetter getter) : dir_getter(std::move(getter)) {}
diff --git a/src/core/hle/service/hid/controllers/npad.cpp b/src/core/hle/service/hid/controllers/npad.cpp
index f8972ec7a..98e4f2af7 100644
--- a/src/core/hle/service/hid/controllers/npad.cpp
+++ b/src/core/hle/service/hid/controllers/npad.cpp
@@ -16,7 +16,6 @@
16#include "core/hid/hid_core.h" 16#include "core/hid/hid_core.h"
17#include "core/hle/kernel/k_event.h" 17#include "core/hle/kernel/k_event.h"
18#include "core/hle/kernel/k_readable_event.h" 18#include "core/hle/kernel/k_readable_event.h"
19#include "core/hle/kernel/k_writable_event.h"
20#include "core/hle/service/hid/controllers/npad.h" 19#include "core/hle/service/hid/controllers/npad.h"
21#include "core/hle/service/hid/errors.h" 20#include "core/hle/service/hid/errors.h"
22#include "core/hle/service/kernel_helpers.h" 21#include "core/hle/service/kernel_helpers.h"
@@ -167,7 +166,7 @@ void Controller_NPad::InitNewlyAddedController(Core::HID::NpadIdType npad_id) {
167 const auto& battery_level = controller.device->GetBattery(); 166 const auto& battery_level = controller.device->GetBattery();
168 auto* shared_memory = controller.shared_memory; 167 auto* shared_memory = controller.shared_memory;
169 if (controller_type == Core::HID::NpadStyleIndex::None) { 168 if (controller_type == Core::HID::NpadStyleIndex::None) {
170 controller.styleset_changed_event->GetWritableEvent().Signal(); 169 controller.styleset_changed_event->Signal();
171 return; 170 return;
172 } 171 }
173 172
@@ -1033,7 +1032,7 @@ Kernel::KReadableEvent& Controller_NPad::GetStyleSetChangedEvent(Core::HID::Npad
1033 1032
1034void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const { 1033void Controller_NPad::SignalStyleSetChangedEvent(Core::HID::NpadIdType npad_id) const {
1035 const auto& controller = GetControllerFromNpadIdType(npad_id); 1034 const auto& controller = GetControllerFromNpadIdType(npad_id);
1036 controller.styleset_changed_event->GetWritableEvent().Signal(); 1035 controller.styleset_changed_event->Signal();
1037} 1036}
1038 1037
1039void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller, 1038void Controller_NPad::AddNewControllerAt(Core::HID::NpadStyleIndex controller,
diff --git a/src/core/hle/service/hid/controllers/palma.cpp b/src/core/hle/service/hid/controllers/palma.cpp
index 575d4e626..4564ea1e2 100644
--- a/src/core/hle/service/hid/controllers/palma.cpp
+++ b/src/core/hle/service/hid/controllers/palma.cpp
@@ -73,7 +73,7 @@ Result Controller_Palma::PlayPalmaActivity(const PalmaConnectionHandle& handle,
73 operation.operation = PalmaOperationType::PlayActivity; 73 operation.operation = PalmaOperationType::PlayActivity;
74 operation.result = PalmaResultSuccess; 74 operation.result = PalmaResultSuccess;
75 operation.data = {}; 75 operation.data = {};
76 operation_complete_event->GetWritableEvent().Signal(); 76 operation_complete_event->Signal();
77 return ResultSuccess; 77 return ResultSuccess;
78} 78}
79 79
@@ -93,7 +93,7 @@ Result Controller_Palma::ReadPalmaStep(const PalmaConnectionHandle& handle) {
93 operation.operation = PalmaOperationType::ReadStep; 93 operation.operation = PalmaOperationType::ReadStep;
94 operation.result = PalmaResultSuccess; 94 operation.result = PalmaResultSuccess;
95 operation.data = {}; 95 operation.data = {};
96 operation_complete_event->GetWritableEvent().Signal(); 96 operation_complete_event->Signal();
97 return ResultSuccess; 97 return ResultSuccess;
98} 98}
99 99
@@ -122,7 +122,7 @@ Result Controller_Palma::ReadPalmaUniqueCode(const PalmaConnectionHandle& handle
122 operation.operation = PalmaOperationType::ReadUniqueCode; 122 operation.operation = PalmaOperationType::ReadUniqueCode;
123 operation.result = PalmaResultSuccess; 123 operation.result = PalmaResultSuccess;
124 operation.data = {}; 124 operation.data = {};
125 operation_complete_event->GetWritableEvent().Signal(); 125 operation_complete_event->Signal();
126 return ResultSuccess; 126 return ResultSuccess;
127} 127}
128 128
@@ -133,7 +133,7 @@ Result Controller_Palma::SetPalmaUniqueCodeInvalid(const PalmaConnectionHandle&
133 operation.operation = PalmaOperationType::SetUniqueCodeInvalid; 133 operation.operation = PalmaOperationType::SetUniqueCodeInvalid;
134 operation.result = PalmaResultSuccess; 134 operation.result = PalmaResultSuccess;
135 operation.data = {}; 135 operation.data = {};
136 operation_complete_event->GetWritableEvent().Signal(); 136 operation_complete_event->Signal();
137 return ResultSuccess; 137 return ResultSuccess;
138} 138}
139 139
@@ -147,7 +147,7 @@ Result Controller_Palma::WritePalmaRgbLedPatternEntry(const PalmaConnectionHandl
147 operation.operation = PalmaOperationType::WriteRgbLedPatternEntry; 147 operation.operation = PalmaOperationType::WriteRgbLedPatternEntry;
148 operation.result = PalmaResultSuccess; 148 operation.result = PalmaResultSuccess;
149 operation.data = {}; 149 operation.data = {};
150 operation_complete_event->GetWritableEvent().Signal(); 150 operation_complete_event->Signal();
151 return ResultSuccess; 151 return ResultSuccess;
152} 152}
153 153
@@ -159,7 +159,7 @@ Result Controller_Palma::WritePalmaWaveEntry(const PalmaConnectionHandle& handle
159 operation.operation = PalmaOperationType::WriteWaveEntry; 159 operation.operation = PalmaOperationType::WriteWaveEntry;
160 operation.result = PalmaResultSuccess; 160 operation.result = PalmaResultSuccess;
161 operation.data = {}; 161 operation.data = {};
162 operation_complete_event->GetWritableEvent().Signal(); 162 operation_complete_event->Signal();
163 return ResultSuccess; 163 return ResultSuccess;
164} 164}
165 165
@@ -172,7 +172,7 @@ Result Controller_Palma::SetPalmaDataBaseIdentificationVersion(const PalmaConnec
172 operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion; 172 operation.operation = PalmaOperationType::ReadDataBaseIdentificationVersion;
173 operation.result = PalmaResultSuccess; 173 operation.result = PalmaResultSuccess;
174 operation.data[0] = {}; 174 operation.data[0] = {};
175 operation_complete_event->GetWritableEvent().Signal(); 175 operation_complete_event->Signal();
176 return ResultSuccess; 176 return ResultSuccess;
177} 177}
178 178
@@ -185,7 +185,7 @@ Result Controller_Palma::GetPalmaDataBaseIdentificationVersion(
185 operation.result = PalmaResultSuccess; 185 operation.result = PalmaResultSuccess;
186 operation.data = {}; 186 operation.data = {};
187 operation.data[0] = static_cast<u8>(database_id_version); 187 operation.data[0] = static_cast<u8>(database_id_version);
188 operation_complete_event->GetWritableEvent().Signal(); 188 operation_complete_event->Signal();
189 return ResultSuccess; 189 return ResultSuccess;
190} 190}
191 191
diff --git a/src/core/hle/service/hid/hid.cpp b/src/core/hle/service/hid/hid.cpp
index 46bad7871..79375bd2f 100644
--- a/src/core/hle/service/hid/hid.cpp
+++ b/src/core/hle/service/hid/hid.cpp
@@ -2118,7 +2118,7 @@ void Hid::WritePalmaWaveEntry(Kernel::HLERequestContext& ctx) {
2118 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size"); 2118 ASSERT_MSG(t_mem->GetSize() == 0x3000, "t_mem has incorrect size");
2119 2119
2120 LOG_WARNING(Service_HID, 2120 LOG_WARNING(Service_HID,
2121 "(STUBBED) called, connection_handle={}, wave_set={}, unkown={}, " 2121 "(STUBBED) called, connection_handle={}, wave_set={}, unknown={}, "
2122 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}", 2122 "t_mem_handle=0x{:08X}, t_mem_size={}, size={}",
2123 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size); 2123 connection_handle.npad_id, wave_set, unknown, t_mem_handle, t_mem_size, size);
2124 2124
diff --git a/src/core/hle/service/hid/hidbus/ringcon.cpp b/src/core/hle/service/hid/hidbus/ringcon.cpp
index ad223d649..57f1a2a26 100644
--- a/src/core/hle/service/hid/hidbus/ringcon.cpp
+++ b/src/core/hle/service/hid/hidbus/ringcon.cpp
@@ -131,12 +131,12 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
131 case RingConCommands::ReadRepCount: 131 case RingConCommands::ReadRepCount:
132 case RingConCommands::ReadTotalPushCount: 132 case RingConCommands::ReadTotalPushCount:
133 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); 133 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
134 send_command_async_event->GetWritableEvent().Signal(); 134 send_command_async_event->Signal();
135 return true; 135 return true;
136 case RingConCommands::ResetRepCount: 136 case RingConCommands::ResetRepCount:
137 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes"); 137 ASSERT_MSG(data.size() == 0x4, "data.size is not 0x4 bytes");
138 total_rep_count = 0; 138 total_rep_count = 0;
139 send_command_async_event->GetWritableEvent().Signal(); 139 send_command_async_event->Signal();
140 return true; 140 return true;
141 case RingConCommands::SaveCalData: { 141 case RingConCommands::SaveCalData: {
142 ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes"); 142 ASSERT_MSG(data.size() == 0x14, "data.size is not 0x14 bytes");
@@ -144,14 +144,14 @@ bool RingController::SetCommand(const std::vector<u8>& data) {
144 SaveCalData save_info{}; 144 SaveCalData save_info{};
145 std::memcpy(&save_info, data.data(), sizeof(SaveCalData)); 145 std::memcpy(&save_info, data.data(), sizeof(SaveCalData));
146 user_calibration = save_info.calibration; 146 user_calibration = save_info.calibration;
147 send_command_async_event->GetWritableEvent().Signal(); 147 send_command_async_event->Signal();
148 return true; 148 return true;
149 } 149 }
150 default: 150 default:
151 LOG_ERROR(Service_HID, "Command not implemented {}", command); 151 LOG_ERROR(Service_HID, "Command not implemented {}", command);
152 command = RingConCommands::Error; 152 command = RingConCommands::Error;
153 // Signal a reply to avoid softlocking the game 153 // Signal a reply to avoid softlocking the game
154 send_command_async_event->GetWritableEvent().Signal(); 154 send_command_async_event->Signal();
155 return false; 155 return false;
156 } 156 }
157} 157}
diff --git a/src/core/hle/service/hid/irsensor/pointing_processor.h b/src/core/hle/service/hid/irsensor/pointing_processor.h
index cf4930794..d63423aff 100644
--- a/src/core/hle/service/hid/irsensor/pointing_processor.h
+++ b/src/core/hle/service/hid/irsensor/pointing_processor.h
@@ -37,10 +37,10 @@ private:
37 u8 pointing_status; 37 u8 pointing_status;
38 INSERT_PADDING_BYTES(3); 38 INSERT_PADDING_BYTES(3);
39 u32 unknown; 39 u32 unknown;
40 float unkown_float1; 40 float unknown_float1;
41 float position_x; 41 float position_x;
42 float position_y; 42 float position_y;
43 float unkown_float2; 43 float unknown_float2;
44 Core::IrSensor::IrsRect window_of_interest; 44 Core::IrSensor::IrsRect window_of_interest;
45 }; 45 };
46 static_assert(sizeof(PointingProcessorMarkerData) == 0x20, 46 static_assert(sizeof(PointingProcessorMarkerData) == 0x20,
diff --git a/src/core/hle/service/kernel_helpers.cpp b/src/core/hle/service/kernel_helpers.cpp
index 3e317367b..af133af93 100644
--- a/src/core/hle/service/kernel_helpers.cpp
+++ b/src/core/hle/service/kernel_helpers.cpp
@@ -9,7 +9,6 @@
9#include "core/hle/kernel/k_readable_event.h" 9#include "core/hle/kernel/k_readable_event.h"
10#include "core/hle/kernel/k_resource_limit.h" 10#include "core/hle/kernel/k_resource_limit.h"
11#include "core/hle/kernel/k_scoped_resource_reservation.h" 11#include "core/hle/kernel/k_scoped_resource_reservation.h"
12#include "core/hle/kernel/k_writable_event.h"
13#include "core/hle/service/kernel_helpers.h" 12#include "core/hle/service/kernel_helpers.h"
14 13
15namespace Service::KernelHelpers { 14namespace Service::KernelHelpers {
@@ -46,7 +45,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
46 } 45 }
47 46
48 // Initialize the event. 47 // Initialize the event.
49 event->Initialize(std::move(name), process); 48 event->Initialize(process);
50 49
51 // Commit the thread reservation. 50 // Commit the thread reservation.
52 event_reservation.Commit(); 51 event_reservation.Commit();
@@ -59,7 +58,7 @@ Kernel::KEvent* ServiceContext::CreateEvent(std::string&& name) {
59 58
60void ServiceContext::CloseEvent(Kernel::KEvent* event) { 59void ServiceContext::CloseEvent(Kernel::KEvent* event) {
61 event->GetReadableEvent().Close(); 60 event->GetReadableEvent().Close();
62 event->GetWritableEvent().Close(); 61 event->Close();
63} 62}
64 63
65} // namespace Service::KernelHelpers 64} // namespace Service::KernelHelpers
diff --git a/src/core/hle/service/ldn/ldn.cpp b/src/core/hle/service/ldn/ldn.cpp
index ea3e7e55a..6df563136 100644
--- a/src/core/hle/service/ldn/ldn.cpp
+++ b/src/core/hle/service/ldn/ldn.cpp
@@ -165,7 +165,7 @@ public:
165 } 165 }
166 166
167 void OnEventFired() { 167 void OnEventFired() {
168 state_change_event->GetWritableEvent().Signal(); 168 state_change_event->Signal();
169 } 169 }
170 170
171 void GetState(Kernel::HLERequestContext& ctx) { 171 void GetState(Kernel::HLERequestContext& ctx) {
diff --git a/src/core/hle/service/nfp/nfp_device.cpp b/src/core/hle/service/nfp/nfp_device.cpp
index ec895ac01..76f8a267a 100644
--- a/src/core/hle/service/nfp/nfp_device.cpp
+++ b/src/core/hle/service/nfp/nfp_device.cpp
@@ -58,7 +58,7 @@ NfpDevice::~NfpDevice() {
58void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) { 58void NfpDevice::NpadUpdate(Core::HID::ControllerTriggerType type) {
59 if (type == Core::HID::ControllerTriggerType::Connected || 59 if (type == Core::HID::ControllerTriggerType::Connected ||
60 type == Core::HID::ControllerTriggerType::Disconnected) { 60 type == Core::HID::ControllerTriggerType::Disconnected) {
61 availability_change_event->GetWritableEvent().Signal(); 61 availability_change_event->Signal();
62 return; 62 return;
63 } 63 }
64 64
@@ -100,7 +100,7 @@ bool NfpDevice::LoadAmiibo(std::span<const u8> data) {
100 100
101 device_state = DeviceState::TagFound; 101 device_state = DeviceState::TagFound;
102 deactivate_event->GetReadableEvent().Clear(); 102 deactivate_event->GetReadableEvent().Clear();
103 activate_event->GetWritableEvent().Signal(); 103 activate_event->Signal();
104 return true; 104 return true;
105} 105}
106 106
@@ -115,7 +115,7 @@ void NfpDevice::CloseAmiibo() {
115 encrypted_tag_data = {}; 115 encrypted_tag_data = {};
116 tag_data = {}; 116 tag_data = {};
117 activate_event->GetReadableEvent().Clear(); 117 activate_event->GetReadableEvent().Clear();
118 deactivate_event->GetWritableEvent().Signal(); 118 deactivate_event->Signal();
119} 119}
120 120
121Kernel::KReadableEvent& NfpDevice::GetActivateEvent() const { 121Kernel::KReadableEvent& NfpDevice::GetActivateEvent() const {
diff --git a/src/core/hle/service/nim/nim.cpp b/src/core/hle/service/nim/nim.cpp
index b2bb7426d..5a8a91e0b 100644
--- a/src/core/hle/service/nim/nim.cpp
+++ b/src/core/hle/service/nim/nim.cpp
@@ -328,7 +328,7 @@ private:
328 void StartTask(Kernel::HLERequestContext& ctx) { 328 void StartTask(Kernel::HLERequestContext& ctx) {
329 // No need to connect to the internet, just finish the task straight away. 329 // No need to connect to the internet, just finish the task straight away.
330 LOG_DEBUG(Service_NIM, "called"); 330 LOG_DEBUG(Service_NIM, "called");
331 finished_event->GetWritableEvent().Signal(); 331 finished_event->Signal();
332 IPC::ResponseBuilder rb{ctx, 2}; 332 IPC::ResponseBuilder rb{ctx, 2};
333 rb.Push(ResultSuccess); 333 rb.Push(ResultSuccess);
334 } 334 }
@@ -350,7 +350,7 @@ private:
350 350
351 void Cancel(Kernel::HLERequestContext& ctx) { 351 void Cancel(Kernel::HLERequestContext& ctx) {
352 LOG_DEBUG(Service_NIM, "called"); 352 LOG_DEBUG(Service_NIM, "called");
353 finished_event->GetWritableEvent().Clear(); 353 finished_event->Clear();
354 IPC::ResponseBuilder rb{ctx, 2}; 354 IPC::ResponseBuilder rb{ctx, 2};
355 rb.Push(ResultSuccess); 355 rb.Push(ResultSuccess);
356 } 356 }
diff --git a/src/core/hle/service/ns/ns.cpp b/src/core/hle/service/ns/ns.cpp
index f7318c3cb..f59a1a63d 100644
--- a/src/core/hle/service/ns/ns.cpp
+++ b/src/core/hle/service/ns/ns.cpp
@@ -8,6 +8,7 @@
8#include "core/file_sys/patch_manager.h" 8#include "core/file_sys/patch_manager.h"
9#include "core/file_sys/vfs.h" 9#include "core/file_sys/vfs.h"
10#include "core/hle/ipc_helpers.h" 10#include "core/hle/ipc_helpers.h"
11#include "core/hle/service/glue/glue_manager.h"
11#include "core/hle/service/ns/errors.h" 12#include "core/hle/service/ns/errors.h"
12#include "core/hle/service/ns/iplatform_service_manager.h" 13#include "core/hle/service/ns/iplatform_service_manager.h"
13#include "core/hle/service/ns/language.h" 14#include "core/hle/service/ns/language.h"
@@ -581,7 +582,7 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
581 : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} { 582 : ServiceFramework{system_, "IReadOnlyApplicationControlDataInterface"} {
582 // clang-format off 583 // clang-format off
583 static const FunctionInfo functions[] = { 584 static const FunctionInfo functions[] = {
584 {0, nullptr, "GetApplicationControlData"}, 585 {0, &IReadOnlyApplicationControlDataInterface::GetApplicationControlData, "GetApplicationControlData"},
585 {1, nullptr, "GetApplicationDesiredLanguage"}, 586 {1, nullptr, "GetApplicationDesiredLanguage"},
586 {2, nullptr, "ConvertApplicationLanguageToLanguageCode"}, 587 {2, nullptr, "ConvertApplicationLanguageToLanguageCode"},
587 {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"}, 588 {3, nullptr, "ConvertLanguageCodeToApplicationLanguage"},
@@ -594,6 +595,33 @@ IReadOnlyApplicationControlDataInterface::IReadOnlyApplicationControlDataInterfa
594 595
595IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default; 596IReadOnlyApplicationControlDataInterface::~IReadOnlyApplicationControlDataInterface() = default;
596 597
598void IReadOnlyApplicationControlDataInterface::GetApplicationControlData(
599 Kernel::HLERequestContext& ctx) {
600 enum class ApplicationControlSource : u8 {
601 CacheOnly,
602 Storage,
603 StorageOnly,
604 };
605
606 struct RequestParameters {
607 ApplicationControlSource source;
608 u64 application_id;
609 };
610 static_assert(sizeof(RequestParameters) == 0x10, "RequestParameters has incorrect size.");
611
612 IPC::RequestParser rp{ctx};
613 const auto parameters{rp.PopRaw<RequestParameters>()};
614 const auto nacp_data{system.GetARPManager().GetControlProperty(parameters.application_id)};
615 const auto result = nacp_data ? ResultSuccess : ResultUnknown;
616
617 if (nacp_data) {
618 ctx.WriteBuffer(nacp_data->data(), nacp_data->size());
619 }
620
621 IPC::ResponseBuilder rb{ctx, 2};
622 rb.Push(result);
623}
624
597NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} { 625NS::NS(const char* name, Core::System& system_) : ServiceFramework{system_, name} {
598 // clang-format off 626 // clang-format off
599 static const FunctionInfo functions[] = { 627 static const FunctionInfo functions[] = {
diff --git a/src/core/hle/service/ns/ns.h b/src/core/hle/service/ns/ns.h
index 4dc191518..9c18e935c 100644
--- a/src/core/hle/service/ns/ns.h
+++ b/src/core/hle/service/ns/ns.h
@@ -78,6 +78,9 @@ class IReadOnlyApplicationControlDataInterface final
78public: 78public:
79 explicit IReadOnlyApplicationControlDataInterface(Core::System& system_); 79 explicit IReadOnlyApplicationControlDataInterface(Core::System& system_);
80 ~IReadOnlyApplicationControlDataInterface() override; 80 ~IReadOnlyApplicationControlDataInterface() override;
81
82private:
83 void GetApplicationControlData(Kernel::HLERequestContext& ctx);
81}; 84};
82 85
83class NS final : public ServiceFramework<NS> { 86class NS final : public ServiceFramework<NS> {
diff --git a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
index 5bee4a3d3..eee11fab8 100644
--- a/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
+++ b/src/core/hle/service/nvdrv/devices/nvhost_ctrl.cpp
@@ -12,7 +12,6 @@
12#include "common/scope_exit.h" 12#include "common/scope_exit.h"
13#include "core/core.h" 13#include "core/core.h"
14#include "core/hle/kernel/k_event.h" 14#include "core/hle/kernel/k_event.h"
15#include "core/hle/kernel/k_writable_event.h"
16#include "core/hle/service/nvdrv/core/container.h" 15#include "core/hle/service/nvdrv/core/container.h"
17#include "core/hle/service/nvdrv/core/syncpoint_manager.h" 16#include "core/hle/service/nvdrv/core/syncpoint_manager.h"
18#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h" 17#include "core/hle/service/nvdrv/devices/nvhost_ctrl.h"
@@ -206,7 +205,7 @@ NvResult nvhost_ctrl::IocCtrlEventWait(const std::vector<u8>& input, std::vector
206 auto& event_ = events[slot]; 205 auto& event_ = events[slot];
207 if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) == 206 if (event_.status.exchange(EventState::Signalling, std::memory_order_acq_rel) ==
208 EventState::Waiting) { 207 EventState::Waiting) {
209 event_.kevent->GetWritableEvent().Signal(); 208 event_.kevent->Signal();
210 } 209 }
211 event_.status.store(EventState::Signalled, std::memory_order_release); 210 event_.status.store(EventState::Signalled, std::memory_order_release);
212 }); 211 });
@@ -306,7 +305,7 @@ NvResult nvhost_ctrl::IocCtrlClearEventWait(const std::vector<u8>& input, std::v
306 } 305 }
307 event.fails++; 306 event.fails++;
308 event.status.store(EventState::Cancelled, std::memory_order_release); 307 event.status.store(EventState::Cancelled, std::memory_order_release);
309 event.kevent->GetWritableEvent().Clear(); 308 event.kevent->Clear();
310 309
311 return NvResult::Success; 310 return NvResult::Success;
312} 311}
diff --git a/src/core/hle/service/nvdrv/nvdrv.cpp b/src/core/hle/service/nvdrv/nvdrv.cpp
index 5e7b7468f..9d9924395 100644
--- a/src/core/hle/service/nvdrv/nvdrv.cpp
+++ b/src/core/hle/service/nvdrv/nvdrv.cpp
@@ -8,7 +8,6 @@
8#include "core/core.h" 8#include "core/core.h"
9#include "core/hle/ipc_helpers.h" 9#include "core/hle/ipc_helpers.h"
10#include "core/hle/kernel/k_event.h" 10#include "core/hle/kernel/k_event.h"
11#include "core/hle/kernel/k_writable_event.h"
12#include "core/hle/service/nvdrv/core/container.h" 11#include "core/hle/service/nvdrv/core/container.h"
13#include "core/hle/service/nvdrv/devices/nvdevice.h" 12#include "core/hle/service/nvdrv/devices/nvdevice.h"
14#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h" 13#include "core/hle/service/nvdrv/devices/nvdisp_disp0.h"
diff --git a/src/core/hle/service/nvdrv/nvdrv_interface.h b/src/core/hle/service/nvdrv/nvdrv_interface.h
index cd58a4f35..5ac06ee30 100644
--- a/src/core/hle/service/nvdrv/nvdrv_interface.h
+++ b/src/core/hle/service/nvdrv/nvdrv_interface.h
@@ -7,10 +7,6 @@
7#include "core/hle/service/nvdrv/nvdrv.h" 7#include "core/hle/service/nvdrv/nvdrv.h"
8#include "core/hle/service/service.h" 8#include "core/hle/service/service.h"
9 9
10namespace Kernel {
11class KWritableEvent;
12}
13
14namespace Service::Nvidia { 10namespace Service::Nvidia {
15 11
16class NVDRV final : public ServiceFramework<NVDRV> { 12class NVDRV final : public ServiceFramework<NVDRV> {
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
index d4ab23a10..77ddbb6ef 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.cpp
@@ -11,7 +11,6 @@
11#include "core/hle/kernel/hle_ipc.h" 11#include "core/hle/kernel/hle_ipc.h"
12#include "core/hle/kernel/k_event.h" 12#include "core/hle/kernel/k_event.h"
13#include "core/hle/kernel/k_readable_event.h" 13#include "core/hle/kernel/k_readable_event.h"
14#include "core/hle/kernel/k_writable_event.h"
15#include "core/hle/kernel/kernel.h" 14#include "core/hle/kernel/kernel.h"
16#include "core/hle/service/kernel_helpers.h" 15#include "core/hle/service/kernel_helpers.h"
17#include "core/hle/service/nvdrv/core/nvmap.h" 16#include "core/hle/service/nvdrv/core/nvmap.h"
@@ -110,7 +109,7 @@ Status BufferQueueProducer::SetBufferCount(s32 buffer_count) {
110 109
111 core->override_max_buffer_count = buffer_count; 110 core->override_max_buffer_count = buffer_count;
112 core->SignalDequeueCondition(); 111 core->SignalDequeueCondition();
113 buffer_wait_event->GetWritableEvent().Signal(); 112 buffer_wait_event->Signal();
114 listener = core->consumer_listener; 113 listener = core->consumer_listener;
115 } 114 }
116 115
@@ -623,7 +622,7 @@ void BufferQueueProducer::CancelBuffer(s32 slot, const Fence& fence) {
623 slots[slot].fence = fence; 622 slots[slot].fence = fence;
624 623
625 core->SignalDequeueCondition(); 624 core->SignalDequeueCondition();
626 buffer_wait_event->GetWritableEvent().Signal(); 625 buffer_wait_event->Signal();
627} 626}
628 627
629Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) { 628Status BufferQueueProducer::Query(NativeWindow what, s32* out_value) {
@@ -753,7 +752,7 @@ Status BufferQueueProducer::Disconnect(NativeWindowApi api) {
753 core->connected_producer_listener = nullptr; 752 core->connected_producer_listener = nullptr;
754 core->connected_api = NativeWindowApi::NoConnectedApi; 753 core->connected_api = NativeWindowApi::NoConnectedApi;
755 core->SignalDequeueCondition(); 754 core->SignalDequeueCondition();
756 buffer_wait_event->GetWritableEvent().Signal(); 755 buffer_wait_event->Signal();
757 listener = core->consumer_listener; 756 listener = core->consumer_listener;
758 } else { 757 } else {
759 LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})", 758 LOG_ERROR(Service_NVFlinger, "still connected to another api (cur = {} req = {})",
@@ -802,7 +801,7 @@ Status BufferQueueProducer::SetPreallocatedBuffer(s32 slot,
802 } 801 }
803 802
804 core->SignalDequeueCondition(); 803 core->SignalDequeueCondition();
805 buffer_wait_event->GetWritableEvent().Signal(); 804 buffer_wait_event->Signal();
806 805
807 return Status::NoError; 806 return Status::NoError;
808} 807}
diff --git a/src/core/hle/service/nvflinger/buffer_queue_producer.h b/src/core/hle/service/nvflinger/buffer_queue_producer.h
index 0ba03a568..7526bf8ec 100644
--- a/src/core/hle/service/nvflinger/buffer_queue_producer.h
+++ b/src/core/hle/service/nvflinger/buffer_queue_producer.h
@@ -24,7 +24,6 @@ namespace Kernel {
24class KernelCore; 24class KernelCore;
25class KEvent; 25class KEvent;
26class KReadableEvent; 26class KReadableEvent;
27class KWritableEvent;
28} // namespace Kernel 27} // namespace Kernel
29 28
30namespace Service::KernelHelpers { 29namespace Service::KernelHelpers {
diff --git a/src/core/hle/service/nvflinger/nvflinger.h b/src/core/hle/service/nvflinger/nvflinger.h
index b62615de2..99509bc5b 100644
--- a/src/core/hle/service/nvflinger/nvflinger.h
+++ b/src/core/hle/service/nvflinger/nvflinger.h
@@ -25,7 +25,6 @@ struct EventType;
25 25
26namespace Kernel { 26namespace Kernel {
27class KReadableEvent; 27class KReadableEvent;
28class KWritableEvent;
29} // namespace Kernel 28} // namespace Kernel
30 29
31namespace Service::Nvidia { 30namespace Service::Nvidia {
diff --git a/src/core/hle/service/ptm/psm.cpp b/src/core/hle/service/ptm/psm.cpp
index 2c31e9485..1ac97fe31 100644
--- a/src/core/hle/service/ptm/psm.cpp
+++ b/src/core/hle/service/ptm/psm.cpp
@@ -37,19 +37,19 @@ public:
37 37
38 void SignalChargerTypeChanged() { 38 void SignalChargerTypeChanged() {
39 if (should_signal && should_signal_charger_type) { 39 if (should_signal && should_signal_charger_type) {
40 state_change_event->GetWritableEvent().Signal(); 40 state_change_event->Signal();
41 } 41 }
42 } 42 }
43 43
44 void SignalPowerSupplyChanged() { 44 void SignalPowerSupplyChanged() {
45 if (should_signal && should_signal_power_supply) { 45 if (should_signal && should_signal_power_supply) {
46 state_change_event->GetWritableEvent().Signal(); 46 state_change_event->Signal();
47 } 47 }
48 } 48 }
49 49
50 void SignalBatteryVoltageStateChanged() { 50 void SignalBatteryVoltageStateChanged() {
51 if (should_signal && should_signal_battery_voltage) { 51 if (should_signal && should_signal_battery_voltage) {
52 state_change_event->GetWritableEvent().Signal(); 52 state_change_event->Signal();
53 } 53 }
54 } 54 }
55 55
diff --git a/src/core/hle/service/ptm/ts.cpp b/src/core/hle/service/ptm/ts.cpp
index 65c3f135f..b1a0a5544 100644
--- a/src/core/hle/service/ptm/ts.cpp
+++ b/src/core/hle/service/ptm/ts.cpp
@@ -15,7 +15,7 @@ TS::TS(Core::System& system_) : ServiceFramework{system_, "ts"} {
15 {0, nullptr, "GetTemperatureRange"}, 15 {0, nullptr, "GetTemperatureRange"},
16 {1, &TS::GetTemperature, "GetTemperature"}, 16 {1, &TS::GetTemperature, "GetTemperature"},
17 {2, nullptr, "SetMeasurementMode"}, 17 {2, nullptr, "SetMeasurementMode"},
18 {3, nullptr, "GetTemperatureMilliC"}, 18 {3, &TS::GetTemperatureMilliC, "GetTemperatureMilliC"},
19 {4, nullptr, "OpenSession"}, 19 {4, nullptr, "OpenSession"},
20 }; 20 };
21 // clang-format on 21 // clang-format on
@@ -29,8 +29,6 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
29 IPC::RequestParser rp{ctx}; 29 IPC::RequestParser rp{ctx};
30 const auto location{rp.PopEnum<Location>()}; 30 const auto location{rp.PopEnum<Location>()};
31 31
32 LOG_WARNING(Service_HID, "(STUBBED) called. location={}", location);
33
34 const s32 temperature = location == Location::Internal ? 35 : 20; 32 const s32 temperature = location == Location::Internal ? 35 : 20;
35 33
36 IPC::ResponseBuilder rb{ctx, 3}; 34 IPC::ResponseBuilder rb{ctx, 3};
@@ -38,4 +36,15 @@ void TS::GetTemperature(Kernel::HLERequestContext& ctx) {
38 rb.Push(temperature); 36 rb.Push(temperature);
39} 37}
40 38
39void TS::GetTemperatureMilliC(Kernel::HLERequestContext& ctx) {
40 IPC::RequestParser rp{ctx};
41 const auto location{rp.PopEnum<Location>()};
42
43 const s32 temperature = location == Location::Internal ? 35000 : 20000;
44
45 IPC::ResponseBuilder rb{ctx, 3};
46 rb.Push(ResultSuccess);
47 rb.Push(temperature);
48}
49
41} // namespace Service::PTM 50} // namespace Service::PTM
diff --git a/src/core/hle/service/ptm/ts.h b/src/core/hle/service/ptm/ts.h
index 39a734ef7..39d51847e 100644
--- a/src/core/hle/service/ptm/ts.h
+++ b/src/core/hle/service/ptm/ts.h
@@ -20,6 +20,7 @@ private:
20 }; 20 };
21 21
22 void GetTemperature(Kernel::HLERequestContext& ctx); 22 void GetTemperature(Kernel::HLERequestContext& ctx);
23 void GetTemperatureMilliC(Kernel::HLERequestContext& ctx);
23}; 24};
24 25
25} // namespace Service::PTM 26} // namespace Service::PTM
diff --git a/src/core/hle/service/set/set_sys.cpp b/src/core/hle/service/set/set_sys.cpp
index 2a0b812c1..d7cea6aac 100644
--- a/src/core/hle/service/set/set_sys.cpp
+++ b/src/core/hle/service/set/set_sys.cpp
@@ -101,6 +101,81 @@ void SET_SYS::SetColorSetId(Kernel::HLERequestContext& ctx) {
101 rb.Push(ResultSuccess); 101 rb.Push(ResultSuccess);
102} 102}
103 103
104// FIXME: implement support for the real system_settings.ini
105
106template <typename T>
107static std::vector<u8> ToBytes(const T& value) {
108 static_assert(std::is_trivially_copyable_v<T>);
109
110 const auto* begin = reinterpret_cast<const u8*>(&value);
111 const auto* end = begin + sizeof(T);
112
113 return std::vector<u8>(begin, end);
114}
115
116using Settings =
117 std::map<std::string, std::map<std::string, std::vector<u8>, std::less<>>, std::less<>>;
118
119static Settings GetSettings() {
120 Settings ret;
121
122 ret["hbloader"]["applet_heap_size"] = ToBytes(u64{0x0});
123 ret["hbloader"]["applet_heap_reservation_size"] = ToBytes(u64{0x8600000});
124
125 return ret;
126}
127
128void SET_SYS::GetSettingsItemValueSize(Kernel::HLERequestContext& ctx) {
129 LOG_DEBUG(Service_SET, "called");
130
131 // The category of the setting. This corresponds to the top-level keys of
132 // system_settings.ini.
133 const auto setting_category_buf{ctx.ReadBuffer(0)};
134 const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
135
136 // The name of the setting. This corresponds to the second-level keys of
137 // system_settings.ini.
138 const auto setting_name_buf{ctx.ReadBuffer(1)};
139 const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
140
141 auto settings{GetSettings()};
142 u64 response_size{0};
143
144 if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
145 response_size = settings[setting_category][setting_name].size();
146 }
147
148 IPC::ResponseBuilder rb{ctx, 4};
149 rb.Push(response_size == 0 ? ResultUnknown : ResultSuccess);
150 rb.Push(response_size);
151}
152
153void SET_SYS::GetSettingsItemValue(Kernel::HLERequestContext& ctx) {
154 LOG_DEBUG(Service_SET, "called");
155
156 // The category of the setting. This corresponds to the top-level keys of
157 // system_settings.ini.
158 const auto setting_category_buf{ctx.ReadBuffer(0)};
159 const std::string setting_category{setting_category_buf.begin(), setting_category_buf.end()};
160
161 // The name of the setting. This corresponds to the second-level keys of
162 // system_settings.ini.
163 const auto setting_name_buf{ctx.ReadBuffer(1)};
164 const std::string setting_name{setting_name_buf.begin(), setting_name_buf.end()};
165
166 auto settings{GetSettings()};
167 Result response{ResultUnknown};
168
169 if (settings.contains(setting_category) && settings[setting_category].contains(setting_name)) {
170 auto setting_value = settings[setting_category][setting_name];
171 ctx.WriteBuffer(setting_value.data(), setting_value.size());
172 response = ResultSuccess;
173 }
174
175 IPC::ResponseBuilder rb{ctx, 2};
176 rb.Push(response);
177}
178
104SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} { 179SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
105 // clang-format off 180 // clang-format off
106 static const FunctionInfo functions[] = { 181 static const FunctionInfo functions[] = {
@@ -138,8 +213,8 @@ SET_SYS::SET_SYS(Core::System& system_) : ServiceFramework{system_, "set:sys"} {
138 {32, nullptr, "SetAccountNotificationSettings"}, 213 {32, nullptr, "SetAccountNotificationSettings"},
139 {35, nullptr, "GetVibrationMasterVolume"}, 214 {35, nullptr, "GetVibrationMasterVolume"},
140 {36, nullptr, "SetVibrationMasterVolume"}, 215 {36, nullptr, "SetVibrationMasterVolume"},
141 {37, nullptr, "GetSettingsItemValueSize"}, 216 {37, &SET_SYS::GetSettingsItemValueSize, "GetSettingsItemValueSize"},
142 {38, nullptr, "GetSettingsItemValue"}, 217 {38, &SET_SYS::GetSettingsItemValue, "GetSettingsItemValue"},
143 {39, nullptr, "GetTvSettings"}, 218 {39, nullptr, "GetTvSettings"},
144 {40, nullptr, "SetTvSettings"}, 219 {40, nullptr, "SetTvSettings"},
145 {41, nullptr, "GetEdid"}, 220 {41, nullptr, "GetEdid"},
diff --git a/src/core/hle/service/set/set_sys.h b/src/core/hle/service/set/set_sys.h
index ac97772b7..258ef8c57 100644
--- a/src/core/hle/service/set/set_sys.h
+++ b/src/core/hle/service/set/set_sys.h
@@ -23,6 +23,8 @@ private:
23 BasicBlack = 1, 23 BasicBlack = 1,
24 }; 24 };
25 25
26 void GetSettingsItemValueSize(Kernel::HLERequestContext& ctx);
27 void GetSettingsItemValue(Kernel::HLERequestContext& ctx);
26 void GetFirmwareVersion(Kernel::HLERequestContext& ctx); 28 void GetFirmwareVersion(Kernel::HLERequestContext& ctx);
27 void GetFirmwareVersion2(Kernel::HLERequestContext& ctx); 29 void GetFirmwareVersion2(Kernel::HLERequestContext& ctx);
28 void GetColorSetId(Kernel::HLERequestContext& ctx); 30 void GetColorSetId(Kernel::HLERequestContext& ctx);
diff --git a/src/core/hle/service/sm/sm.cpp b/src/core/hle/service/sm/sm.cpp
index 246c94623..48e70f93c 100644
--- a/src/core/hle/service/sm/sm.cpp
+++ b/src/core/hle/service/sm/sm.cpp
@@ -156,7 +156,8 @@ ResultVal<Kernel::KClientSession*> SM::GetServiceImpl(Kernel::HLERequestContext&
156 156
157 // Create a new session. 157 // Create a new session.
158 Kernel::KClientSession* session{}; 158 Kernel::KClientSession* session{};
159 if (const auto result = port->GetClientPort().CreateSession(std::addressof(session)); 159 if (const auto result = port->GetClientPort().CreateSession(
160 std::addressof(session), std::make_shared<Kernel::SessionRequestManager>(kernel));
160 result.IsError()) { 161 result.IsError()) {
161 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw); 162 LOG_ERROR(Service_SM, "called service={} -> error 0x{:08X}", name, result.raw);
162 return result; 163 return result;
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.cpp b/src/core/hle/service/time/system_clock_context_update_callback.cpp
index a649bed3a..cafc04ee7 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.cpp
+++ b/src/core/hle/service/time/system_clock_context_update_callback.cpp
@@ -1,7 +1,7 @@
1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2019 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#include "core/hle/kernel/k_writable_event.h" 4#include "core/hle/kernel/k_event.h"
5#include "core/hle/service/time/errors.h" 5#include "core/hle/service/time/errors.h"
6#include "core/hle/service/time/system_clock_context_update_callback.h" 6#include "core/hle/service/time/system_clock_context_update_callback.h"
7 7
@@ -20,13 +20,13 @@ bool SystemClockContextUpdateCallback::NeedUpdate(const SystemClockContext& valu
20} 20}
21 21
22void SystemClockContextUpdateCallback::RegisterOperationEvent( 22void SystemClockContextUpdateCallback::RegisterOperationEvent(
23 std::shared_ptr<Kernel::KWritableEvent>&& writable_event) { 23 std::shared_ptr<Kernel::KEvent>&& event) {
24 operation_event_list.emplace_back(std::move(writable_event)); 24 operation_event_list.emplace_back(std::move(event));
25} 25}
26 26
27void SystemClockContextUpdateCallback::BroadcastOperationEvent() { 27void SystemClockContextUpdateCallback::BroadcastOperationEvent() {
28 for (const auto& writable_event : operation_event_list) { 28 for (const auto& event : operation_event_list) {
29 writable_event->Signal(); 29 event->Signal();
30 } 30 }
31} 31}
32 32
diff --git a/src/core/hle/service/time/system_clock_context_update_callback.h b/src/core/hle/service/time/system_clock_context_update_callback.h
index 9c6caf196..bf657acd9 100644
--- a/src/core/hle/service/time/system_clock_context_update_callback.h
+++ b/src/core/hle/service/time/system_clock_context_update_callback.h
@@ -9,7 +9,7 @@
9#include "core/hle/service/time/clock_types.h" 9#include "core/hle/service/time/clock_types.h"
10 10
11namespace Kernel { 11namespace Kernel {
12class KWritableEvent; 12class KEvent;
13} 13}
14 14
15namespace Service::Time::Clock { 15namespace Service::Time::Clock {
@@ -24,7 +24,7 @@ public:
24 24
25 bool NeedUpdate(const SystemClockContext& value) const; 25 bool NeedUpdate(const SystemClockContext& value) const;
26 26
27 void RegisterOperationEvent(std::shared_ptr<Kernel::KWritableEvent>&& writable_event); 27 void RegisterOperationEvent(std::shared_ptr<Kernel::KEvent>&& event);
28 28
29 void BroadcastOperationEvent(); 29 void BroadcastOperationEvent();
30 30
@@ -37,7 +37,7 @@ protected:
37 37
38private: 38private:
39 bool has_context{}; 39 bool has_context{};
40 std::vector<std::shared_ptr<Kernel::KWritableEvent>> operation_event_list; 40 std::vector<std::shared_ptr<Kernel::KEvent>> operation_event_list;
41}; 41};
42 42
43} // namespace Service::Time::Clock 43} // namespace Service::Time::Clock
diff --git a/src/core/hle/service/vi/display/vi_display.cpp b/src/core/hle/service/vi/display/vi_display.cpp
index 288aafaaf..8ef74f1f0 100644
--- a/src/core/hle/service/vi/display/vi_display.cpp
+++ b/src/core/hle/service/vi/display/vi_display.cpp
@@ -10,7 +10,6 @@
10#include "core/core.h" 10#include "core/core.h"
11#include "core/hle/kernel/k_event.h" 11#include "core/hle/kernel/k_event.h"
12#include "core/hle/kernel/k_readable_event.h" 12#include "core/hle/kernel/k_readable_event.h"
13#include "core/hle/kernel/k_writable_event.h"
14#include "core/hle/service/kernel_helpers.h" 13#include "core/hle/service/kernel_helpers.h"
15#include "core/hle/service/nvdrv/core/container.h" 14#include "core/hle/service/nvdrv/core/container.h"
16#include "core/hle/service/nvflinger/buffer_item_consumer.h" 15#include "core/hle/service/nvflinger/buffer_item_consumer.h"
@@ -74,7 +73,7 @@ Kernel::KReadableEvent* Display::GetVSyncEventUnchecked() {
74} 73}
75 74
76void Display::SignalVSyncEvent() { 75void Display::SignalVSyncEvent() {
77 vsync_event->GetWritableEvent().Signal(); 76 vsync_event->Signal();
78} 77}
79 78
80void Display::CreateLayer(u64 layer_id, u32 binder_id, 79void Display::CreateLayer(u64 layer_id, u32 binder_id,
diff --git a/src/core/hle/service/vi/vi_results.h b/src/core/hle/service/vi/vi_results.h
index a46c247d2..22bac799f 100644
--- a/src/core/hle/service/vi/vi_results.h
+++ b/src/core/hle/service/vi/vi_results.h
@@ -1,6 +1,8 @@
1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project 1// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
2// SPDX-License-Identifier: GPL-2.0-or-later 2// SPDX-License-Identifier: GPL-2.0-or-later
3 3
4#pragma once
5
4#include "core/hle/result.h" 6#include "core/hle/result.h"
5 7
6namespace Service::VI { 8namespace Service::VI {
diff --git a/src/video_core/texture_cache/descriptor_table.h b/src/video_core/texture_cache/descriptor_table.h
index b18e3838f..ee4240288 100644
--- a/src/video_core/texture_cache/descriptor_table.h
+++ b/src/video_core/texture_cache/descriptor_table.h
@@ -18,7 +18,7 @@ class DescriptorTable {
18public: 18public:
19 explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {} 19 explicit DescriptorTable(Tegra::MemoryManager& gpu_memory_) : gpu_memory{gpu_memory_} {}
20 20
21 [[nodiscard]] bool Synchornize(GPUVAddr gpu_addr, u32 limit) { 21 [[nodiscard]] bool Synchronize(GPUVAddr gpu_addr, u32 limit) {
22 [[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) { 22 [[likely]] if (current_gpu_addr == gpu_addr && current_limit == limit) {
23 return false; 23 return false;
24 } 24 }
diff --git a/src/video_core/texture_cache/texture_cache.h b/src/video_core/texture_cache/texture_cache.h
index 413baf730..0e0fd410f 100644
--- a/src/video_core/texture_cache/texture_cache.h
+++ b/src/video_core/texture_cache/texture_cache.h
@@ -193,11 +193,11 @@ void TextureCache<P>::SynchronizeGraphicsDescriptors() {
193 const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding; 193 const bool linked_tsc = maxwell3d->regs.sampler_binding == SamplerBinding::ViaHeaderBinding;
194 const u32 tic_limit = maxwell3d->regs.tex_header.limit; 194 const u32 tic_limit = maxwell3d->regs.tex_header.limit;
195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit; 195 const u32 tsc_limit = linked_tsc ? tic_limit : maxwell3d->regs.tex_sampler.limit;
196 if (channel_state->graphics_sampler_table.Synchornize(maxwell3d->regs.tex_sampler.Address(), 196 if (channel_state->graphics_sampler_table.Synchronize(maxwell3d->regs.tex_sampler.Address(),
197 tsc_limit)) { 197 tsc_limit)) {
198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 198 channel_state->graphics_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
199 } 199 }
200 if (channel_state->graphics_image_table.Synchornize(maxwell3d->regs.tex_header.Address(), 200 if (channel_state->graphics_image_table.Synchronize(maxwell3d->regs.tex_header.Address(),
201 tic_limit)) { 201 tic_limit)) {
202 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 202 channel_state->graphics_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
203 } 203 }
@@ -209,10 +209,10 @@ void TextureCache<P>::SynchronizeComputeDescriptors() {
209 const u32 tic_limit = kepler_compute->regs.tic.limit; 209 const u32 tic_limit = kepler_compute->regs.tic.limit;
210 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit; 210 const u32 tsc_limit = linked_tsc ? tic_limit : kepler_compute->regs.tsc.limit;
211 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address(); 211 const GPUVAddr tsc_gpu_addr = kepler_compute->regs.tsc.Address();
212 if (channel_state->compute_sampler_table.Synchornize(tsc_gpu_addr, tsc_limit)) { 212 if (channel_state->compute_sampler_table.Synchronize(tsc_gpu_addr, tsc_limit)) {
213 channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID); 213 channel_state->compute_sampler_ids.resize(tsc_limit + 1, CORRUPT_ID);
214 } 214 }
215 if (channel_state->compute_image_table.Synchornize(kepler_compute->regs.tic.Address(), 215 if (channel_state->compute_image_table.Synchronize(kepler_compute->regs.tic.Address(),
216 tic_limit)) { 216 tic_limit)) {
217 channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID); 217 channel_state->compute_image_view_ids.resize(tic_limit + 1, CORRUPT_ID);
218 } 218 }
diff --git a/src/yuzu/main.cpp b/src/yuzu/main.cpp
index f45a25410..a94624be6 100644
--- a/src/yuzu/main.cpp
+++ b/src/yuzu/main.cpp
@@ -3280,7 +3280,7 @@ void GMainWindow::LoadAmiibo(const QString& filename) {
3280 QMessageBox::warning(this, title, tr("The current game is not looking for amiibos")); 3280 QMessageBox::warning(this, title, tr("The current game is not looking for amiibos"));
3281 break; 3281 break;
3282 case InputCommon::VirtualAmiibo::Info::Unknown: 3282 case InputCommon::VirtualAmiibo::Info::Unknown:
3283 QMessageBox::warning(this, title, tr("An unkown error occured")); 3283 QMessageBox::warning(this, title, tr("An unknown error occurred"));
3284 break; 3284 break;
3285 default: 3285 default:
3286 break; 3286 break;