It's only ever updated after the queue is updated, so its state will
always lag slightly behind it. It's sufficient to just use empty().
This seems to fix some caching issues that were noticeable on Skylake
CPUs (#998).
In the previous code, the worker thread would notify the MTGS thread
while the mutex is still locked, which could cause the MTGS thread to
wake up and immediately go back to sleep again since it can't lock the
mutex.
Use a separate mutex for waiting, which avoids the issue.
* Upgrade the counter to signed 32 bits. 16 bits is too small to contains the 64K value.
* Read ThreadProc/m_count when the mutex is locked
* Use old value of the fetch instead to read back the new value
In the previous code, the threads were created and destroyed in the base
class constructor and destructor, so the threads could potentially be
active while the object is in a partially constructed or destroyed state.
The thread however, relies on a virtual function to process the queue
items, and the vtable might not be in the desired state when the object
is partially constructed or destroyed.
This probably only matters during object destruction - no items are in
the queue during object construction so the virtual function won't be
called, but items may still be queued up when the destructor is called,
so the virtual function can be called. It wasn't an issue because all
uses of the thread explicitly waited for the queues to be empty before
invoking the destructor.
Adjust the constructor to take a std::function parameter, which the
thread will use instead to process queue items, and avoid inheriting
from the GSJobQueue class. This will also eliminate the need to
explicitly wait for all jobs to finish (unless there are other external
factors, of course), which would probably make future code safer.
Use a relaxed atomic to read the exit variable in the hot path
Wait that exit is deasserted in the destructor, so we are sure the
thread will "soon" return
Visual Studio Find and Replace can only be trusted if all the files are
included in the project. I suppose it's time to add any missing files
to the relevant projects...
If someone has a more elegant solution, feel free to share it
spin_thread = 0
spin_thread = 1 // the faster but GS thread will never stop, very bad for laptop
It is faster on linux, it requires less code, and it is "portable"
It requires boost (only hpp files) + MSVC 2013 (for atomic) (seem doable by 2012 too)
Actually there are several queues that either use spinlock or full sleep