Merge remote-tracking branch 'upstream/master' into feature/savestates-2

This commit is contained in:
Hamish Milne 2020-03-28 12:46:24 +00:00
commit 03379b2072
17 changed files with 224 additions and 93 deletions

View file

@ -319,7 +319,7 @@ System::ResultStatus System::Init(Frontend::EmuWindow& emu_window, u32 system_mo
memory = std::make_unique<Memory::MemorySystem>();
timing = std::make_unique<Timing>(num_cores);
timing = std::make_unique<Timing>(num_cores, Settings::values.cpu_clock_percentage);
kernel = std::make_unique<Kernel::KernelSystem>(
*memory, *timing, [this] { PrepareReschedule(); }, system_mode, num_cores, n3ds_mode);

View file

@ -22,14 +22,21 @@ bool Timing::Event::operator<(const Timing::Event& right) const {
return std::tie(time, fifo_order) < std::tie(right.time, right.fifo_order);
}
Timing::Timing(std::size_t num_cores) {
Timing::Timing(std::size_t num_cores, u32 cpu_clock_percentage) {
timers.resize(num_cores);
for (std::size_t i = 0; i < num_cores; ++i) {
timers[i] = std::make_shared<Timer>();
}
UpdateClockSpeed(cpu_clock_percentage);
current_timer = timers[0];
}
void Timing::UpdateClockSpeed(u32 cpu_clock_percentage) {
for (auto& timer : timers) {
timer->cpu_clock_scale = 100.0 / cpu_clock_percentage;
}
}
TimingEventType* Timing::RegisterEvent(const std::string& name, TimedCallback callback) {
// check for existing type with same name.
// we want event type names to remain unique so that we can use them for serialization.
@ -117,6 +124,8 @@ std::shared_ptr<Timing::Timer> Timing::GetTimer(std::size_t cpu_id) {
return timers[cpu_id];
}
Timing::Timer::Timer() = default;
Timing::Timer::~Timer() {
MoveEvents();
}
@ -130,7 +139,7 @@ u64 Timing::Timer::GetTicks() const {
}
void Timing::Timer::AddTicks(u64 ticks) {
downcount -= ticks;
downcount -= static_cast<u64>(ticks * cpu_clock_scale);
}
u64 Timing::Timer::GetIdleTicks() const {

View file

@ -176,6 +176,7 @@ public:
class Timer {
public:
Timer();
~Timer();
s64 GetMaxSliceLength() const;
@ -218,7 +219,10 @@ public:
s64 slice_length = MAX_SLICE_LENGTH;
s64 downcount = MAX_SLICE_LENGTH;
s64 executed_ticks = 0;
u64 idled_cycles;
u64 idled_cycles = 0;
// Stores a scaling for the internal clockspeed. Changing this number results in
// under/overclocking the guest cpu
double cpu_clock_scale = 1.0;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
@ -234,7 +238,7 @@ public:
friend class boost::serialization::access;
};
explicit Timing(std::size_t num_cores);
explicit Timing(std::size_t num_cores, u32 cpu_clock_percentage);
~Timing(){};
@ -261,6 +265,11 @@ public:
global_timer += ticks;
}
/**
* Updates the value of the cpu clock scaling to the new percentage.
*/
void UpdateClockSpeed(u32 cpu_clock_percentage);
std::chrono::microseconds GetGlobalTimeUs() const;
std::shared_ptr<Timer> GetTimer(std::size_t cpu_id);
@ -270,11 +279,15 @@ private:
// unordered_map stores each element separately as a linked list node so pointers to
// elements remain stable regardless of rehashes/resizing.
std::unordered_map<std::string, TimingEventType> event_types;
std::unordered_map<std::string, TimingEventType> event_types = {};
std::vector<std::shared_ptr<Timer>> timers;
std::shared_ptr<Timer> current_timer;
// Stores a scaling for the internal clockspeed. Changing this number results in
// under/overclocking the guest cpu
double cpu_clock_scale = 1.0;
template <class Archive>
void serialize(Archive& ar, const unsigned int) {
// event_types set during initialization of other things

View file

@ -152,13 +152,16 @@ ResultCode VMManager::ChangeMemoryState(VAddr target, u32 size, MemoryState expe
}
CASCADE_RESULT(auto vma, CarveVMARange(target, size));
ASSERT(vma->second.size == size);
vma->second.permissions = new_perms;
vma->second.meminfo_state = new_state;
UpdatePageTableForVMA(vma->second);
MergeAdjacent(vma);
const VMAIter end = vma_map.end();
// The comparison against the end of the range must be done using addresses since VMAs can be
// merged during this process, causing invalidation of the iterators.
while (vma != end && vma->second.base < target_end) {
vma->second.permissions = new_perms;
vma->second.meminfo_state = new_state;
UpdatePageTableForVMA(vma->second);
vma = std::next(MergeAdjacent(vma));
}
return RESULT_SUCCESS;
}

View file

@ -46,10 +46,17 @@ static const ResultCode ERROR_NOT_LOADED = // 0xD8A12C0D
static bool VerifyBufferState(Kernel::Process& process, VAddr buffer_ptr, u32 size) {
auto vma = process.vm_manager.FindVMA(buffer_ptr);
return vma != process.vm_manager.vma_map.end() &&
vma->second.base + vma->second.size >= buffer_ptr + size &&
vma->second.permissions == Kernel::VMAPermission::ReadWrite &&
vma->second.meminfo_state == Kernel::MemoryState::Private;
while (vma != process.vm_manager.vma_map.end()) {
if (vma->second.permissions != Kernel::VMAPermission::ReadWrite ||
vma->second.meminfo_state != Kernel::MemoryState::Private) {
return false;
}
if (vma->second.base + vma->second.size >= buffer_ptr + size) {
return true;
}
vma = std::next(vma);
}
return false;
}
void RO::Initialize(Kernel::HLERequestContext& ctx) {

View file

@ -44,6 +44,7 @@ void Apply() {
auto& system = Core::System::GetInstance();
if (system.IsPoweredOn()) {
system.CoreTiming().UpdateClockSpeed(values.cpu_clock_percentage);
Core::DSP().SetSink(values.sink_id, values.audio_device_id);
Core::DSP().EnableStretching(values.enable_audio_stretching);

View file

@ -128,6 +128,7 @@ struct Values {
// Core
bool use_cpu_jit;
int cpu_clock_percentage;
// Data Storage
bool use_virtual_sd;