mirror of
https://github.com/libretro/parallel-gx1.git
synced 2026-11-07 04:26:01 -10:00
Every std::mutex, lock_guard, unique_lock, scoped_lock, condition_variable, call_once and semaphore left in Source/Core is replaced by a lock-free design: - Input: the device list, control bindings, stick calibration and default device are published snapshots read under a quiesce; a rebind requested while another thread is rebinding is handed to that thread instead of waited for. - WiimoteReal: the pool thread owns the slots and runs commands from an MPSC queue; the active Wiimotes are atomic slots. - EXI/SI/IOS devices: socket and packet traffic goes through SPSC rings or MPSC handoffs owned by one thread; USB scanning publishes its device list, and libusb transfers drain through a CallGate. - Memory cards: the flush thread applies change records queued by the CPU thread. - Custom assets: loads are scheduled as a published batch with an atomic cursor, results come back over an MPSC stack, and busy assets are skipped and retried. - D3D state and GL program caches use insert-only atomic maps (Common/AtomicHashMap.h). - Logging appends with O_APPEND / FILE_APPEND_DATA; FatFs reports busy instead of waiting; per-socket WSAStartup/WSACleanup. Deleted as unused by the libretro core: the profiler, the FIFO recorder, the volume verifier, the touch InputOverrider and the GameCube adapter's libusb path.
48 lines
1.2 KiB
C++
48 lines
1.2 KiB
C++
// Copyright 2022 DolphiniOS Project
|
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
|
|
|
#pragma once
|
|
|
|
#include <array>
|
|
#include <cstddef>
|
|
|
|
#include <retro_atomic.h>
|
|
|
|
#include "Common/Quiesce.h"
|
|
|
|
namespace Common
|
|
{
|
|
// Tracks the JIT code regions whose write and execute permissions are toggled around code
|
|
// emission. Each JIT emits into its own region on its own thread, so a region's nest count is
|
|
// that thread's alone; the set of regions is shared, and kept in atomic slots.
|
|
class JITMemoryTracker final
|
|
{
|
|
public:
|
|
JITMemoryTracker();
|
|
~JITMemoryTracker();
|
|
|
|
void RegisterJITRegion(void* ptr, size_t size);
|
|
void UnregisterJITRegion(void* ptr);
|
|
|
|
void JITRegionWriteEnableExecuteDisable(void* ptr);
|
|
void JITRegionWriteDisableExecuteEnable(void* ptr);
|
|
|
|
private:
|
|
struct JITRegionInfo
|
|
{
|
|
quiesce_node_t node; // first: the free callback casts it back
|
|
void* start_ptr;
|
|
size_t size;
|
|
int nest_counter;
|
|
};
|
|
static void FreeRegion(quiesce_node_t* node);
|
|
|
|
// Only inside m_quiesce.
|
|
JITRegionInfo* FindRegion(void* ptr);
|
|
|
|
static constexpr size_t MAX_REGIONS = 64;
|
|
std::array<retro_atomic_ptr_t, MAX_REGIONS> m_jit_regions{};
|
|
quiesce_t m_quiesce{};
|
|
};
|
|
} // namespace Common
|