summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorbunnei <ericbunnie@gmail.com>2014-05-21 01:37:46 +0200
committerbunnei <ericbunnie@gmail.com>2014-05-21 01:37:46 +0200
commit75c6d2a8fa3547946227094af6c179e5ccba0e1e (patch)
tree6199164fdc1745d6b12333b0b2efc269e8c7ee5d /src/core
parentARM_Interpreter/ARM_Interface: Fixed member variable naming to be consistent with style guide (diff)
downloadyuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar.gz
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar.bz2
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar.lz
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar.xz
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.tar.zst
yuzu-75c6d2a8fa3547946227094af6c179e5ccba0e1e.zip
Diffstat (limited to 'src/core')
-rw-r--r--src/core/hle/kernel/kernel.cpp6
-rw-r--r--src/core/hle/kernel/thread.cpp184
-rw-r--r--src/core/hle/kernel/thread.h26
-rw-r--r--src/core/hle/svc.cpp4
4 files changed, 117 insertions, 103 deletions
diff --git a/src/core/hle/kernel/kernel.cpp b/src/core/hle/kernel/kernel.cpp
index b1fdffde5..45e36173c 100644
--- a/src/core/hle/kernel/kernel.cpp
+++ b/src/core/hle/kernel/kernel.cpp
@@ -132,11 +132,11 @@ Object* ObjectPool::CreateByIDType(int type) {
}
void Init() {
- __KernelThreadingInit();
+ Kernel::ThreadingInit();
}
void Shutdown() {
- __KernelThreadingShutdown();
+ Kernel::ThreadingShutdown();
}
} // namespace
@@ -147,7 +147,7 @@ bool __KernelLoadExec(u32 entry_point) {
Core::g_app_core->SetPC(entry_point);
// 0x30 is the typical main thread priority I've seen used so far
- Handle thread_id = __KernelSetupMainThread(0x30);
+ Handle thread_id = Kernel::SetupMainThread(0x30);
return true;
}
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index b3d306c53..7b4f0ea47 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -19,7 +19,7 @@
#include "core/hle/kernel/kernel.h"
#include "core/hle/kernel/thread.h"
-// Enums
+namespace Kernel {
enum ThreadStatus {
THREADSTATUS_RUNNING = 1,
@@ -81,33 +81,32 @@ std::vector<Handle> g_thread_queue;
Common::ThreadQueueList<Handle> g_thread_ready_queue;
Handle g_current_thread_handle;
-
Thread* g_current_thread;
+/// Gets the current thread
inline Thread* __GetCurrentThread() {
return g_current_thread;
}
+/// Sets the current thread
inline void __SetCurrentThread(Thread* t) {
g_current_thread = t;
g_current_thread_handle = t->GetHandle();
}
-////////////////////////////////////////////////////////////////////////////////////////////////////
-
/// Saves the current CPU context
-void __KernelSaveContext(ThreadContext& ctx) {
+void __SaveContext(ThreadContext& ctx) {
Core::g_app_core->SaveContext(ctx);
}
/// Loads a CPU context
-void __KernelLoadContext(const ThreadContext& ctx) {
+void __LoadContext(const ThreadContext& ctx) {
Core::g_app_core->LoadContext(ctx);
}
/// Resets a thread
-void __KernelResetThread(Thread* t, s32 lowest_priority) {
+void __ResetThread(Thread* t, s32 lowest_priority) {
memset(&t->context, 0, sizeof(ThreadContext));
t->context.pc = t->entry_point;
@@ -121,7 +120,7 @@ void __KernelResetThread(Thread* t, s32 lowest_priority) {
}
/// Change a thread to "ready" state
-void __KernelChangeReadyState(Thread* t, bool ready) {
+void __ChangeReadyState(Thread* t, bool ready) {
Handle handle = t->GetHandle();
if (t->IsReady()) {
if (!ready) {
@@ -138,11 +137,11 @@ void __KernelChangeReadyState(Thread* t, bool ready) {
}
/// Changes a threads state
-void __KernelChangeThreadState(Thread* t, ThreadStatus new_status) {
+void __ChangeThreadState(Thread* t, ThreadStatus new_status) {
if (!t || t->status == new_status) {
return;
}
- __KernelChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0);
+ __ChangeReadyState(t, (new_status & THREADSTATUS_READY) != 0);
t->status = new_status;
if (new_status == THREADSTATUS_WAIT) {
@@ -153,16 +152,75 @@ void __KernelChangeThreadState(Thread* t, ThreadStatus new_status) {
}
/// Calls a thread by marking it as "ready" (note: will not actually execute until current thread yields)
-void __KernelCallThread(Thread* t) {
+void __CallThread(Thread* t) {
// Stop waiting
if (t->wait_type != WAITTYPE_NONE) {
t->wait_type = WAITTYPE_NONE;
}
- __KernelChangeThreadState(t, THREADSTATUS_READY);
+ __ChangeThreadState(t, THREADSTATUS_READY);
+}
+
+/// Switches CPU context to that of the specified thread
+void __SwitchContext(Thread* t, const char* reason) {
+ Thread* cur = __GetCurrentThread();
+
+ // Save context for current thread
+ if (cur) {
+ __SaveContext(cur->context);
+
+ if (cur->IsRunning()) {
+ __ChangeReadyState(cur, true);
+ }
+ }
+ // Load context of new thread
+ if (t) {
+ __SetCurrentThread(t);
+ __ChangeReadyState(t, false);
+ t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
+ t->wait_type = WAITTYPE_NONE;
+ __LoadContext(t->context);
+ } else {
+ __SetCurrentThread(NULL);
+ }
+}
+
+/// Gets the next thread that is ready to be run by priority
+Thread* __NextThread() {
+ Handle next;
+ Thread* cur = __GetCurrentThread();
+
+ if (cur && cur->IsRunning()) {
+ next = g_thread_ready_queue.pop_first_better(cur->current_priority);
+ } else {
+ next = g_thread_ready_queue.pop_first();
+ }
+ if (next < 0) {
+ return NULL;
+ }
+ return Kernel::g_object_pool.GetFast<Thread>(next);
+}
+
+/// Resumes a thread from waiting by marking it as "ready"
+void __ResumeThreadFromWait(Handle handle) {
+ u32 error;
+ Thread* t = Kernel::g_object_pool.Get<Thread>(handle, error);
+ if (t) {
+ t->status &= ~THREADSTATUS_WAIT;
+ if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
+ __ChangeReadyState(t, true);
+ }
+ }
+}
+
+/// Puts a thread in the wait state for the given type/reason
+void __WaitCurThread(WaitType wait_type, const char* reason) {
+ Thread* t = __GetCurrentThread();
+ t->wait_type = wait_type;
+ __ChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND)));
}
/// Creates a new thread
-Thread* __KernelCreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority,
+Thread* CreateThread(Handle& handle, const char* name, u32 entry_point, s32 priority,
s32 processor_id, u32 stack_top, int stack_size) {
Thread* t = new Thread;
@@ -187,31 +245,31 @@ Thread* __KernelCreateThread(Handle& handle, const char* name, u32 entry_point,
}
/// Creates a new thread - wrapper for external user
-Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id,
+Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id,
u32 stack_top, int stack_size) {
if (name == NULL) {
- ERROR_LOG(KERNEL, "__KernelCreateThread(): NULL name");
+ ERROR_LOG(KERNEL, "CreateThread(): NULL name");
return -1;
}
if ((u32)stack_size < 0x200) {
- ERROR_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid stack_size=0x%08X", name,
+ ERROR_LOG(KERNEL, "CreateThread(name=%s): invalid stack_size=0x%08X", name,
stack_size);
return -1;
}
if (priority < THREADPRIO_HIGHEST || priority > THREADPRIO_LOWEST) {
s32 new_priority = CLAMP(priority, THREADPRIO_HIGHEST, THREADPRIO_LOWEST);
- WARN_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid priority=0x%08X, clamping to %08X",
+ WARN_LOG(KERNEL, "CreateThread(name=%s): invalid priority=0x%08X, clamping to %08X",
name, priority, new_priority);
// TODO(bunnei): Clamping to a valid priority is not necessarily correct behavior... Confirm
// validity of this
priority = new_priority;
}
if (!Memory::GetPointer(entry_point)) {
- ERROR_LOG(KERNEL, "__KernelCreateThread(name=%s): invalid entry %08x", name, entry_point);
+ ERROR_LOG(KERNEL, "CreateThread(name=%s): invalid entry %08x", name, entry_point);
return -1;
}
Handle handle;
- Thread* t = __KernelCreateThread(handle, name, entry_point, priority, processor_id, stack_top,
+ Thread* t = CreateThread(handle, name, entry_point, priority, processor_id, stack_top,
stack_size);
HLE::EatCycles(32000);
@@ -220,114 +278,62 @@ Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority, s32
// Technically, this should not eat all at once, and reschedule in the middle, but that's hard.
HLE::ReSchedule("thread created");
- __KernelCallThread(t);
+ __CallThread(t);
return handle;
}
-/// Switches CPU context to that of the specified thread
-void __KernelSwitchContext(Thread* t, const char* reason) {
- Thread* cur = __GetCurrentThread();
-
- // Save context for current thread
- if (cur) {
- __KernelSaveContext(cur->context);
-
- if (cur->IsRunning()) {
- __KernelChangeReadyState(cur, true);
- }
- }
- // Load context of new thread
- if (t) {
- __SetCurrentThread(t);
- __KernelChangeReadyState(t, false);
- t->status = (t->status | THREADSTATUS_RUNNING) & ~THREADSTATUS_READY;
- t->wait_type = WAITTYPE_NONE;
- __KernelLoadContext(t->context);
- } else {
- __SetCurrentThread(NULL);
- }
-}
-
-/// Gets the next thread that is ready to be run by priority
-Thread* __KernelNextThread() {
- Handle next;
- Thread* cur = __GetCurrentThread();
-
- if (cur && cur->IsRunning()) {
- next = g_thread_ready_queue.pop_first_better(cur->current_priority);
- } else {
- next = g_thread_ready_queue.pop_first();
- }
- if (next < 0) {
- return NULL;
- }
- return Kernel::g_object_pool.GetFast<Thread>(next);
+/// Gets the current thread
+Handle GetCurrentThread() {
+ return __GetCurrentThread()->GetHandle();
}
/// Sets up the primary application thread
-Handle __KernelSetupMainThread(s32 priority, int stack_size) {
+Handle SetupMainThread(s32 priority, int stack_size) {
Handle handle;
// Initialize new "main" thread
- Thread* t = __KernelCreateThread(handle, "main", Core::g_app_core->GetPC(), priority,
+ Thread* t = CreateThread(handle, "main", Core::g_app_core->GetPC(), priority,
THREADPROCESSORID_0, Memory::SCRATCHPAD_VADDR_END, stack_size);
- __KernelResetThread(t, 0);
+ __ResetThread(t, 0);
// If running another thread already, set it to "ready" state
Thread* cur = __GetCurrentThread();
if (cur && cur->IsRunning()) {
- __KernelChangeReadyState(cur, true);
+ __ChangeReadyState(cur, true);
}
// Run new "main" thread
__SetCurrentThread(t);
t->status = THREADSTATUS_RUNNING;
- __KernelLoadContext(t->context);
+ __LoadContext(t->context);
return handle;
}
-/// Resumes a thread from waiting by marking it as "ready"
-void __KernelResumeThreadFromWait(Handle handle) {
- u32 error;
- Thread* t = Kernel::g_object_pool.Get<Thread>(handle, error);
- if (t) {
- t->status &= ~THREADSTATUS_WAIT;
- if (!(t->status & (THREADSTATUS_WAITSUSPEND | THREADSTATUS_DORMANT | THREADSTATUS_DEAD))) {
- __KernelChangeReadyState(t, true);
- }
- }
-}
-
-/// Puts a thread in the wait state for the given type/reason
-void __KernelWaitCurThread(WaitType wait_type, const char* reason) {
- Thread* t = __GetCurrentThread();
- t->wait_type = wait_type;
- __KernelChangeThreadState(t, ThreadStatus(THREADSTATUS_WAIT | (t->status & THREADSTATUS_SUSPEND)));
-}
-
/// Reschedules to the next available thread (call after current thread is suspended)
-void __KernelReschedule(const char* reason) {
- Thread* next = __KernelNextThread();
+void Reschedule(const char* reason) {
+ Thread* next = __NextThread();
if (next > 0) {
- __KernelSwitchContext(next, reason);
+ __SwitchContext(next, reason);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////
/// Put current thread in a wait state - on WaitSynchronization
-void __KernelWaitThread_Synchronization() {
+void WaitThread_Synchronization() {
// TODO(bunnei): Just a placeholder function for now... FixMe
- __KernelWaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called");
+ __WaitCurThread(WAITTYPE_SYNCH, "waitSynchronization called");
}
////////////////////////////////////////////////////////////////////////////////////////////////////
-void __KernelThreadingInit() {
+void ThreadingInit() {
}
-void __KernelThreadingShutdown() {
+void ThreadingShutdown() {
}
+
+} // namespace
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 72e9a416d..2c0199273 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -7,8 +7,6 @@
#include "common/common_types.h"
#include "core/hle/kernel/kernel.h"
-class Thread;
-
enum ThreadPriority {
THREADPRIO_HIGHEST = 0,
THREADPRIO_DEFAULT = 16,
@@ -21,18 +19,28 @@ enum ThreadProcessorId {
THREADPROCESSORID_ALL = 0xFFFFFFFC,
};
+namespace Kernel {
+
/// Creates a new thread - wrapper for external user
-Handle __KernelCreateThread(const char* name, u32 entry_point, s32 priority,
- s32 processor_id, u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE);
+Handle CreateThread(const char* name, u32 entry_point, s32 priority, s32 processor_id,
+ u32 stack_top, int stack_size=Kernel::DEFAULT_STACK_SIZE);
/// Sets up the primary application thread
-Handle __KernelSetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE);
+Handle SetupMainThread(s32 priority, int stack_size=Kernel::DEFAULT_STACK_SIZE);
/// Reschedules to the next available thread (call after current thread is suspended)
-void __KernelReschedule(const char* reason);
+void Reschedule(const char* reason);
-void __KernelThreadingInit();
-void __KernelThreadingShutdown();
+/// Gets the current thread
+Handle GetCurrentThread();
/// Put current thread in a wait state - on WaitSynchronization
-void __KernelWaitThread_Synchronization();
+void WaitThread_Synchronization();
+
+/// Initialize threading
+void ThreadingInit();
+
+/// Shutdown threading
+void ThreadingShutdown();
+
+} // namespace
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp
index a9141699c..6f0f099c6 100644
--- a/src/core/hle/svc.cpp
+++ b/src/core/hle/svc.cpp
@@ -123,7 +123,7 @@ Result WaitSynchronizationN(void* _out, void* _handles, u32 handle_count, u32 wa
for (u32 i = 0; i < handle_count; i++) {
DEBUG_LOG(SVC, "\thandle[%d]=0x%08X", i, handles[i]);
}
- __KernelReschedule("WaitSynchronizationN");
+ Kernel::Reschedule("WaitSynchronizationN");
return 0;
}
@@ -175,7 +175,7 @@ Result CreateThread(void* thread, u32 priority, u32 entry_point, u32 arg, u32 st
"threadpriority=0x%08X, processorid=0x%08X", entry_point, name.c_str(), arg, stack_top,
priority, processor_id);
- Handle handle = __KernelCreateThread(name.c_str(), entry_point, priority, processor_id,
+ Handle handle = Kernel::CreateThread(name.c_str(), entry_point, priority, processor_id,
stack_top);
Core::g_app_core->SetReg(1, 0xFEEDDEAF);