Files
parallel-gx1/Source/Core/Common/JITMemoryTracker.h
T
LibretroAdmin f7d5095739 Core, InputCommon, VideoCommon: remove the remaining locks
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.
2026-11-05 20:11:31 +01:00

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