mirror of
https://github.com/wheremyfoodat/Panda3DS.git
synced 2025-04-07 22:55:40 +12:00
Add basic scheduler structure
This commit is contained in:
parent
b5718010ee
commit
7343497f36
4 changed files with 85 additions and 28 deletions
|
@ -244,7 +244,7 @@ set(HEADER_FILES include/emulator.hpp include/helpers.hpp include/termcolor.hpp
|
||||||
include/services/news_u.hpp include/applets/software_keyboard.hpp include/applets/applet_manager.hpp include/fs/archive_user_save_data.hpp
|
include/services/news_u.hpp include/applets/software_keyboard.hpp include/applets/applet_manager.hpp include/fs/archive_user_save_data.hpp
|
||||||
include/services/amiibo_device.hpp include/services/nfc_types.hpp include/swap.hpp include/services/csnd.hpp include/services/nwm_uds.hpp
|
include/services/amiibo_device.hpp include/services/nfc_types.hpp include/swap.hpp include/services/csnd.hpp include/services/nwm_uds.hpp
|
||||||
include/fs/archive_system_save_data.hpp include/lua_manager.hpp include/memory_mapped_file.hpp include/hydra_icon.hpp
|
include/fs/archive_system_save_data.hpp include/lua_manager.hpp include/memory_mapped_file.hpp include/hydra_icon.hpp
|
||||||
include/PICA/dynapica/shader_rec_emitter_arm64.hpp
|
include/PICA/dynapica/shader_rec_emitter_arm64.hpp include/scheduler.hpp
|
||||||
)
|
)
|
||||||
|
|
||||||
cmrc_add_resource_library(
|
cmrc_add_resource_library(
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include "helpers.hpp"
|
#include "helpers.hpp"
|
||||||
#include "kernel.hpp"
|
#include "kernel.hpp"
|
||||||
#include "memory.hpp"
|
#include "memory.hpp"
|
||||||
|
#include "scheduler.hpp"
|
||||||
|
|
||||||
class CPU;
|
class CPU;
|
||||||
|
|
||||||
|
@ -112,15 +113,16 @@ public:
|
||||||
};
|
};
|
||||||
|
|
||||||
class CPU {
|
class CPU {
|
||||||
std::unique_ptr<Dynarmic::A32::Jit> jit;
|
std::unique_ptr<Dynarmic::A32::Jit> jit;
|
||||||
std::shared_ptr<CP15> cp15;
|
std::shared_ptr<CP15> cp15;
|
||||||
|
|
||||||
// Make exclusive monitor with only 1 CPU core
|
// Make exclusive monitor with only 1 CPU core
|
||||||
Dynarmic::ExclusiveMonitor exclusiveMonitor{1};
|
Dynarmic::ExclusiveMonitor exclusiveMonitor{1};
|
||||||
MyEnvironment env;
|
MyEnvironment env;
|
||||||
Memory& mem;
|
Memory& mem;
|
||||||
|
Scheduler scheduler;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
static constexpr u64 ticksPerSec = 268111856;
|
static constexpr u64 ticksPerSec = 268111856;
|
||||||
|
|
||||||
CPU(Memory& mem, Kernel& kernel);
|
CPU(Memory& mem, Kernel& kernel);
|
||||||
|
|
50
include/scheduler.hpp
Normal file
50
include/scheduler.hpp
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
#pragma once
|
||||||
|
#include <boost/container/flat_map.hpp>
|
||||||
|
#include <boost/container/static_vector.hpp>
|
||||||
|
#include <limits>
|
||||||
|
#include <ranges>
|
||||||
|
|
||||||
|
#include "helpers.hpp"
|
||||||
|
|
||||||
|
struct Scheduler {
|
||||||
|
enum class EventType {
|
||||||
|
VBlank = 0, // End of frame event
|
||||||
|
Panic = 1, // Dummy event that is always pending and should never be triggered (Timestamp = UINT64_MAX)
|
||||||
|
TotalNumberOfEvents // How many event types do we have in total?
|
||||||
|
};
|
||||||
|
static constexpr usize totalNumberOfEvents = static_cast<usize>(EventType::TotalNumberOfEvents);
|
||||||
|
|
||||||
|
template <typename Key, typename Val, usize size>
|
||||||
|
using EventMap = boost::container::flat_multimap<Key, Val, std::less<Key>, boost::container::static_vector<std::pair<Key, Val>, size>>;
|
||||||
|
|
||||||
|
EventMap<u64, EventType, totalNumberOfEvents> events;
|
||||||
|
u64 currentTimestamp = 0;
|
||||||
|
u64 nextTimestamp = 0;
|
||||||
|
|
||||||
|
// Set nextTimestamp to the timestamp of the next event
|
||||||
|
void updateNextTimestamp() { nextTimestamp = events.cbegin()->first; }
|
||||||
|
void addCycles(u64 cycles) { currentTimestamp += cycles; }
|
||||||
|
|
||||||
|
void addEvent(EventType type, u64 timestamp) {
|
||||||
|
events.emplace(timestamp, type);
|
||||||
|
updateNextTimestamp();
|
||||||
|
}
|
||||||
|
|
||||||
|
void removeEvent(EventType type) {
|
||||||
|
auto it = std::ranges::find_if(events, [type](decltype(events)::const_reference pair) { return pair.second == type; });
|
||||||
|
|
||||||
|
if (it != events.end()) {
|
||||||
|
events.erase(it);
|
||||||
|
updateNextTimestamp();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void reset() {
|
||||||
|
currentTimestamp = 0;
|
||||||
|
|
||||||
|
// Clear any pending events
|
||||||
|
events.clear();
|
||||||
|
// Add a dummy event to always keep the scheduler non-empty
|
||||||
|
addEvent(EventType::Panic, std::numeric_limits<u64>::max());
|
||||||
|
}
|
||||||
|
};
|
|
@ -1,32 +1,37 @@
|
||||||
#ifdef CPU_DYNARMIC
|
#ifdef CPU_DYNARMIC
|
||||||
#include "cpu_dynarmic.hpp"
|
#include "cpu_dynarmic.hpp"
|
||||||
|
|
||||||
#include "arm_defs.hpp"
|
#include "arm_defs.hpp"
|
||||||
|
|
||||||
CPU::CPU(Memory& mem, Kernel& kernel) : mem(mem), env(mem, kernel) {
|
CPU::CPU(Memory& mem, Kernel& kernel) : mem(mem), env(mem, kernel) {
|
||||||
cp15 = std::make_shared<CP15>();
|
cp15 = std::make_shared<CP15>();
|
||||||
|
|
||||||
Dynarmic::A32::UserConfig config;
|
Dynarmic::A32::UserConfig config;
|
||||||
config.arch_version = Dynarmic::A32::ArchVersion::v6K;
|
config.arch_version = Dynarmic::A32::ArchVersion::v6K;
|
||||||
config.callbacks = &env;
|
config.callbacks = &env;
|
||||||
config.coprocessors[15] = cp15;
|
config.coprocessors[15] = cp15;
|
||||||
config.define_unpredictable_behaviour = true;
|
config.define_unpredictable_behaviour = true;
|
||||||
config.global_monitor = &exclusiveMonitor;
|
config.global_monitor = &exclusiveMonitor;
|
||||||
config.processor_id = 0;
|
config.processor_id = 0;
|
||||||
|
|
||||||
jit = std::make_unique<Dynarmic::A32::Jit>(config);
|
jit = std::make_unique<Dynarmic::A32::Jit>(config);
|
||||||
}
|
}
|
||||||
|
|
||||||
void CPU::reset() {
|
void CPU::reset() {
|
||||||
setCPSR(CPSR::UserMode);
|
setCPSR(CPSR::UserMode);
|
||||||
setFPSCR(FPSCR::MainThreadDefault);
|
setFPSCR(FPSCR::MainThreadDefault);
|
||||||
env.totalTicks = 0;
|
env.totalTicks = 0;
|
||||||
|
|
||||||
cp15->reset();
|
cp15->reset();
|
||||||
cp15->setTLSBase(VirtualAddrs::TLSBase); // Set cp15 TLS pointer to the main thread's thread-local storage
|
cp15->setTLSBase(VirtualAddrs::TLSBase); // Set cp15 TLS pointer to the main thread's thread-local storage
|
||||||
jit->Reset();
|
jit->Reset();
|
||||||
jit->ClearCache();
|
jit->ClearCache();
|
||||||
jit->Regs().fill(0);
|
jit->Regs().fill(0);
|
||||||
jit->ExtRegs().fill(0);
|
jit->ExtRegs().fill(0);
|
||||||
|
|
||||||
|
// Reset scheduler and add a VBlank event
|
||||||
|
scheduler.reset();
|
||||||
|
scheduler.addEvent(Scheduler::EventType::VBlank, ticksPerSec / 60);
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // CPU_DYNARMIC
|
#endif // CPU_DYNARMIC
|
Loading…
Add table
Reference in a new issue