A handling method and the handler it becomes are a struct: kind, the
value or pointer and mask of the simple kinds, and for a complex one a
C function called with a word of context. Registering copies it in;
nothing is allocated, constructed or destroyed (the handler arrays are
the system's zeroed pages), where every handler was a heap object with
std::functions, thousands of them per boot.
The size converters are C functions whose context is the handler(s):
to smaller the high part, the low part being the next; to larger the
larger handler with the shift in its low bits. The devices' lambdas take
the context in place of what they captured (an index, a mask, a
register; EXI's channel, through member functions), and the JITs call
the function directly: the emitters' std::function trampolines are gone.
CPU: the state machine drops its two mutexes and two condition
variables. The state is one atomic word, which the JIT still reads in
place; PowerDown sticks through a CAS. The CPU thread marks itself
active and then rechecks for a pause or a state change, and a pausing
thread stores its request and then waits for the flag to drop, a
Dekker pair, so neither misses the other. Waits park on eventcounts.
A step request and its Event travel as one exchanged pointer, pending
jobs are an MPSC stack run in order, and SetStepping and PauseAndLock
still run one at a time, through a claimed flag.
Core: the recursive core mutex goes. Stop moves the state with a CAS,
and PauseAndLock pairs are already serialized by the CPU's claim. Host
jobs are an MPSC stack the host thread moves, in order, into its own
queue, which keeps HostDispatchJobs re-entrant. RunOnCPUThread waits
on a Common::Event instead of a binary semaphore, and OneShotEvent is
removed.
State: the transferable shared mutex that counted save tasks is a
counter and an eventcount; the slot readers and the flush hook wait for
it to reach zero. TransferableSharedMutex is removed. WaitableFlag
parks on an eventcount.
PixelEngine: the token, its interrupt flags and the raised-event flag
are one atomic word; the video thread merges into it and schedules the
event only on the edge, the CPU thread takes the flags with a CAS.
Savestates keep the old fields.
VertexLoaderManager: the loader map is a fixed set of buckets, each a
list pushed with a CAS and read without a lock by the main and the
preprocessing thread; two threads making the same loader keep one.
AsyncShaderCompiler: the pending queue is the video thread's own. It
hands the most urgent items to two slots per worker, and finished items
come back on an MPSC stack, so neither side takes a lock.
OSD messages are posted to an MPSC stack and taken in by the video
thread when it draws; a screenshot request is one exchanged string.
Also removed, being unreachable: the surface change and resize requests
nothing sends (and the swap mutex guarding them), the ImGui keyboard
and mouse input nothing feeds (and the ImGui mutex, as only the video
thread touches the context now), ClearMessages, and the libretro Vulkan
WaitForPresentation with its mutex and condition variable.
The core never creates a NetPlay client or server; only the standalone
frontends did. Drop NetPlay with what only it used: the traversal
client, ENet, the QoS session, the NetPlay config layer and settings,
the chat and golf overlays, the netplay index, the save sync plumbing
in BootSessionData and WiiRoot, the disc sync hashes, and the Android
app's netplay feature and JNI bindings.
This was added in 385d8e2b15, but became somewhat redundant with Do in 4c7bbd96e4, and completely redundant now that std::is_trivially_copyable_v is well-supported.
Fixes Bomberman Jetters in single core mode.
When single core mode pauses the CPU to execute the GPU
FIFO it greedily executes the whole thing. Before this commit,
Finish and Token interrupts would happen instantly, not even
taking into account how long the current FIFO window has
taken to execute. The interrupts would be effectively backdated
to the start of this execution window.
This commit does two things: It pipes the current FIFO window
execution time though to the interrupt scheduling and it enforces
a minimum delay of 500 cycles before an interrupt will be fired.
SPDX standardizes how source code conveys its copyright and licensing
information. See https://spdx.github.io/spdx-spec/1-rationale/ . SPDX
tags are adopted in many large projects, including things like the Linux
kernel.
Now that we have an actual interface to manage things, we can stop
duplicating the calls to to the pixel shader manager and remove the
need to remember to actually do so when disabling or enabling the
bounding box.
Rather than expose the bounding box members directly, we can instead
provide an interface for code to use. This makes it nicer to transition
from global data, as the interface function names are already in
place.