diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 6f834984..8df95874 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -48,6 +48,7 @@ add_library(skyline SHARED ${source_DIR}/skyline/kernel/types/KThread.cpp ${source_DIR}/skyline/kernel/types/KSharedMemory.cpp ${source_DIR}/skyline/kernel/types/KPrivateMemory.cpp + ${source_DIR}/skyline/kernel/types/KSyncObject.cpp ${source_DIR}/skyline/audio.cpp ${source_DIR}/skyline/audio/track.cpp ${source_DIR}/skyline/audio/resampler.cpp diff --git a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp index dc841a04..65406eeb 100644 --- a/app/src/main/cpp/skyline/gpu/presentation_engine.cpp +++ b/app/src/main/cpp/skyline/gpu/presentation_engine.cpp @@ -9,9 +9,7 @@ extern skyline::u16 Fps; extern skyline::u32 FrameTime; namespace skyline::gpu { - PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared(state)), bufferEvent(std::make_shared(state)) { - vsyncEvent->Signal(); - } + PresentationEngine::PresentationEngine(const DeviceState &state) : state(state), vsyncEvent(std::make_shared(state, true)), bufferEvent(std::make_shared(state, true)) {} PresentationEngine::~PresentationEngine() { if (window) diff --git a/app/src/main/cpp/skyline/input/npad_device.cpp b/app/src/main/cpp/skyline/input/npad_device.cpp index 512b42a7..4b217872 100644 --- a/app/src/main/cpp/skyline/input/npad_device.cpp +++ b/app/src/main/cpp/skyline/input/npad_device.cpp @@ -6,7 +6,7 @@ #include "npad.h" namespace skyline::input { - NpadDevice::NpadDevice(NpadManager &manager, NpadSection §ion, NpadId id) : manager(manager), section(section), id(id), updateEvent(std::make_shared(manager.state)) {} + NpadDevice::NpadDevice(NpadManager &manager, NpadSection §ion, NpadId id) : manager(manager), section(section), id(id), updateEvent(std::make_shared(manager.state, false)) {} void NpadDevice::Connect(NpadControllerType newType) { if (type == newType) { diff --git a/app/src/main/cpp/skyline/kernel/svc.cpp b/app/src/main/cpp/skyline/kernel/svc.cpp index 6a34abb0..42dd56bb 100644 --- a/app/src/main/cpp/skyline/kernel/svc.cpp +++ b/app/src/main/cpp/skyline/kernel/svc.cpp @@ -524,11 +524,8 @@ namespace skyline::kernel::svc { auto object{state.process->GetHandle(handle)}; switch (object->objectType) { case type::KType::KEvent: - std::static_pointer_cast(object)->ResetSignal(); - break; - case type::KType::KProcess: - std::static_pointer_cast(object)->ResetSignal(); + std::static_pointer_cast(object)->ResetSignal(); break; default: { @@ -552,17 +549,18 @@ namespace skyline::kernel::svc { u32 numHandles{state.ctx->gpr.w2}; if (numHandles > maxSyncHandles) { - state.ctx->gpr.w0 = result::OutOfHandles; + state.ctx->gpr.w0 = result::OutOfRange; return; } - std::string handleStr; - std::vector> objectTable; span waitHandles(reinterpret_cast(state.ctx->gpr.x1), numHandles); + std::vector> objectTable; + objectTable.reserve(numHandles); + std::string handleString; for (const auto &handle : waitHandles) { if (Logger::LogLevel::Debug <= state.logger->configLevel) - handleStr += fmt::format("* 0x{:X}\n", handle); + handleString += fmt::format("* 0x{:X}\n", handle); auto object{state.process->GetHandle(handle)}; switch (object->objectType) { @@ -574,46 +572,99 @@ namespace skyline::kernel::svc { break; default: { + state.logger->Debug("svcWaitSynchronization: An invalid handle was supplied: 0x{:X}", handle); state.ctx->gpr.w0 = result::InvalidHandle; return; } } } - u64 timeout{state.ctx->gpr.x3}; - state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: 0x{:X} ns", handleStr, timeout); + i64 timeout{static_cast(state.ctx->gpr.x3)}; + state.logger->Debug("svcWaitSynchronization: Waiting on handles:\n{}Timeout: {}ns", handleString, timeout); - SchedulerScopedLock schedulerLock(state); - auto start{util::GetTimeNs()}; - while (true) { - if (state.thread->cancelSync) { - state.thread->cancelSync = false; - state.ctx->gpr.w0 = result::Cancelled; + std::unique_lock lock(type::KSyncObject::syncObjectMutex); + if (state.thread->cancelSync) { + state.thread->cancelSync = false; + state.ctx->gpr.w0 = result::Cancelled; + return; + } + + u32 index{}; + for (const auto &object : objectTable) { + if (object->signalled) { + state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles[index]); + state.ctx->gpr.w0 = Result{}; + state.ctx->gpr.w1 = index; return; } + index++; + } - u32 index{}; - for (const auto &object : objectTable) { - if (object->signalled) { - state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles[index]); - state.ctx->gpr.w0 = Result{}; - state.ctx->gpr.w1 = index; - return; - } - index++; - } + if (timeout == 0) { + state.logger->Debug("svcWaitSynchronization: No handle is currently signalled"); + state.ctx->gpr.w0 = result::TimedOut; + return; + } - if ((util::GetTimeNs() - start) >= timeout) { - state.logger->Debug("svcWaitSynchronization: Wait has timed out"); - state.ctx->gpr.w0 = result::TimedOut; - return; - } + auto priority{state.thread->priority.load()}; + for (const auto &object : objectTable) + object->syncObjectWaiters.insert(std::upper_bound(object->syncObjectWaiters.begin(), object->syncObjectWaiters.end(), priority, type::KThread::IsHigherPriority), state.thread); + + state.thread->isCancellable = true; + state.thread->wakeObject = nullptr; + state.scheduler->RemoveThread(); + + lock.unlock(); + if (timeout > 0) + state.scheduler->TimedWaitSchedule(std::chrono::nanoseconds(timeout)); + else + state.scheduler->WaitSchedule(false); + lock.lock(); + + state.thread->isCancellable = false; + auto wakeObject{state.thread->wakeObject}; + + u32 wakeIndex{}; + index = 0; + for (const auto &object : objectTable) { + if (object.get() == wakeObject) + wakeIndex = index; + + auto it{std::find(object->syncObjectWaiters.begin(), object->syncObjectWaiters.end(), state.thread)}; + if (it != object->syncObjectWaiters.end()) + object->syncObjectWaiters.erase(it); + else + throw exception("svcWaitSynchronization: An object (0x{:X}) has been removed from the syncObjectWaiters queue incorrectly", waitHandles[index]); + + index++; + } + + if (wakeObject) { + state.logger->Debug("svcWaitSynchronization: Signalled handle: 0x{:X}", waitHandles[index]); + state.ctx->gpr.w0 = Result{}; + state.ctx->gpr.w1 = wakeIndex; + } else if (state.thread->cancelSync) { + state.thread->cancelSync = false; + state.logger->Debug("svcWaitSynchronization: Wait has been cancelled"); + state.ctx->gpr.w0 = result::Cancelled; + } else { + state.logger->Debug("svcWaitSynchronization: Wait has timed out"); + state.ctx->gpr.w0 = result::TimedOut; + lock.unlock(); + state.scheduler->InsertThread(state.thread); + state.scheduler->WaitSchedule(); } } void CancelSynchronization(const DeviceState &state) { try { - state.process->GetHandle(state.ctx->gpr.w0)->cancelSync = true; + std::unique_lock lock(type::KSyncObject::syncObjectMutex); + auto thread{state.process->GetHandle(state.ctx->gpr.w0)}; + thread->cancelSync = true; + if (thread->isCancellable) { + thread->isCancellable = false; + state.scheduler->InsertThread(thread); + } } catch (const std::out_of_range &) { state.logger->Warn("svcCancelSynchronization: 'handle' invalid: 0x{:X}", static_cast(state.ctx->gpr.w0)); state.ctx->gpr.w0 = result::InvalidHandle; @@ -878,7 +929,7 @@ namespace skyline::kernel::svc { break; case InfoState::UserExceptionContextAddr: - out = reinterpret_cast(state.process->tlsPages[0]->Get(0)); + out = reinterpret_cast(state.process->tlsExceptionContext); break; default: diff --git a/app/src/main/cpp/skyline/kernel/types/KEvent.h b/app/src/main/cpp/skyline/kernel/types/KEvent.h index 164447ca..a0972f77 100644 --- a/app/src/main/cpp/skyline/kernel/types/KEvent.h +++ b/app/src/main/cpp/skyline/kernel/types/KEvent.h @@ -12,13 +12,9 @@ namespace skyline::kernel::type { */ class KEvent : public KSyncObject { public: - KEvent(const DeviceState &state) : KSyncObject(state, KType::KEvent) {} - /** - * @brief Resets the KEvent to an unsignalled state + * @param presignalled If this object should be signalled initially or not */ - inline void ResetSignal() { - signalled = false; - } + KEvent(const DeviceState &state, bool presignalled) : KSyncObject(state, KType::KEvent, presignalled) {} }; } diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp index 7fa9f59f..551e97fc 100644 --- a/app/src/main/cpp/skyline/kernel/types/KProcess.cpp +++ b/app/src/main/cpp/skyline/kernel/types/KProcess.cpp @@ -10,19 +10,9 @@ namespace skyline::kernel::type { KProcess::TlsPage::TlsPage(const std::shared_ptr &memory) : memory(memory) {} u8 *KProcess::TlsPage::ReserveSlot() { - if (Full()) - throw exception("Trying to reserve TLS slot in full page"); - return Get(index++); - } - - u8 *KProcess::TlsPage::Get(u8 slot) { - if (slot >= constant::TlsSlots) - throw exception("TLS slot is out of range"); - return memory->ptr + (constant::TlsSlotSize * slot); - } - - bool KProcess::TlsPage::Full() { - return index == constant::TlsSlots; + if (index == constant::TlsSlots) + return nullptr; + return memory->ptr + (constant::TlsSlotSize * index++); } KProcess::KProcess(const DeviceState &state) : memory(state), KSyncObject(state, KType::KProcess) {} @@ -52,22 +42,23 @@ namespace skyline::kernel::type { } } - void KProcess::InitializeHeap() { + void KProcess::InitializeHeapTls() { constexpr size_t DefaultHeapSize{0x200000}; heap = heap.make_shared(state, reinterpret_cast(state.process->memory.heap.address), DefaultHeapSize, memory::Permission{true, true, false}, memory::states::Heap); InsertItem(heap); // Insert it into the handle table so GetMemoryObject will contain it + tlsExceptionContext = AllocateTlsSlot(); } u8 *KProcess::AllocateTlsSlot() { + std::lock_guard lock(tlsMutex); + u8 *slot; for (auto &tlsPage: tlsPages) - if (!tlsPage->Full()) - return tlsPage->ReserveSlot(); + if ((slot = tlsPage->ReserveSlot())) + return slot; - u8 *ptr = tlsPages.empty() ? reinterpret_cast(state.process->memory.tlsIo.address) : ((*(tlsPages.end() - 1))->memory->ptr + PAGE_SIZE); - auto tlsPage{std::make_shared(std::make_shared(state, ptr, PAGE_SIZE, memory::Permission(true, true, false), memory::states::ThreadLocal))}; + slot = tlsPages.empty() ? reinterpret_cast(memory.tlsIo.address) : ((*(tlsPages.end() - 1))->memory->ptr + PAGE_SIZE); + auto tlsPage{std::make_shared(std::make_shared(state, slot, PAGE_SIZE, memory::Permission(true, true, false), memory::states::ThreadLocal))}; tlsPages.push_back(tlsPage); - - tlsPage->ReserveSlot(); // User-mode exception handling return tlsPage->ReserveSlot(); } diff --git a/app/src/main/cpp/skyline/kernel/types/KProcess.h b/app/src/main/cpp/skyline/kernel/types/KProcess.h index 30fb0e59..027c6131 100644 --- a/app/src/main/cpp/skyline/kernel/types/KProcess.h +++ b/app/src/main/cpp/skyline/kernel/types/KProcess.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include "KThread.h" #include "KTransferMemory.h" @@ -30,7 +29,7 @@ namespace skyline { bool disableThreadCreation{}; //!< If to disable thread creation, we use this to prevent thread creation after all threads have been killed std::vector> threads; - using SyncWaiters = std::multimap>; + using SyncWaiters = std::multimap>; std::mutex syncWaiterMutex; //!< Synchronizes all mutations to the map to prevent races SyncWaiters syncWaiters; //!< All threads waiting on process-wide synchronization primitives (Atomic keys + Address Arbiter) @@ -42,21 +41,23 @@ namespace skyline { */ struct TlsPage { u8 index{}; //!< The slots are assigned sequentially, this holds the index of the last TLS slot reserved - std::shared_ptr memory; + std::shared_ptr memory; //!< A single page sized memory allocation for this TLS page TlsPage(const std::shared_ptr &memory); + /** + * @return A non-null pointer to a TLS page slot on success, a nullptr will be returned if this page is full + * @note This function is not thread-safe and should be called by exclusively one thread at a time + */ u8 *ReserveSlot(); - - u8 *Get(u8 slot); - - bool Full(); }; public: - std::shared_ptr mainThreadStack; + u8* tlsExceptionContext{}; //!< A pointer to the TLS Exception Handling Context slot + std::mutex tlsMutex; //!< A mutex to synchronize allocation of TLS pages to prevent extra pages from being created + std::vector> tlsPages; //!< All TLS pages allocated by this process + std::shared_ptr mainThreadStack; //!< The stack memory of the main thread stack is owned by the KProcess itself std::shared_ptr heap; - std::vector> tlsPages; vfs::NPDM npdm; private: @@ -79,9 +80,10 @@ namespace skyline { void Kill(bool join, bool all = false, bool disableCreation = false); /** + * @brief This initializes the process heap and TLS Error Context slot pointer, it should be called prior to creating the first thread * @note This requires VMM regions to be initialized, it will map heap at an arbitrary location otherwise */ - void InitializeHeap(); + void InitializeHeapTls(); /** * @return A 0x200 TLS slot allocated inside the TLS/IO region @@ -177,7 +179,12 @@ namespace skyline { template<> std::shared_ptr GetHandle(KHandle handle) { - return handles.at(handle - constant::BaseHandleIndex); + std::shared_lock lock(handleMutex); + auto &item{handles.at(handle - constant::BaseHandleIndex)}; + if (item != nullptr) + return item; + else + throw std::out_of_range(fmt::format("GetHandle was called with a deleted handle: 0x{:X}", handle)); } /** @@ -215,13 +222,6 @@ namespace skyline { * @brief Signals the conditional variable at the specified address */ void ConditionalVariableSignal(u32 *key, u64 amount); - - /** - * @brief Resets the object to an unsignalled state - */ - inline void ResetSignal() { - signalled = false; - } }; } } diff --git a/app/src/main/cpp/skyline/kernel/types/KSyncObject.cpp b/app/src/main/cpp/skyline/kernel/types/KSyncObject.cpp new file mode 100644 index 00000000..387052b6 --- /dev/null +++ b/app/src/main/cpp/skyline/kernel/types/KSyncObject.cpp @@ -0,0 +1,19 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright © 2020 Skyline Team and Contributors (https://github.com/skyline-emu/) + +#include "KSyncObject.h" +#include "KThread.h" + +namespace skyline::kernel::type { + void KSyncObject::Signal() { + std::lock_guard lock(syncObjectMutex); + signalled = true; + for (auto& waiter : syncObjectWaiters) { + if (waiter->isCancellable) { + waiter->isCancellable = false; + waiter->wakeObject = this; + state.scheduler->InsertThread(waiter); + } + } + } +} diff --git a/app/src/main/cpp/skyline/kernel/types/KSyncObject.h b/app/src/main/cpp/skyline/kernel/types/KSyncObject.h index 4dbc50c3..47a16d33 100644 --- a/app/src/main/cpp/skyline/kernel/types/KSyncObject.h +++ b/app/src/main/cpp/skyline/kernel/types/KSyncObject.h @@ -7,19 +7,31 @@ namespace skyline::kernel::type { /** - * @brief KSyncObject holds the state of a waitable object + * @brief KSyncObject is an abstract class which holds everything necessary for an object to be synchronizable + * @note This abstraction is roughly equivalent to KSynchronizationObject on HOS */ class KSyncObject : public KObject { public: - std::atomic signalled{false}; //!< If the current object is signalled (Used as object stays signalled till the signal is consumed) - - KSyncObject(const DeviceState &state, skyline::kernel::type::KType type) : KObject(state, type) {}; + inline static std::mutex syncObjectMutex; //!< A global lock used for locking all signalling to avoid races + std::list> syncObjectWaiters; //!< A list of threads waiting on this object to be signalled + std::atomic signalled; //!< If the current object is signalled (An object stays signalled till the signal has been explicitly reset) /** - * @brief A function for calling when a particular KSyncObject is signalled + * @param presignalled If this object should be signalled initially or not */ - virtual void Signal() { - signalled = true; + KSyncObject(const DeviceState &state, skyline::kernel::type::KType type, bool presignalled = false) : KObject(state, type), signalled(presignalled) {}; + + /** + * @brief Wakes up any waiters on this object and flips the 'signalled' flag + */ + void Signal(); + + /** + * @brief Resets the object to an unsignalled state + */ + inline void ResetSignal() { + std::lock_guard lock(syncObjectMutex); + signalled = false; } virtual ~KSyncObject() = default; diff --git a/app/src/main/cpp/skyline/kernel/types/KThread.h b/app/src/main/cpp/skyline/kernel/types/KThread.h index ce449bf5..847e0c87 100644 --- a/app/src/main/cpp/skyline/kernel/types/KThread.h +++ b/app/src/main/cpp/skyline/kernel/types/KThread.h @@ -3,7 +3,6 @@ #pragma once -#include #include #include #include @@ -27,7 +26,7 @@ namespace skyline { public: std::mutex mutex; //!< Synchronizes all thread state changes bool running{false}; //!< If the host thread that corresponds to this thread is running, this doesn't reflect guest scheduling changes - std::atomic cancelSync{false}; //!< This is to flag to a thread to cancel a synchronization call it currently is in + bool killed{false}; //!< If this thread was previously running and has been killed KHandle handle; size_t id; //!< Index of thread in parent process's KThread vector @@ -54,6 +53,9 @@ namespace skyline { KHandle waitTag; //!< The handle of the thread which requested the mutex lock std::shared_ptr waitThread; //!< The thread which this thread is waiting on std::list> waiters; //!< A queue of threads waiting on this thread sorted by priority + bool isCancellable{false}; //!< If the thread is currently in a position where it is cancellable + bool cancelSync{false}; //!< If to cancel a SvcWaitSynchronization call this thread currently is in/the next one it joins + type::KSyncObject* wakeObject{}; //!< A pointer to the synchronization object responsible for waking this thread up KThread(const DeviceState &state, KHandle handle, KProcess *parent, size_t id, void *entry, u64 argument, void *stackTop, u8 priority, i8 idealCore); diff --git a/app/src/main/cpp/skyline/os.cpp b/app/src/main/cpp/skyline/os.cpp index c9b6d376..018119e8 100644 --- a/app/src/main/cpp/skyline/os.cpp +++ b/app/src/main/cpp/skyline/os.cpp @@ -36,7 +36,7 @@ namespace skyline::kernel { auto &process{state.process}; process = std::make_shared(state); auto entry{state.loader->LoadProcessData(process, state)}; - process->InitializeHeap(); + process->InitializeHeapTls(); auto thread{process->CreateThread(entry)}; if (thread) { state.logger->Debug("Starting main HOS thread"); diff --git a/app/src/main/cpp/skyline/services/am/applet/ILibraryAppletAccessor.cpp b/app/src/main/cpp/skyline/services/am/applet/ILibraryAppletAccessor.cpp index d9584392..1f1e2fdb 100644 --- a/app/src/main/cpp/skyline/services/am/applet/ILibraryAppletAccessor.cpp +++ b/app/src/main/cpp/skyline/services/am/applet/ILibraryAppletAccessor.cpp @@ -7,7 +7,7 @@ #include "ILibraryAppletAccessor.h" namespace skyline::service::am { - ILibraryAppletAccessor::ILibraryAppletAccessor(const DeviceState &state, ServiceManager &manager) : stateChangeEvent(std::make_shared(state)), BaseService(state, manager) {} + ILibraryAppletAccessor::ILibraryAppletAccessor(const DeviceState &state, ServiceManager &manager) : stateChangeEvent(std::make_shared(state, false)), BaseService(state, manager) {} Result ILibraryAppletAccessor::GetAppletStateChangedEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { stateChangeEvent->Signal(); diff --git a/app/src/main/cpp/skyline/services/am/controller/IApplicationFunctions.cpp b/app/src/main/cpp/skyline/services/am/controller/IApplicationFunctions.cpp index ab13988e..a5dec98f 100644 --- a/app/src/main/cpp/skyline/services/am/controller/IApplicationFunctions.cpp +++ b/app/src/main/cpp/skyline/services/am/controller/IApplicationFunctions.cpp @@ -7,7 +7,7 @@ #include "IApplicationFunctions.h" namespace skyline::service::am { - IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : gpuErrorEvent(std::make_shared(state)), BaseService(state, manager) {} + IApplicationFunctions::IApplicationFunctions(const DeviceState &state, ServiceManager &manager) : gpuErrorEvent(std::make_shared(state, false)), BaseService(state, manager) {} Result IApplicationFunctions::PopLaunchParameter(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { constexpr u32 LaunchParameterMagic{0xC79497CA}; //!< The magic of the application launch parameters diff --git a/app/src/main/cpp/skyline/services/am/controller/ICommonStateGetter.cpp b/app/src/main/cpp/skyline/services/am/controller/ICommonStateGetter.cpp index 093c4d39..27028585 100644 --- a/app/src/main/cpp/skyline/services/am/controller/ICommonStateGetter.cpp +++ b/app/src/main/cpp/skyline/services/am/controller/ICommonStateGetter.cpp @@ -11,7 +11,7 @@ namespace skyline::service::am { messageEvent->Signal(); } - ICommonStateGetter::ICommonStateGetter(const DeviceState &state, ServiceManager &manager) : messageEvent(std::make_shared(state)), BaseService(state, manager) { + ICommonStateGetter::ICommonStateGetter(const DeviceState &state, ServiceManager &manager) : messageEvent(std::make_shared(state, false)), BaseService(state, manager) { operationMode = static_cast(state.settings->GetBool("operation_mode")); state.logger->Info("Switch to mode: {}", static_cast(operationMode) ? "Docked" : "Handheld"); QueueMessage(Message::FocusStateChange); diff --git a/app/src/main/cpp/skyline/services/am/controller/ISelfController.cpp b/app/src/main/cpp/skyline/services/am/controller/ISelfController.cpp index a98847cb..fd1956f5 100644 --- a/app/src/main/cpp/skyline/services/am/controller/ISelfController.cpp +++ b/app/src/main/cpp/skyline/services/am/controller/ISelfController.cpp @@ -6,7 +6,7 @@ #include "ISelfController.h" namespace skyline::service::am { - ISelfController::ISelfController(const DeviceState &state, ServiceManager &manager) : libraryAppletLaunchableEvent(std::make_shared(state)), accumulatedSuspendedTickChangedEvent(std::make_shared(state)), BaseService(state, manager) {} + ISelfController::ISelfController(const DeviceState &state, ServiceManager &manager) : libraryAppletLaunchableEvent(std::make_shared(state, false)), accumulatedSuspendedTickChangedEvent(std::make_shared(state, false)), BaseService(state, manager) {} Result ISelfController::LockExit(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { return {}; diff --git a/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp b/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp index dad27d72..928c8c5d 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioDevice.cpp @@ -6,7 +6,7 @@ #include "IAudioDevice.h" namespace skyline::service::audio { - IAudioDevice::IAudioDevice(const DeviceState &state, ServiceManager &manager) : systemEvent(std::make_shared(state)), BaseService(state, manager) {} + IAudioDevice::IAudioDevice(const DeviceState &state, ServiceManager &manager) : systemEvent(std::make_shared(state, true)), BaseService(state, manager) {} Result IAudioDevice::ListAudioDeviceName(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { span buffer{request.outputBuf.at(0)}; diff --git a/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp b/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp index e2a0a34d..db974dd7 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioOut.cpp @@ -5,7 +5,7 @@ #include "IAudioOut.h" namespace skyline::service::audio { - IAudioOut::IAudioOut(const DeviceState &state, ServiceManager &manager, u8 channelCount, u32 sampleRate) : sampleRate(sampleRate), channelCount(channelCount), releaseEvent(std::make_shared(state)), BaseService(state, manager) { + IAudioOut::IAudioOut(const DeviceState &state, ServiceManager &manager, u8 channelCount, u32 sampleRate) : sampleRate(sampleRate), channelCount(channelCount), releaseEvent(std::make_shared(state, false)), BaseService(state, manager) { track = state.audio->OpenTrack(channelCount, constant::SampleRate, [this]() { this->releaseEvent->Signal(); }); } diff --git a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp index f427472c..4d09aa45 100644 --- a/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp +++ b/app/src/main/cpp/skyline/services/audio/IAudioRenderer/IAudioRenderer.cpp @@ -6,7 +6,7 @@ namespace skyline::service::audio::IAudioRenderer { IAudioRenderer::IAudioRenderer(const DeviceState &state, ServiceManager &manager, AudioRendererParameters ¶meters) - : systemEvent(std::make_shared(state)), parameters(parameters), BaseService(state, manager) { + : systemEvent(std::make_shared(state, true)), parameters(parameters), BaseService(state, manager) { track = state.audio->OpenTrack(constant::ChannelCount, constant::SampleRate, []() {}); track->Start(); diff --git a/app/src/main/cpp/skyline/services/friends/INotificationService.cpp b/app/src/main/cpp/skyline/services/friends/INotificationService.cpp index 992f19a7..b5135081 100644 --- a/app/src/main/cpp/skyline/services/friends/INotificationService.cpp +++ b/app/src/main/cpp/skyline/services/friends/INotificationService.cpp @@ -5,7 +5,7 @@ #include "INotificationService.h" namespace skyline::service::friends { - INotificationService::INotificationService(const DeviceState &state, ServiceManager &manager) : notificationEvent(std::make_shared(state)), BaseService(state, manager) {} + INotificationService::INotificationService(const DeviceState &state, ServiceManager &manager) : notificationEvent(std::make_shared(state, false)), BaseService(state, manager) {} Result INotificationService::GetEvent(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { KHandle handle{state.process->InsertItem(notificationEvent)}; diff --git a/app/src/main/cpp/skyline/services/nifm/IRequest.cpp b/app/src/main/cpp/skyline/services/nifm/IRequest.cpp index 38457c13..f56ccdf9 100644 --- a/app/src/main/cpp/skyline/services/nifm/IRequest.cpp +++ b/app/src/main/cpp/skyline/services/nifm/IRequest.cpp @@ -5,7 +5,7 @@ #include "IRequest.h" namespace skyline::service::nifm { - IRequest::IRequest(const DeviceState &state, ServiceManager &manager) : event0(std::make_shared(state)), event1(std::make_shared(state)), BaseService(state, manager) {} + IRequest::IRequest(const DeviceState &state, ServiceManager &manager) : event0(std::make_shared(state, false)), event1(std::make_shared(state, false)), BaseService(state, manager) {} Result IRequest::GetRequestState(type::KSession &session, ipc::IpcRequest &request, ipc::IpcResponse &response) { constexpr u32 Unsubmitted{1}; //!< The request has not been submitted diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp index ab66e74f..6c602b73 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_channel.cpp @@ -7,7 +7,7 @@ #include "nvhost_channel.h" namespace skyline::service::nvdrv::device { - NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared(state)), smExceptionBreakpointPauseReportEvent(std::make_shared(state)), errorNotifierEvent(std::make_shared(state)), NvDevice(state) { + NvHostChannel::NvHostChannel(const DeviceState &state) : smExceptionBreakpointIntReportEvent(std::make_shared(state, false)), smExceptionBreakpointPauseReportEvent(std::make_shared(state, false)), errorNotifierEvent(std::make_shared(state, false)), NvDevice(state) { auto driver{nvdrv::driver.lock()}; auto &hostSyncpoint{driver->hostSyncpoint}; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp index 131f101a..ebc4e2e7 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.cpp @@ -7,17 +7,17 @@ #include "nvhost_ctrl.h" namespace skyline::service::nvdrv::device { - NvHostEvent::NvHostEvent(const DeviceState &state) : event(std::make_shared(state)) {} + NvHostEvent::NvHostEvent(const DeviceState &state) : event(std::make_shared(state, false)) {} void NvHostEvent::Signal() { auto oldState{state}; - state = State::Signaling; + state = State::Signalling; // This is to ensure that the HOS event isn't signalled when the nvhost event is cancelled if (oldState == State::Waiting) event->Signal(); - state = State::Signaled; + state = State::Signalled; } void NvHostEvent::Cancel(const std::shared_ptr &gpuState) { @@ -46,7 +46,7 @@ namespace skyline::service::nvdrv::device { if (events[i]) { const auto &event{*events[i]}; - if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) { + if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signalled) { eventIndex = i; // This event is already attached to the requested syncpoint, so use it @@ -113,7 +113,7 @@ namespace skyline::service::nvdrv::device { } auto &event{*events.at(userEventId)}; - if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signaled) { + if (event.state == NvHostEvent::State::Cancelled || event.state == NvHostEvent::State::Available || event.state == NvHostEvent::State::Signalled) { state.logger->Debug("Waiting on nvhost event: {} with fence: {}", userEventId, data.fence.id); event.Wait(state.gpu, data.fence); diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h index d7d4d4e0..202b5845 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl.h @@ -26,8 +26,8 @@ namespace skyline { Available = 0, Waiting = 1, Cancelling = 2, - Signaling = 3, - Signaled = 4, + Signalling = 3, + Signalled = 4, Cancelled = 5, }; diff --git a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp index c7e18e10..6faee00f 100644 --- a/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp +++ b/app/src/main/cpp/skyline/services/nvdrv/devices/nvhost_ctrl_gpu.cpp @@ -4,7 +4,7 @@ #include "nvhost_ctrl_gpu.h" namespace skyline::service::nvdrv::device { - NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared(state)), unknownEvent(std::make_shared(state)), NvDevice(state) {} + NvHostCtrlGpu::NvHostCtrlGpu(const DeviceState &state) : errorNotifierEvent(std::make_shared(state, false)), unknownEvent(std::make_shared(state, false)), NvDevice(state) {} NvStatus NvHostCtrlGpu::ZCullGetCtxSize(IoctlType type, span buffer, span inlineBuffer) { buffer.as() = 0x1;