common/fiber: make fibers easier to use
This commit is contained in:
		@@ -41,51 +41,32 @@ void CpuManager::Shutdown() {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::function<void(void*)> CpuManager::GetGuestThreadStartFunc() {
 | 
			
		||||
    return GuestThreadFunction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::function<void(void*)> CpuManager::GetIdleThreadStartFunc() {
 | 
			
		||||
    return IdleThreadFunction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::function<void(void*)> CpuManager::GetShutdownThreadStartFunc() {
 | 
			
		||||
    return ShutdownThreadFunction;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CpuManager::GuestThreadFunction(void* cpu_manager_) {
 | 
			
		||||
    CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
 | 
			
		||||
    if (cpu_manager->is_multicore) {
 | 
			
		||||
        cpu_manager->MultiCoreRunGuestThread();
 | 
			
		||||
void CpuManager::GuestThreadFunction() {
 | 
			
		||||
    if (is_multicore) {
 | 
			
		||||
        MultiCoreRunGuestThread();
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_manager->SingleCoreRunGuestThread();
 | 
			
		||||
        SingleCoreRunGuestThread();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CpuManager::GuestRewindFunction(void* cpu_manager_) {
 | 
			
		||||
    CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
 | 
			
		||||
    if (cpu_manager->is_multicore) {
 | 
			
		||||
        cpu_manager->MultiCoreRunGuestLoop();
 | 
			
		||||
void CpuManager::GuestRewindFunction() {
 | 
			
		||||
    if (is_multicore) {
 | 
			
		||||
        MultiCoreRunGuestLoop();
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_manager->SingleCoreRunGuestLoop();
 | 
			
		||||
        SingleCoreRunGuestLoop();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CpuManager::IdleThreadFunction(void* cpu_manager_) {
 | 
			
		||||
    CpuManager* cpu_manager = static_cast<CpuManager*>(cpu_manager_);
 | 
			
		||||
    if (cpu_manager->is_multicore) {
 | 
			
		||||
        cpu_manager->MultiCoreRunIdleThread();
 | 
			
		||||
void CpuManager::IdleThreadFunction() {
 | 
			
		||||
    if (is_multicore) {
 | 
			
		||||
        MultiCoreRunIdleThread();
 | 
			
		||||
    } else {
 | 
			
		||||
        cpu_manager->SingleCoreRunIdleThread();
 | 
			
		||||
        SingleCoreRunIdleThread();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void CpuManager::ShutdownThreadFunction(void* cpu_manager) {
 | 
			
		||||
    static_cast<CpuManager*>(cpu_manager)->ShutdownThread();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void* CpuManager::GetStartFuncParameter() {
 | 
			
		||||
    return this;
 | 
			
		||||
void CpuManager::ShutdownThreadFunction() {
 | 
			
		||||
    ShutdownThread();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
///////////////////////////////////////////////////////////////////////////////
 | 
			
		||||
@@ -97,7 +78,7 @@ void CpuManager::MultiCoreRunGuestThread() {
 | 
			
		||||
    kernel.CurrentScheduler()->OnThreadStart();
 | 
			
		||||
    auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
 | 
			
		||||
    auto& host_context = thread->GetHostContext();
 | 
			
		||||
    host_context->SetRewindPoint(GuestRewindFunction, this);
 | 
			
		||||
    host_context->SetRewindPoint([this] { GuestRewindFunction(); });
 | 
			
		||||
    MultiCoreRunGuestLoop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -134,7 +115,7 @@ void CpuManager::SingleCoreRunGuestThread() {
 | 
			
		||||
    kernel.CurrentScheduler()->OnThreadStart();
 | 
			
		||||
    auto* thread = kernel.CurrentScheduler()->GetSchedulerCurrentThread();
 | 
			
		||||
    auto& host_context = thread->GetHostContext();
 | 
			
		||||
    host_context->SetRewindPoint(GuestRewindFunction, this);
 | 
			
		||||
    host_context->SetRewindPoint([this] { GuestRewindFunction(); });
 | 
			
		||||
    SingleCoreRunGuestLoop();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -50,10 +50,15 @@ public:
 | 
			
		||||
    void Initialize();
 | 
			
		||||
    void Shutdown();
 | 
			
		||||
 | 
			
		||||
    static std::function<void(void*)> GetGuestThreadStartFunc();
 | 
			
		||||
    static std::function<void(void*)> GetIdleThreadStartFunc();
 | 
			
		||||
    static std::function<void(void*)> GetShutdownThreadStartFunc();
 | 
			
		||||
    void* GetStartFuncParameter();
 | 
			
		||||
    std::function<void()> GetGuestThreadStartFunc() {
 | 
			
		||||
        return [this] { GuestThreadFunction(); };
 | 
			
		||||
    }
 | 
			
		||||
    std::function<void()> GetIdleThreadStartFunc() {
 | 
			
		||||
        return [this] { IdleThreadFunction(); };
 | 
			
		||||
    }
 | 
			
		||||
    std::function<void()> GetShutdownThreadStartFunc() {
 | 
			
		||||
        return [this] { ShutdownThreadFunction(); };
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    void PreemptSingleCore(bool from_running_enviroment = true);
 | 
			
		||||
 | 
			
		||||
@@ -62,10 +67,10 @@ public:
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
private:
 | 
			
		||||
    static void GuestThreadFunction(void* cpu_manager);
 | 
			
		||||
    static void GuestRewindFunction(void* cpu_manager);
 | 
			
		||||
    static void IdleThreadFunction(void* cpu_manager);
 | 
			
		||||
    static void ShutdownThreadFunction(void* cpu_manager);
 | 
			
		||||
    void GuestThreadFunction();
 | 
			
		||||
    void GuestRewindFunction();
 | 
			
		||||
    void IdleThreadFunction();
 | 
			
		||||
    void ShutdownThreadFunction();
 | 
			
		||||
 | 
			
		||||
    void MultiCoreRunGuestThread();
 | 
			
		||||
    void MultiCoreRunGuestLoop();
 | 
			
		||||
 
 | 
			
		||||
@@ -622,7 +622,7 @@ void KScheduler::YieldToAnyThread(KernelCore& kernel) {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
KScheduler::KScheduler(Core::System& system_, s32 core_id_) : system{system_}, core_id{core_id_} {
 | 
			
		||||
    switch_fiber = std::make_shared<Common::Fiber>(OnSwitch, this);
 | 
			
		||||
    switch_fiber = std::make_shared<Common::Fiber>([this] { SwitchToCurrent(); });
 | 
			
		||||
    state.needs_scheduling.store(true);
 | 
			
		||||
    state.interrupt_task_thread_runnable = false;
 | 
			
		||||
    state.should_count_idle = false;
 | 
			
		||||
@@ -778,11 +778,6 @@ void KScheduler::ScheduleImpl() {
 | 
			
		||||
    next_scheduler.SwitchContextStep2();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KScheduler::OnSwitch(void* this_scheduler) {
 | 
			
		||||
    KScheduler* sched = static_cast<KScheduler*>(this_scheduler);
 | 
			
		||||
    sched->SwitchToCurrent();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KScheduler::SwitchToCurrent() {
 | 
			
		||||
    while (true) {
 | 
			
		||||
        {
 | 
			
		||||
 
 | 
			
		||||
@@ -165,7 +165,6 @@ private:
 | 
			
		||||
     */
 | 
			
		||||
    void UpdateLastContextSwitchTime(KThread* thread, KProcess* process);
 | 
			
		||||
 | 
			
		||||
    static void OnSwitch(void* this_scheduler);
 | 
			
		||||
    void SwitchToCurrent();
 | 
			
		||||
 | 
			
		||||
    KThread* prev_thread{};
 | 
			
		||||
 
 | 
			
		||||
@@ -246,14 +246,12 @@ Result KThread::Initialize(KThreadFunction func, uintptr_t arg, VAddr user_stack
 | 
			
		||||
 | 
			
		||||
Result KThread::InitializeThread(KThread* thread, KThreadFunction func, uintptr_t arg,
 | 
			
		||||
                                 VAddr user_stack_top, s32 prio, s32 core, KProcess* owner,
 | 
			
		||||
                                 ThreadType type, std::function<void(void*)>&& init_func,
 | 
			
		||||
                                 void* init_func_parameter) {
 | 
			
		||||
                                 ThreadType type, std::function<void()>&& init_func) {
 | 
			
		||||
    // Initialize the thread.
 | 
			
		||||
    R_TRY(thread->Initialize(func, arg, user_stack_top, prio, core, owner, type));
 | 
			
		||||
 | 
			
		||||
    // Initialize emulation parameters.
 | 
			
		||||
    thread->host_context =
 | 
			
		||||
        std::make_shared<Common::Fiber>(std::move(init_func), init_func_parameter);
 | 
			
		||||
    thread->host_context = std::make_shared<Common::Fiber>(std::move(init_func));
 | 
			
		||||
    thread->is_single_core = !Settings::values.use_multi_core.GetValue();
 | 
			
		||||
 | 
			
		||||
    return ResultSuccess;
 | 
			
		||||
@@ -265,15 +263,13 @@ Result KThread::InitializeDummyThread(KThread* thread) {
 | 
			
		||||
 | 
			
		||||
Result KThread::InitializeIdleThread(Core::System& system, KThread* thread, s32 virt_core) {
 | 
			
		||||
    return InitializeThread(thread, {}, {}, {}, IdleThreadPriority, virt_core, {}, ThreadType::Main,
 | 
			
		||||
                            Core::CpuManager::GetIdleThreadStartFunc(),
 | 
			
		||||
                            system.GetCpuManager().GetStartFuncParameter());
 | 
			
		||||
                            system.GetCpuManager().GetIdleThreadStartFunc());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Result KThread::InitializeHighPriorityThread(Core::System& system, KThread* thread,
 | 
			
		||||
                                             KThreadFunction func, uintptr_t arg, s32 virt_core) {
 | 
			
		||||
    return InitializeThread(thread, func, arg, {}, {}, virt_core, nullptr, ThreadType::HighPriority,
 | 
			
		||||
                            Core::CpuManager::GetShutdownThreadStartFunc(),
 | 
			
		||||
                            system.GetCpuManager().GetStartFuncParameter());
 | 
			
		||||
                            system.GetCpuManager().GetShutdownThreadStartFunc());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThreadFunction func,
 | 
			
		||||
@@ -281,8 +277,7 @@ Result KThread::InitializeUserThread(Core::System& system, KThread* thread, KThr
 | 
			
		||||
                                     KProcess* owner) {
 | 
			
		||||
    system.Kernel().GlobalSchedulerContext().AddThread(thread);
 | 
			
		||||
    return InitializeThread(thread, func, arg, user_stack_top, prio, virt_core, owner,
 | 
			
		||||
                            ThreadType::User, Core::CpuManager::GetGuestThreadStartFunc(),
 | 
			
		||||
                            system.GetCpuManager().GetStartFuncParameter());
 | 
			
		||||
                            ThreadType::User, system.GetCpuManager().GetGuestThreadStartFunc());
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void KThread::PostDestroy(uintptr_t arg) {
 | 
			
		||||
 
 | 
			
		||||
@@ -729,8 +729,7 @@ private:
 | 
			
		||||
    [[nodiscard]] static Result InitializeThread(KThread* thread, KThreadFunction func,
 | 
			
		||||
                                                 uintptr_t arg, VAddr user_stack_top, s32 prio,
 | 
			
		||||
                                                 s32 core, KProcess* owner, ThreadType type,
 | 
			
		||||
                                                 std::function<void(void*)>&& init_func,
 | 
			
		||||
                                                 void* init_func_parameter);
 | 
			
		||||
                                                 std::function<void()>&& init_func);
 | 
			
		||||
 | 
			
		||||
    static void RestorePriority(KernelCore& kernel_ctx, KThread* thread);
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user