mirror of
https://github.com/mitch030504/Wiicompiled_VR_Frame.git
synced 2026-10-06 08:00:25 +02:00
init
This commit is contained in:
commit
ec226e8348
1099 files changed
+400981
No files matched your search
@@ -0,0 +1,126 @@
|
||||
#pragma once
|
||||
|
||||
#include <atomic>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <thread>
|
||||
#include <unordered_map>
|
||||
|
||||
#if defined(_WIN32)
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#ifndef WIN32_LEAN_AND_MEAN
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#include "ppc_runtime.h"
|
||||
|
||||
// Forward declarations
|
||||
struct CpuContext;
|
||||
|
||||
// GuestFiberManager: each guest OSThread maps to a Windows Fiber. A scheduler fiber picks
|
||||
// which guest fiber runs; a real timer thread queues VI retraces at the VI cadence. Guest
|
||||
// threads only switch at explicit yield points (OSSleepThread, OSYieldThread, ...), matching
|
||||
// Wii cooperative semantics exactly.
|
||||
|
||||
namespace Fiber {
|
||||
|
||||
// Thread states matching guest OS
|
||||
enum class ThreadState : uint32_t {
|
||||
READY = 1,
|
||||
RUNNING = 2,
|
||||
WAITING = 4,
|
||||
MORIBUND = 8,
|
||||
};
|
||||
|
||||
// Information about a guest fiber
|
||||
struct GuestFiber {
|
||||
void* fiber = nullptr; // Windows fiber handle
|
||||
uint32_t entryPoint = 0; // Thread entry function
|
||||
uint32_t entryArg = 0; // Argument to entry function
|
||||
CpuContext cpuContext{}; // Saved CPU context for this fiber
|
||||
ThreadState state = ThreadState::READY;
|
||||
bool isSchedulerFiber = false; // True for the main scheduler fiber
|
||||
bool terminated = false; // Thread has exited
|
||||
};
|
||||
|
||||
class GuestFiberManager {
|
||||
public:
|
||||
// Initialize the fiber system - must be called from main thread
|
||||
static void Initialize();
|
||||
|
||||
// Shutdown the fiber system
|
||||
static void Shutdown();
|
||||
|
||||
// Check if fiber system is initialized
|
||||
static bool IsInitialized();
|
||||
|
||||
// Create a fiber for a guest thread (called from OSCreateThread HLE).
|
||||
// OSCreateThread's stackSize/priority are not passed: the host fiber models
|
||||
// neither, only the guest SP seeded from stackBase. Returns true on success.
|
||||
static bool CreateGuestFiber(uint32_t guestThreadAddr, uint32_t entryPoint,
|
||||
uint32_t entryArg, uint32_t stackBase);
|
||||
|
||||
// Resume a guest thread (called from OSResumeThread HLE)
|
||||
// This marks the fiber as runnable
|
||||
static void ResumeGuestThread(uint32_t guestThreadAddr);
|
||||
|
||||
// Suspend a guest thread (called from OSSuspendThread HLE)
|
||||
static void SuspendGuestThread(uint32_t guestThreadAddr);
|
||||
|
||||
// Called when a guest thread exits or is canceled
|
||||
static void ExitGuestThread(uint32_t guestThreadAddr, ThreadState finalState);
|
||||
|
||||
// Switch to a specific guest thread's fiber (called from OSLoadContext)
|
||||
// This saves the current fiber's state and switches to the target
|
||||
static void SwitchToThread(uint32_t guestThreadAddr, CpuContext* cpu);
|
||||
|
||||
// Get the currently running guest thread address (0 if in scheduler)
|
||||
static uint32_t GetCurrentGuestThread();
|
||||
|
||||
// Get fiber info for a guest thread (may be null)
|
||||
static GuestFiber* GetFiber(uint32_t guestThreadAddr);
|
||||
|
||||
// Check for VI retrace and process it (called from scheduler idle)
|
||||
static void ProcessTimerEvents(CpuContext* cpu);
|
||||
|
||||
// Register the current host fiber as a guest thread fiber
|
||||
// This is used for the default/main thread that exists before OSCreateThread
|
||||
static bool RegisterMainThreadAsFiber(uint32_t guestThreadAddr, CpuContext* cpu);
|
||||
|
||||
// Check if a fiber exists for a guest thread
|
||||
static bool HasFiber(uint32_t guestThreadAddr);
|
||||
static bool IsTerminated(uint32_t guestThreadAddr);
|
||||
|
||||
private:
|
||||
// The fiber entry point wrapper
|
||||
#if defined(_WIN32)
|
||||
static void CALLBACK FiberProc(void* param);
|
||||
#else
|
||||
static void FiberProc(void* param);
|
||||
#endif
|
||||
|
||||
// Internal state
|
||||
static std::mutex s_mutex;
|
||||
static std::unordered_map<uint32_t, GuestFiber> s_fibers;
|
||||
static std::vector<void*> s_fibersPendingDelete;
|
||||
static void* s_schedulerFiber;
|
||||
static uint32_t s_currentGuestThread;
|
||||
static bool s_initialized;
|
||||
// Stored CPU context pointer for fiber switches
|
||||
static thread_local CpuContext* s_cpuContext;
|
||||
|
||||
static void PurgePendingFibers();
|
||||
};
|
||||
|
||||
// Global pending retrace count. GuestFiberManager::ProcessTimerEvents drains
|
||||
// this on the guest thread so VI callbacks still run with guest state/locking
|
||||
// expectations.
|
||||
extern std::atomic<uint32_t> g_viRetracePendingCount;
|
||||
|
||||
} // namespace Fiber
|
||||
|
||||
Reference in new issue
Block a user