mirror of
https://git.eden-emu.dev/eden-emu/eden.git
synced 2026-10-28 10:31:18 +00:00
Fix license headers
This commit is contained in:
@@ -459,6 +459,7 @@ struct System::Impl {
|
|||||||
fs_controller.Reset();
|
fs_controller.Reset();
|
||||||
cheat_engine.reset();
|
cheat_engine.reset();
|
||||||
core_timing.ClearPendingEvents();
|
core_timing.ClearPendingEvents();
|
||||||
|
core_timing.Reset();
|
||||||
app_loader.reset();
|
app_loader.reset();
|
||||||
audio_core.reset();
|
audio_core.reset();
|
||||||
gpu_core.reset();
|
gpu_core.reset();
|
||||||
|
|||||||
@@ -304,10 +304,10 @@ std::optional<s64> CoreTiming::Advance() {
|
|||||||
|
|
||||||
void CoreTiming::Reset() {
|
void CoreTiming::Reset() {
|
||||||
paused = true;
|
paused = true;
|
||||||
pause_event.Set();
|
|
||||||
event.Set();
|
|
||||||
if (timer_thread.joinable()) {
|
if (timer_thread.joinable()) {
|
||||||
timer_thread.request_stop();
|
timer_thread.request_stop();
|
||||||
|
pause_event.Set();
|
||||||
|
event.Set();
|
||||||
timer_thread.join();
|
timer_thread.join();
|
||||||
}
|
}
|
||||||
has_started = false;
|
has_started = false;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
|
#include <thread>
|
||||||
#include "common/assert.h"
|
#include "common/assert.h"
|
||||||
#include "core/hle/kernel/k_process.h"
|
#include "core/hle/kernel/k_process.h"
|
||||||
#include "core/hle/kernel/k_thread.h"
|
#include "core/hle/kernel/k_thread.h"
|
||||||
@@ -26,7 +27,15 @@ void KWorkerTask::DoWorkerTask(KernelCore& kernel) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
KWorkerTaskManager::KWorkerTaskManager() : m_waiting_thread(1, "KWorkerTaskManager") {}
|
KWorkerTaskManager::KWorkerTaskManager() {}
|
||||||
|
|
||||||
|
KWorkerTaskManager::~KWorkerTaskManager() {
|
||||||
|
if (m_waiting_thread.joinable()) {
|
||||||
|
m_waiting_thread.request_stop();
|
||||||
|
m_task_cv.notify_one();
|
||||||
|
m_waiting_thread.join();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task) {
|
void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task) {
|
||||||
ASSERT(type <= WorkerType::Count);
|
ASSERT(type <= WorkerType::Count);
|
||||||
@@ -35,10 +44,31 @@ void KWorkerTaskManager::AddTask(KernelCore& kernel, WorkerType type, KWorkerTas
|
|||||||
|
|
||||||
void KWorkerTaskManager::AddTask(KernelCore& kernel, KWorkerTask* task) {
|
void KWorkerTaskManager::AddTask(KernelCore& kernel, KWorkerTask* task) {
|
||||||
KScopedSchedulerLock sl(kernel);
|
KScopedSchedulerLock sl(kernel);
|
||||||
m_waiting_thread.QueueWork([&kernel, task]() {
|
|
||||||
// Do the task.
|
// spawn thread on demand
|
||||||
task->DoWorkerTask(kernel);
|
if (!m_waiting_thread.joinable()) {
|
||||||
|
LOG_INFO(Kernel, "spawning KWorkerTaskManager thread");
|
||||||
|
m_waiting_thread = std::jthread([&kernel, this](std::stop_token stop_token) {
|
||||||
|
while (!stop_token.stop_requested()) {
|
||||||
|
KWorkerTask* t;
|
||||||
|
{
|
||||||
|
std::unique_lock lk{m_task_mutex};
|
||||||
|
m_task_cv.wait(lk);
|
||||||
|
if (stop_token.stop_requested())
|
||||||
|
break;
|
||||||
|
t = m_task_queue.back();
|
||||||
|
m_task_queue.pop_back();
|
||||||
|
}
|
||||||
|
t->DoWorkerTask(kernel);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
std::scoped_lock lk{m_task_mutex};
|
||||||
|
m_task_queue.emplace_back(task);
|
||||||
|
}
|
||||||
|
m_task_cv.notify_one();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|||||||
@@ -1,8 +1,13 @@
|
|||||||
|
// SPDX-FileCopyrightText: Copyright 2026 Eden Emulator Project
|
||||||
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
// SPDX-FileCopyrightText: Copyright 2022 yuzu Emulator Project
|
||||||
// SPDX-License-Identifier: GPL-2.0-or-later
|
// SPDX-License-Identifier: GPL-2.0-or-later
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include <condition_variable>
|
||||||
|
#include <thread>
|
||||||
#include "common/common_types.h"
|
#include "common/common_types.h"
|
||||||
#include "common/thread_worker.h"
|
#include "common/thread_worker.h"
|
||||||
|
|
||||||
@@ -19,14 +24,16 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
KWorkerTaskManager();
|
KWorkerTaskManager();
|
||||||
|
~KWorkerTaskManager();
|
||||||
|
|
||||||
static void AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task);
|
static void AddTask(KernelCore& kernel, WorkerType type, KWorkerTask* task);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddTask(KernelCore& kernel, KWorkerTask* task);
|
void AddTask(KernelCore& kernel, KWorkerTask* task);
|
||||||
|
std::jthread m_waiting_thread;
|
||||||
|
|
||||||
private:
|
std::mutex m_task_mutex;
|
||||||
Common::ThreadWorker m_waiting_thread;
|
std::condition_variable m_task_cv;
|
||||||
|
std::vector<KWorkerTask*> m_task_queue;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace Kernel
|
} // namespace Kernel
|
||||||
|
|||||||
@@ -20,15 +20,17 @@
|
|||||||
|
|
||||||
namespace Service::Glue::Time {
|
namespace Service::Glue::Time {
|
||||||
|
|
||||||
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource,
|
TimeWorker::TimeWorker(Core::System& system, StandardSteadyClockResource& steady_clock_resource, FileTimestampWorker& file_timestamp_worker)
|
||||||
FileTimestampWorker& file_timestamp_worker)
|
: m_system{system}
|
||||||
: m_system{system}, m_ctx{m_system, "Glue:TimeWorker"}, m_event{m_ctx.CreateEvent(
|
, m_ctx{m_system, "Glue:TimeWorker"}
|
||||||
"Glue:TimeWorker:Event")},
|
, m_event{m_ctx.CreateEvent("Glue:TimeWorker:Event")}
|
||||||
m_steady_clock_resource{steady_clock_resource},
|
, m_steady_clock_resource{steady_clock_resource}
|
||||||
m_file_timestamp_worker{file_timestamp_worker}, m_timer_steady_clock{m_ctx.CreateEvent(
|
, m_file_timestamp_worker{file_timestamp_worker}
|
||||||
"Glue:TimeWorker:SteadyClockTimerEvent")},
|
, m_timer_steady_clock{m_ctx.CreateEvent("Glue:TimeWorker:SteadyClockTimerEvent")}
|
||||||
m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")},
|
, m_timer_file_system{m_ctx.CreateEvent("Glue:TimeWorker:FileTimeTimerEvent")}
|
||||||
m_alarm_worker{m_system, m_steady_clock_resource}, m_pm_state_change_handler{m_alarm_worker} {
|
, m_alarm_worker{m_system, m_steady_clock_resource}
|
||||||
|
, m_pm_state_change_handler{m_alarm_worker}
|
||||||
|
{
|
||||||
m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
|
m_timer_steady_clock_timing_event = Core::Timing::CreateEvent(
|
||||||
"Time::SteadyClockEvent",
|
"Time::SteadyClockEvent",
|
||||||
[this](s64 time,
|
[this](s64 time,
|
||||||
@@ -50,11 +52,12 @@ TimeWorker::~TimeWorker() {
|
|||||||
m_local_clock_event->Signal(m_system.Kernel());
|
m_local_clock_event->Signal(m_system.Kernel());
|
||||||
m_network_clock_event->Signal(m_system.Kernel());
|
m_network_clock_event->Signal(m_system.Kernel());
|
||||||
m_ephemeral_clock_event->Signal(m_system.Kernel());
|
m_ephemeral_clock_event->Signal(m_system.Kernel());
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(16));
|
|
||||||
|
|
||||||
|
if (m_thread.joinable()) {
|
||||||
m_thread.request_stop();
|
m_thread.request_stop();
|
||||||
m_event->Signal(m_system.Kernel());
|
m_event->Signal(m_system.Kernel());
|
||||||
m_thread.join();
|
m_thread.join();
|
||||||
|
}
|
||||||
|
|
||||||
m_ctx.CloseEvent(m_event);
|
m_ctx.CloseEvent(m_event);
|
||||||
m_system.CoreTiming().UnscheduleEvent(m_timer_steady_clock_timing_event);
|
m_system.CoreTiming().UnscheduleEvent(m_timer_steady_clock_timing_event);
|
||||||
@@ -122,13 +125,9 @@ void TimeWorker::Initialize(std::shared_ptr<Service::PSC::Time::StaticService> t
|
|||||||
}
|
}
|
||||||
|
|
||||||
void TimeWorker::StartThread() {
|
void TimeWorker::StartThread() {
|
||||||
m_thread = std::jthread(std::bind_front(&TimeWorker::ThreadFunc, this));
|
m_thread = m_system.Kernel().RunOnHostCoreThread("TimeWorker", [this]() {
|
||||||
}
|
auto const stop_token = m_thread.get_stop_token();
|
||||||
|
|
||||||
void TimeWorker::ThreadFunc(std::stop_token stop_token) {
|
|
||||||
Common::SetCurrentThreadName("TimeWorker");
|
|
||||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::Low);
|
Common::SetCurrentThreadPriority(Common::ThreadPriority::Low);
|
||||||
|
|
||||||
while (!stop_token.stop_requested()) {
|
while (!stop_token.stop_requested()) {
|
||||||
enum class EventType : s32 {
|
enum class EventType : s32 {
|
||||||
Exit = 0,
|
Exit = 0,
|
||||||
@@ -146,13 +145,15 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
|
|||||||
|
|
||||||
if (m_pm_state_change_handler.m_priority != 0) {
|
if (m_pm_state_change_handler.m_priority != 0) {
|
||||||
// TODO: gIPmModuleService::GetEvent() 1
|
// TODO: gIPmModuleService::GetEvent() 1
|
||||||
index = WaitAny(m_system.Kernel(),
|
index = WaitAny(
|
||||||
|
m_system.Kernel(),
|
||||||
&m_event->GetReadableEvent(), // 0
|
&m_event->GetReadableEvent(), // 0
|
||||||
&m_alarm_worker.GetEvent() // 1
|
&m_alarm_worker.GetEvent() // 1
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// TODO: gIPmModuleService::GetEvent() 1
|
// TODO: gIPmModuleService::GetEvent() 1
|
||||||
index = WaitAny(m_system.Kernel(),
|
index = WaitAny(
|
||||||
|
m_system.Kernel(),
|
||||||
&m_event->GetReadableEvent(), // 0
|
&m_event->GetReadableEvent(), // 0
|
||||||
&m_alarm_worker.GetEvent(), // 1
|
&m_alarm_worker.GetEvent(), // 1
|
||||||
&m_alarm_worker.GetTimerEvent().GetReadableEvent(), // 2
|
&m_alarm_worker.GetTimerEvent().GetReadableEvent(), // 2
|
||||||
@@ -165,7 +166,10 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (static_cast<EventType>(index)) {
|
if (stop_token.stop_requested())
|
||||||
|
break;
|
||||||
|
|
||||||
|
switch (EventType(index)) {
|
||||||
case EventType::Exit:
|
case EventType::Exit:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -258,7 +262,6 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
|
|||||||
|
|
||||||
case EventType::UpdateFileTimestamp:
|
case EventType::UpdateFileTimestamp:
|
||||||
m_timer_file_system->Clear(m_system.Kernel());
|
m_timer_file_system->Clear(m_system.Kernel());
|
||||||
|
|
||||||
m_file_timestamp_worker.SetFilesystemPosixTime();
|
m_file_timestamp_worker.SetFilesystemPosixTime();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -266,22 +269,20 @@ void TimeWorker::ThreadFunc(std::stop_token stop_token) {
|
|||||||
m_standard_user_auto_correct_clock_event->Clear(m_system.Kernel());
|
m_standard_user_auto_correct_clock_event->Clear(m_system.Kernel());
|
||||||
|
|
||||||
bool automatic_correction{};
|
bool automatic_correction{};
|
||||||
R_ASSERT(m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled(
|
R_ASSERT(m_time_sm->IsStandardUserSystemClockAutomaticCorrectionEnabled(&automatic_correction));
|
||||||
&automatic_correction));
|
|
||||||
|
|
||||||
Service::PSC::Time::SteadyClockTimePoint time_point{};
|
Service::PSC::Time::SteadyClockTimePoint time_point{};
|
||||||
R_ASSERT(
|
R_ASSERT(m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(&time_point));
|
||||||
m_time_sm->GetStandardUserSystemClockAutomaticCorrectionUpdatedTime(&time_point));
|
|
||||||
|
|
||||||
m_set_sys->SetUserSystemClockAutomaticCorrectionEnabled(automatic_correction);
|
m_set_sys->SetUserSystemClockAutomaticCorrectionEnabled(automatic_correction);
|
||||||
m_set_sys->SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
|
m_set_sys->SetUserSystemClockAutomaticCorrectionUpdatedTime(time_point);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace Service::Glue::Time
|
} // namespace Service::Glue::Time
|
||||||
|
|||||||
@@ -94,6 +94,9 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
|||||||
{"ldn", &LDN::LoopProcess},
|
{"ldn", &LDN::LoopProcess},
|
||||||
{"nvservices", &Nvidia::LoopProcess},
|
{"nvservices", &Nvidia::LoopProcess},
|
||||||
{"bsdsocket", &Sockets::LoopProcess},
|
{"bsdsocket", &Sockets::LoopProcess},
|
||||||
|
// TODO: glue is only required here as otherwise the dummythread doesn't close
|
||||||
|
// TODO: rework sched so this isn't needed
|
||||||
|
{"glue", &Glue::LoopProcess},
|
||||||
})
|
})
|
||||||
kernel.RunOnHostCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); }).detach();
|
kernel.RunOnHostCoreProcess(std::string(e.first), [&system, f = e.second] { f(system); }).detach();
|
||||||
kernel.RunOnHostCoreProcess("vi", [&, token] { VI::LoopProcess(system, token); }).detach();
|
kernel.RunOnHostCoreProcess("vi", [&, token] { VI::LoopProcess(system, token); }).detach();
|
||||||
@@ -117,7 +120,6 @@ Services::Services(std::shared_ptr<SM::ServiceManager>& sm, Core::System& system
|
|||||||
{"friends", &Friend::LoopProcess},
|
{"friends", &Friend::LoopProcess},
|
||||||
{"settings", &Set::LoopProcess},
|
{"settings", &Set::LoopProcess},
|
||||||
{"psc", &PSC::LoopProcess},
|
{"psc", &PSC::LoopProcess},
|
||||||
{"glue", &Glue::LoopProcess},
|
|
||||||
{"grc", &GRC::LoopProcess},
|
{"grc", &GRC::LoopProcess},
|
||||||
{"hid", &HID::LoopProcess},
|
{"hid", &HID::LoopProcess},
|
||||||
{"jit", &JIT::LoopProcess},
|
{"jit", &JIT::LoopProcess},
|
||||||
|
|||||||
@@ -11,6 +11,7 @@
|
|||||||
#include "common/thread.h"
|
#include "common/thread.h"
|
||||||
#include "core/core.h"
|
#include "core/core.h"
|
||||||
#include "core/core_timing.h"
|
#include "core/core_timing.h"
|
||||||
|
#include "core/hle/kernel/kernel.h"
|
||||||
#include "core/hle/service/vi/conductor.h"
|
#include "core/hle/service/vi/conductor.h"
|
||||||
#include "core/hle/service/vi/container.h"
|
#include "core/hle/service/vi/container.h"
|
||||||
#include "core/hle/service/vi/display_list.h"
|
#include "core/hle/service/vi/display_list.h"
|
||||||
@@ -38,7 +39,18 @@ Conductor::Conductor(Core::System& system, Container& container, DisplayList& di
|
|||||||
});
|
});
|
||||||
|
|
||||||
system.CoreTiming().ScheduleLoopingEvent(FrameNs, FrameNs, m_event);
|
system.CoreTiming().ScheduleLoopingEvent(FrameNs, FrameNs, m_event);
|
||||||
m_thread = std::jthread([this](std::stop_token token) { this->VsyncThread(token); });
|
m_thread = system.Kernel().RunOnHostCoreThread("VSyncThread", [this]() {
|
||||||
|
auto const stop_token = m_thread.get_stop_token();
|
||||||
|
Common::SetCurrentThreadPriority(Common::ThreadPriority::VeryHigh);
|
||||||
|
Common::SetCurrentThreadToPerformanceCores();
|
||||||
|
while (!stop_token.stop_requested()) {
|
||||||
|
m_signal.Wait();
|
||||||
|
if (stop_token.stop_requested() || m_system.IsShuttingDown()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
this->ProcessVsync();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
m_event = Core::Timing::CreateEvent(
|
m_event = Core::Timing::CreateEvent(
|
||||||
"ScreenComposition",
|
"ScreenComposition",
|
||||||
@@ -54,10 +66,10 @@ Conductor::Conductor(Core::System& system, Container& container, DisplayList& di
|
|||||||
|
|
||||||
Conductor::~Conductor() {
|
Conductor::~Conductor() {
|
||||||
m_system.CoreTiming().UnscheduleEvent(m_event);
|
m_system.CoreTiming().UnscheduleEvent(m_event);
|
||||||
|
if (m_thread.joinable()) {
|
||||||
if (m_system.IsMulticore()) {
|
|
||||||
m_thread.request_stop();
|
m_thread.request_stop();
|
||||||
m_signal.Set();
|
m_signal.Set();
|
||||||
|
m_thread.join();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -83,22 +95,6 @@ void Conductor::ProcessVsync() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void Conductor::VsyncThread(std::stop_token token) {
|
|
||||||
Common::SetCurrentThreadName("VSyncThread");
|
|
||||||
Common::SetCurrentThreadPriority(Common::ThreadPriority::VeryHigh);
|
|
||||||
Common::SetCurrentThreadToPerformanceCores();
|
|
||||||
|
|
||||||
while (!token.stop_requested()) {
|
|
||||||
m_signal.Wait();
|
|
||||||
|
|
||||||
if (m_system.IsShuttingDown()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this->ProcessVsync();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
s64 Conductor::GetNextTicks() const {
|
s64 Conductor::GetNextTicks() const {
|
||||||
const auto& settings = Settings::values;
|
const auto& settings = Settings::values;
|
||||||
auto speed_scale = 1.f;
|
auto speed_scale = 1.f;
|
||||||
|
|||||||
Reference in New Issue
Block a user