* Improve KMemory Comments
* Add parameter prefix 'p-' to `KPrivateMemory::UpdatePermission`
* Fix the missing trailing double quote in missing service prints, this was due to `stringName` being padded with extra 0s
The following scheduler bugs were fixed:
* It was assumed that all non-cooperative `Rotate` calls were from a preemptive yield and changed the state of `KThread::isPreempted` incorrectly which could lead to UB, an example of a scenario with it would be:
* * Preemptive thread A gets a signal to yield from cooperative thread B due to it being ready to schedule and higher priority
* * A complies with this request but there's an assumption that the signal was actually from it's preemption timer therefore it doesn't reset it (As it isn't required if the timer was responsible for the signal)
* * A receives the actual preemption signal a while later, causing UB as the signal handler is invoked twice
* `Scheduler::UpdatePriority`
* * A check for `currentIt == core->queue.begin()` existed which caused an incorrect early return
* * The preemption timer was armed correctly when a priority transition from cooperative priority -> preemption priority occurred but not disarmed when a transition from preemption priority -> cooperative priority occurred
* * The timer was unnecessarily disarmed in the case of updating the priority of a non-running thread, this isn't as much a bug as it is just pointless
* Priority inheritance in `KProcess::MutexLock` is fundamentally broken as it performs UB with `waitThread` being accessed prior to being assigned
* When a thread sets its own priority using `SvcSetThreadCoreMask` and its current core is no longer in the affinity mask, it wouldn't actually move to the new thread until the next time the thread is load balanced
This addresses all CR comments including more codebase-wide changes arising from certain review comments like proper usage of its/it's and consistent contraction of it is into it's.
An overhaul was made to the presentation and formatting of `KThread.h` and `LoadBalance` works has been superseded by `GetOptimalCoreForThread` which can be used alongside `InsertThread` or `MigrateToCore`. It makes the API far more atomic and neater. This was a major point of contention for the design prior, it's simplified some code and potentially improved performance.
The case of a thread not being in the core queue during a non-cooperative core affinity change would break things as the thread was non-conditionally removed and inserted, this has been fixed by adding a check to see if the thread exists in the core's queue prior to migration. In addition, `yieldWithCoreMigration` was broken by the previous commit as the fallthrough was intentional and removing it cause core migration without a yield which led to breakage in certain circumstances. The mutex locking logic was also improved in `ConditionalVariableWait` to use atomics in a more effective manner with less atomic operations being performed overall.
The SVCs improvements are as follows:
* Make SVC logs more concise for:
* * `SleepThread`
* * `ClearEvent`
* * `CloseHandle`
* * `ResetSignal`
* * `WaitSynchronization` (Special case for single handle)
* * `ArbitrateLock`
* * `ArbitrateUnlock`
* * `WaitProcessWideKeyAtomic`
* * `SignalProcessWideKey`
* Fix unintentional fallthrough into `yieldWithoutCoreMigration` from `yieldWithCoreMigration` in `SleepThread`
* Return `result::InvalidState` when an unsignalled handle is reset in `ResetSignal`
* Return `Result{}` (Success) in `CancelSynchronization`
* Do not return `result::InvalidCurrentMemory` in `ArbitrateLock` as it's not a failure condition
* Make `count` in `WaitProcessWideKeyAtomic` a `i32` from a `u32`, zero and all negative values result in waking all waiters
The entirety of the address arbiter is implemented in this commit, all three arbitration types: `WaitIfLessThan`, `DecrementAndWaitIfLessThan` and `WaitIfEqual`, and all three signal types: `Signal`, `SignalAndIncrementIfEqual` and `SignalAndModifyBasedOnWaitingThreadCountIfEqual` have been implemented.
This allows any application which uses levent (Light Events) to function which includes titles such as ARMS.
We did not support migration of threads which were running in a non-cooperative manner, this was partially due to the dependence on per-core conditional variables rather than per-thread which made this harder to do programmatically. This has been fixed by moving to per-thread cvars and therefore the limitation can be removed, this feature is used by Unity games.
SvcClearEvent previously set the `signalled` flag directly rather than
calling `ResetSignal`, which skipped the locking necessary to make it
globally visible. Switch it to use `ResetSignal` to fix this.
An exceptional signal handler allows us to convert an OS signal into a C++ exception, this allows us to alleviate a lot of crashes that would otherwise occur from signals being thrown during execution of games and be able to handle them gracefully.
This patch reduces the burden of adding services significantly, rather
than having to create an enum entry and add strings in the constructor
it will all be determined at runtime through RTTI. A macro is also used
in the service creation case to reduce clutter.
unmapped regions
svcQueryMemory will return a valid descriptor for anything in the
address space, from 0 to 1 << addrSpaceBits, this was handled
incorrectly before and we were only returning descriptors if the
address was in a mapped region.
If an address in an unmapped region is requested then the extents of the
unmapped region up to the address space end are returned. If the address
requested is outside of the address space then the extents of the
inaccessible address space are returned.
To facilitate this support was added to MemoryManager::Get for
generating the extents of unmapped regions using the chunk list.