* Add thread preemption when a thread wakes up from a timeout * Add arbiter sleeping with timeout Update threads.cpp * Scheduler: Fix event numbers * More address arbiter fixes * Update preempt threads branch (#755) * CI: Fix Vulkan SDK action (#723) * GPU registers: Fix writes to some registers ignoring the mask (#725) Co-authored-by: henry <23128103+atem2069@users.noreply.github.com> * OLED theme * OLED theme config fix (#736) Co-authored-by: smiRaphi <neogt404@gmail.com> * Adding Swedish translation * Fix Metal renderer compilation on iOS * [Core] Improve iOS compilation workflow * [Qt] Hook Swedish to UI * AppDataDocumentProvider: Typo (#740) * More iOS work * More iOS progress * More iOS work * AppDataDocumentProvider: Add missing ``COLUMN_FLAGS`` in the default document projectation (#741) Fixes unable to copy files from device to app's internal storage problem * More iOS work * ios: Simplify MTKView interface (still doesn't work though) * ios: Pass CAMetalLayer instead of void* to Obj-C++ bridging header * Fix bridging cast * FINALLY IOS GRAPHICS * ios: Remove printf spam * Metal: Reimplement some texture formats on iOS * metal: implement texture decoder * metal: check for format support * metal: implement texture swizzling * metal: remove unused texture functions * Shadergen types: Add Metal & MSL * Format * Undo submodule changes * Readme: Add Chonkystation 3 * Metal: Use std::unique_ptr for texture decode * AppDataDocumentProvider: Allow to remove documents (#744) * AppDataDocumentProvider: Allow to remove documents * Typo * Metal renderer fixes for iOS * iOS driver: Add doc comments * iOS: Add frontend & frontend build files (#746) * iOS: Add SwiftUI part to repo * Add iOS build script * Update SDL2 submodule * Fix iOS build script * CI: Update xcode tools for iOS * Update iOS_Build.yml * Update iOS build * Lower XCode version * A * Update project.pbxproj * Update iOS_Build.yml * Update iOS_Build.yml * Update build.sh * iOS: Fail on build error * iOS: Add file picker (#747) * iOS: Add file picker * Fix lock placement * Qt: Add runpog icon (#752) * Update discord-rpc submodule (#753) * Remove cryptoppwin submodule (#754) --------- Co-authored-by: henry <23128103+atem2069@users.noreply.github.com> Co-authored-by: smiRaphi <neogt404@gmail.com> Co-authored-by: smiRaphi <87574679+smiRaphi@users.noreply.github.com> Co-authored-by: Daniel Nylander <po@danielnylander.se> Co-authored-by: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Co-authored-by: Samuliak <samuliak77@gmail.com> Co-authored-by: Albert <45282415+ggrtk@users.noreply.github.com> --------- Co-authored-by: henry <23128103+atem2069@users.noreply.github.com> Co-authored-by: smiRaphi <neogt404@gmail.com> Co-authored-by: smiRaphi <87574679+smiRaphi@users.noreply.github.com> Co-authored-by: Daniel Nylander <po@danielnylander.se> Co-authored-by: Ishan09811 <156402647+Ishan09811@users.noreply.github.com> Co-authored-by: Samuliak <samuliak77@gmail.com> Co-authored-by: Albert <45282415+ggrtk@users.noreply.github.com>
93 lines
3.0 KiB
C++
93 lines
3.0 KiB
C++
#pragma once
|
|
#include <boost/container/flat_map.hpp>
|
|
#include <boost/container/static_vector.hpp>
|
|
#include <limits>
|
|
|
|
#include "helpers.hpp"
|
|
|
|
struct Scheduler {
|
|
enum class EventType {
|
|
VBlank = 0, // End of frame event
|
|
ThreadWakeup = 1, // A thread might wake up from eg sleeping or timing outs
|
|
RunDSP = 2, // Make the emulated DSP run for one audio frame
|
|
UpdateTimers = 3, // Update kernel timer objects
|
|
SignalY2R = 4, // Signal that a Y2R conversion has finished
|
|
UpdateIR = 5, // Update an IR device (For now, just the CirclePad Pro/N3DS controls)
|
|
Panic = 6, // 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);
|
|
static constexpr u64 arm11Clock = 268111856;
|
|
|
|
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 addEvent(EventType type, u64 timestamp) {
|
|
events.emplace(timestamp, type);
|
|
updateNextTimestamp();
|
|
}
|
|
|
|
void removeEvent(EventType type) {
|
|
for (auto it = events.begin(); it != events.end(); it++) {
|
|
// Find first event of type "type" and remove it.
|
|
// Our scheduler shouldn't have duplicate events, so it's safe to exit when an event is found
|
|
if (it->second == type) {
|
|
events.erase(it);
|
|
updateNextTimestamp();
|
|
break;
|
|
}
|
|
}
|
|
};
|
|
|
|
void reset() {
|
|
currentTimestamp = 0;
|
|
|
|
// Clear any pending events
|
|
events.clear();
|
|
addEvent(Scheduler::EventType::VBlank, arm11Clock / 60);
|
|
|
|
// Add a dummy event to always keep the scheduler non-empty
|
|
addEvent(EventType::Panic, std::numeric_limits<u64>::max());
|
|
}
|
|
|
|
private:
|
|
static constexpr u64 MAX_VALUE_TO_MULTIPLY = std::numeric_limits<s64>::max() / arm11Clock;
|
|
|
|
public:
|
|
// Function for converting time units to cycles for various kernel functions
|
|
// Thank you Citra
|
|
static constexpr s64 nsToCycles(float ns) { return s64(arm11Clock * (0.000000001f) * ns); }
|
|
static constexpr s64 nsToCycles(int ns) { return arm11Clock * s64(ns) / 1000000000; }
|
|
|
|
static constexpr s64 nsToCycles(s64 ns) {
|
|
if (ns / 1000000000 > static_cast<s64>(MAX_VALUE_TO_MULTIPLY)) {
|
|
return std::numeric_limits<s64>::max();
|
|
}
|
|
|
|
if (ns > static_cast<s64>(MAX_VALUE_TO_MULTIPLY)) {
|
|
return arm11Clock * (ns / 1000000000);
|
|
}
|
|
|
|
return (arm11Clock * ns) / 1000000000;
|
|
}
|
|
|
|
static constexpr s64 nsToCycles(u64 ns) {
|
|
if (ns / 1000000000 > MAX_VALUE_TO_MULTIPLY) {
|
|
return std::numeric_limits<s64>::max();
|
|
}
|
|
|
|
if (ns > MAX_VALUE_TO_MULTIPLY) {
|
|
return arm11Clock * (s64(ns) / 1000000000);
|
|
}
|
|
|
|
return (arm11Clock * s64(ns)) / 1000000000;
|
|
}
|
|
};
|