A retro_run that draws nothing new allocates nothing; before, it made
some thirty-six allocations:
- Option lookups by key (IsUpdated and GetCached, about thirty a run)
made a std::string of the key for an unordered_map. The options are
now an array in the order of their definitions with an index sorted
by key, searched with strcmp.
- The JIT asks for its thread's stack bounds each time it starts
running, every run with frame stepping, and glibc's
pthread_getattr_np allocates. A thread's stack does not move: the
bounds are kept per thread after the first time.
- Every event pushed to the video thread, two a field for the XFB
swap, was built with new. Events are now built in a ring of fixed
slots: at most the queue's 1024 wait and one runs, so a slot comes
round again only once its event is done.
- A frame step, every run, posted a resume command to the real
Wiimote manager, built with new. A momentary state change no longer
resumes the remotes; a reported one still does.
Every Common::SPSCQueue goes, and with it the mutexes in front of the
multi-producer ones:
- WorkQueueThread runs on an sthread fed by an mpsc_stack, so any
thread pushes without a lock, and parks on retro_eventcount.
- AsyncRequests hands requests to the video thread through a
retro_waitable_spsc of pointers; a blocking request lives on the
caller's stack.
- CoreTiming's off-thread events and the DVD thread's results move to
mpsc_stack, dropping the CoreTiming write lock.
- Real Wiimote reports cross threads as fixed 32-byte records in
retro_spsc rings; the read thread receives straight into the ring.
- Bluetooth passthrough frees transfers through an mpsc_stack whose
nodes live in the transfers' own buffers, queues incoming packets in
mirrored retro_spsc rings and hands ACL data to IOS in place.
- PerformanceTracker's frame times move to a retro_spsc ring.
Given how many member functions make use of the system instance,
it's likely just better to pass the system instance in on construction.
Makes the interface a little less noisy to use.
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.
It used to be the case that frame advance skipped duplicate frames
(i.e. it would take 30 frame advances to get through one second
of emulated time in a 30 fps game), but this broke in 9c5c3c0.
Skipping duplicate frames making TASing less annoying.
Makes the global variable follow our convention of prefixing g_ on
global variables to make it obvious in surrounding code that it's not a
local variable.
Normalizes all variables related to statistics so that they follow our
coding style.
These are relatively low traffic areas, so this modification isn't too
noisy.
Prior to this change, it's possible for m_wake_me_up_again to be used
while it's in an uninitialized state from the exposed API.
e.g.
- Using SetEnable after construction would perform an uninitialized read.
- Using PushEvent would perform an uninitialized read by way of operator |=.
internally, an uninitialized read can happen if PullEventsInternal() is
executed before other functions.
Just to avoid the whole possibility of performing uninitialized reads,
we just give the class member a default value of false.
Replaces old and simple usages of std::atomic<bool> with Common::Flag
(which was introduced after the initial usage), so it's clear that
the variable is a flag and because Common::Flag is well tested.
This also replaces the ready logic in WiimoteReal with Common::Event
since it was basically just unnecessarily reimplementing Common::Event.