Skip to content

Commit

Permalink
nagisc007's pseudo system core
Browse files Browse the repository at this point in the history
  • Loading branch information
sickc committed Sep 14, 2018
1 parent 6d4d02a commit 0f6df68
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 4 deletions.
5 changes: 4 additions & 1 deletion src/citra_qt/debugger/wait_tree.cpp
Expand Up @@ -223,7 +223,10 @@ std::vector<std::unique_ptr<WaitTreeItem>> WaitTreeThread::GetChildren() const {
processor = tr("AppCore");
break;
case ThreadProcessorId::THREADPROCESSORID_1:
processor = tr("SysCore");
processor = tr("SysCore(Core1)");
break;
case ThreadProcessorId::THREADPROCESSORID_2:
processor = tr("SysCore(Core2)");
break;
default:
processor = tr("Unknown processor %1").arg(thread.processor_id);
Expand Down
4 changes: 4 additions & 0 deletions src/core/hle/kernel/svc.cpp
Expand Up @@ -751,6 +751,10 @@ static ResultCode CreateThread(Handle* out_handle, u32 priority, u32 entry_point
LOG_ERROR(Kernel_SVC,
"Newly created thread must run in the SysCore (Core1), unimplemented.");
break;
case THREADPROCESSORID_2:
LOG_ERROR(Kernel_SVC,
"Newly created thread must run in the SysCore (Core2), unimplemented.");
break;
default:
// TODO(bunnei): Implement support for other processor IDs
ASSERT_MSG(false, "Unsupported thread processor ID: {}", processor_id);
Expand Down
45 changes: 43 additions & 2 deletions src/core/hle/kernel/thread.cpp
Expand Up @@ -30,6 +30,11 @@ namespace Kernel {
/// Event type for the thread wake up event
static CoreTiming::EventType* ThreadWakeupEventType = nullptr;

static int system_core_percent = 100;
static int system_thread_count = 0;
static int run_system_threads = 0;
static int system_core_base = THREADPROCESSORID_1;

bool Thread::ShouldWait(Thread* thread) const {
return status != THREADSTATUS_DEAD;
}
Expand Down Expand Up @@ -122,11 +127,29 @@ static void PriorityBoostStarvedThreads() {
}
}
}

static void RescheduleForSystemCore() {
run_system_threads = system_thread_count * system_core_percent / 100;
int system_threads = run_system_threads;
if (system_threads == 0) return;

for (auto& thread : thread_list) {
if (thread->status == THREADSTATUS_READY && thread->processor_id >= system_core_base) {
if (system_threads <= 0) {
const s32 priority = std::min(thread->current_priority + 10,
static_cast<unsigned int>(THREADPRIO_LOWEST));
thread->BoostPriority(priority);
}
--system_threads;
}
}
}

/**
* Switches the CPU's active thread context to that of the specified thread
* @param new_thread The thread to switch to
*/
static void SwitchContext(Thread* new_thread) {
static int SwitchContext(Thread* new_thread) {
Thread* previous_thread = GetCurrentThread();

// Save context for previous thread
Expand Down Expand Up @@ -166,10 +189,12 @@ static void SwitchContext(Thread* new_thread) {

Core::CPU().LoadContext(new_thread->context);
Core::CPU().SetCP15Register(CP15_THREAD_URO, new_thread->GetTLSAddress());
return new_thread->processor_id;
} else {
current_thread = nullptr;
// Note: We do not reset the current process and current page table when idling because
// technically we haven't changed processes, our threads are just paused.
return -1;
}
}

Expand All @@ -196,6 +221,10 @@ static Thread* PopNextReadyThread() {
return next;
}

void Thread::UpdateSystemCorePercent(int per) {
system_core_percent = per;
}

void WaitCurrentThread_Sleep() {
Thread* thread = GetCurrentThread();
thread->status = THREADSTATUS_WAIT_SLEEP;
Expand All @@ -204,6 +233,7 @@ void WaitCurrentThread_Sleep() {
void ExitCurrentThread() {
Thread* thread = GetCurrentThread();
thread->Stop();
if (thread->processor_id >= system_core_base) --system_thread_count;
thread_list.erase(std::remove(thread_list.begin(), thread_list.end(), thread),
thread_list.end());
}
Expand Down Expand Up @@ -372,6 +402,7 @@ ResultVal<SharedPtr<Thread>> Thread::Create(std::string name, VAddr entry_point,

thread_list.push_back(thread);
ready_queue.prepare(priority);
if (processor_id >= system_core_base) ++system_thread_count;

thread->thread_id = NewThreadId();
thread->status = THREADSTATUS_DORMANT;
Expand Down Expand Up @@ -488,6 +519,8 @@ bool HaveReadyThreads() {
}

void Reschedule() {
RescheduleForSystemCore();

if (Settings::values.use_priority_boost) {
PriorityBoostStarvedThreads();
}
Expand All @@ -503,7 +536,13 @@ void Reschedule() {
LOG_TRACE(Kernel, "context switch idle -> {}", next->GetObjectId());
}

SwitchContext(next);
int th_processor_id = SwitchContext(next);
if (th_processor_id >= system_core_base) {
// in system core
CoreTiming::Advance();
Core::CPU().Run();
SwitchContext(PopNextReadyThread());
}
}

void Thread::SetWaitSynchronizationResult(ResultCode result) {
Expand Down Expand Up @@ -541,6 +580,8 @@ void ThreadingShutdown() {
for (auto& t : thread_list) {
t->Stop();
}
system_core_percent = 100;
system_thread_count = 0;
thread_list.clear();
ready_queue.clear();
ClearProcessList();
Expand Down
5 changes: 4 additions & 1 deletion src/core/hle/kernel/thread.h
Expand Up @@ -26,7 +26,8 @@ enum ThreadProcessorId : s32 {
THREADPROCESSORID_DEFAULT = -2, ///< Run thread on default core specified by exheader
THREADPROCESSORID_ALL = -1, ///< Run thread on either core
THREADPROCESSORID_0 = 0, ///< Run thread on core 0 (AppCore)
THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore)
THREADPROCESSORID_1 = 1, ///< Run thread on core 1 (SysCore1)
THREADPROCESSORID_2 = 2, ///< Run thread on core 2 (SysCore2)
THREADPROCESSORID_MAX = 2, ///< Processor ID must be less than this
};

Expand Down Expand Up @@ -82,6 +83,8 @@ class Thread final : public WaitObject {
return HANDLE_TYPE;
}

static void UpdateSystemCorePercent(int per);

bool ShouldWait(Thread* thread) const override;
void Acquire(Thread* thread) override;

Expand Down
3 changes: 3 additions & 0 deletions src/core/hle/service/apt/apt.cpp
Expand Up @@ -10,6 +10,7 @@
#include "core/hle/applets/applet.h"
#include "core/hle/kernel/mutex.h"
#include "core/hle/kernel/shared_memory.h"
#include "core/hle/kernel/thread.h"
#include "core/hle/romfs.h"
#include "core/hle/service/apt/applet_manager.h"
#include "core/hle/service/apt/apt.h"
Expand Down Expand Up @@ -467,6 +468,8 @@ void Module::Interface::SetAppCpuTimeLimit(Kernel::HLERequestContext& ctx) {
IPC::RequestBuilder rb = rp.MakeBuilder(1, 0);
rb.Push(RESULT_SUCCESS); // No error

Kernel::Thread::UpdateSystemCorePercent(apt->cpu_percent);

LOG_WARNING(Service_APT, "(STUBBED) called, cpu_percent={}, value={}", apt->cpu_percent, value);
}

Expand Down

0 comments on commit 0f6df68

Please sign in to comment.