Most applications call AcquireRight before calling RegisterInterruptRelayQueue so we can't assign the thread id there.
This fixes the bug with LLE applets not launching properly.
This is true for all interrupts except PDC0 and PDC1, which should be triggered for all registered threads.
TODO: The real GSP module seems to only trigger PDC0 after updating the screens (both top and bottom). PDC1 doesn't seem to be triggered at all.
The registered interrupt event is unique to each session that calls RegisterInterruptRelayQueue, and only that event should be reset when UnregisterInterruptRelayQueue is called.
In a future commit, the count of cached pages will be reintroduced in
the actual surface cache. Also adds an Invalidate only to the cache
which marks a region as invalid in order to try to avoid a costly flush
from 3ds memory
The only functional change is the error handling of GSP_GPU::ReadHWRegs function. We previously didn't return error codes (not even for success). The new returns were found by reverse engineering the GSP module.
Terminating processes with ready threads is not currently implemented and will assert. It is currently unknown how the 3DS kernel stops ready threads or threads running in another core.
Some services can have multiple clients at the same time, and they identify the different clients using the server session as a key.
This parameter (if present) should be a structure that contains the per-session data for each service.
The data can be retrieved using ServiceFramework::GetSessionData(session)
The File class now holds a list of connected sessions along with data unique to each session.
A subfile is a window into an existing file. They have a few limitations compared to normal files:
* They can't be written to.
* They can't be flushed.
* Their size can not be changed.
* New subfiles can't be created from another subfile.
Alleviates the need to static_cast to an enum type at the call sites of the Push and Pop calls.
We only allow strongly typed enums, as they have a defined type of int
by default if an underlying type isn't explicitly specified, whereas
with regular enums, if an underlying type isn't specified, an
implementation-defined type is used that can fit all the enumeration
values.