summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGravatar bunnei2014-05-14 20:50:30 -0400
committerGravatar bunnei2014-05-14 20:50:30 -0400
commitb99a5da65b76ce16e40fe05feb786aac11931904 (patch)
treec4e59e9fe73417ac931b99b468004219286b2560 /src
parentchanged primary thread priority to 0x30 - this is typical, not 0x31 (diff)
downloadyuzu-b99a5da65b76ce16e40fe05feb786aac11931904.tar.gz
yuzu-b99a5da65b76ce16e40fe05feb786aac11931904.tar.xz
yuzu-b99a5da65b76ce16e40fe05feb786aac11931904.zip
- added helper function for __KernelCreateThread
- added __KernelSwitchToThread for enabling a thread - added __KernelRotateThreadReadyQueue
Diffstat (limited to 'src')
-rw-r--r--src/core/hle/kernel/thread.cpp74
-rw-r--r--src/core/hle/kernel/thread.h6
2 files changed, 76 insertions, 4 deletions
diff --git a/src/core/hle/kernel/thread.cpp b/src/core/hle/kernel/thread.cpp
index c59d2a689..b6d02aa12 100644
--- a/src/core/hle/kernel/thread.cpp
+++ b/src/core/hle/kernel/thread.cpp
@@ -13,6 +13,8 @@
13 13
14#include "core/core.h" 14#include "core/core.h"
15#include "core/mem_map.h" 15#include "core/mem_map.h"
16#include "core/hle/hle.h"
17#include "core/hle/syscall.h"
16#include "core/hle/kernel/kernel.h" 18#include "core/hle/kernel/kernel.h"
17#include "core/hle/kernel/thread.h" 19#include "core/hle/kernel/thread.h"
18 20
@@ -357,7 +359,7 @@ public:
357 //void Cleanup() { 359 //void Cleanup() {
358 // // Callbacks are automatically deleted when their owning thread is deleted. 360 // // Callbacks are automatically deleted when their owning thread is deleted.
359 // for (auto it = callbacks.begin(), end = callbacks.end(); it != end; ++it) 361 // for (auto it = callbacks.begin(), end = callbacks.end(); it != end; ++it)
360 // kernelObjects.Destroy<Callback>(*it); 362 // g_kernel_objects.Destroy<Callback>(*it);
361 363
362 // if (pushed_stacks.size() != 0) 364 // if (pushed_stacks.size() != 0)
363 // { 365 // {
@@ -432,7 +434,7 @@ const char* g_hle_current_thread_name = NULL;
432 434
433/// Creates a new thread 435/// Creates a new thread
434Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, 436Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority,
435 u32 entrypoint, u32 arg, u32 stack_top, u32 processor_id, int stack_size) { 437 u32 entry_point, u32 arg, u32 stack_top, u32 processor_id, int stack_size) {
436 438
437 Thread *t = new Thread; 439 Thread *t = new Thread;
438 id = g_kernel_objects.Create(t); 440 id = g_kernel_objects.Create(t);
@@ -442,7 +444,7 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
442 444
443 memset(&t->nt, 0xCD, sizeof(t->nt)); 445 memset(&t->nt, 0xCD, sizeof(t->nt));
444 446
445 t->nt.entry_point = entrypoint; 447 t->nt.entry_point = entry_point;
446 t->nt.native_size = sizeof(t->nt); 448 t->nt.native_size = sizeof(t->nt);
447 t->nt.initial_priority = t->nt.current_priority = priority; 449 t->nt.initial_priority = t->nt.current_priority = priority;
448 t->nt.status = THREADSTATUS_DORMANT; 450 t->nt.status = THREADSTATUS_DORMANT;
@@ -459,6 +461,18 @@ Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 prior
459 return t; 461 return t;
460} 462}
461 463
464UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg,
465 u32 stack_top, u32 processor_id, int stack_size) {
466 UID id;
467 __KernelCreateThread(id, module_id, name, priority, entry_point, arg, stack_top, processor_id,
468 stack_size);
469
470 HLE::EatCycles(32000);
471 HLE::ReSchedule("thread created");
472
473 return id;
474}
475
462/// Resets the specified thread back to initial calling state 476/// Resets the specified thread back to initial calling state
463void __KernelResetThread(Thread *t, int lowest_priority) { 477void __KernelResetThread(Thread *t, int lowest_priority) {
464 t->context.reset(); 478 t->context.reset();
@@ -608,6 +622,31 @@ void __KernelSwitchContext(Thread *target, const char *reason) {
608 } 622 }
609} 623}
610 624
625bool __KernelSwitchToThread(UID thread_id, const char *reason) {
626 if (!reason) {
627 reason = "switch to thread";
628 }
629 if (g_current_thread == thread_id) {
630 return false;
631 }
632 u32 error;
633 Thread *t = g_kernel_objects.Get<Thread>(thread_id, error);
634 if (!t) {
635 ERROR_LOG(KERNEL, "__KernelSwitchToThread: %x doesn't exist", thread_id);
636 HLE::ReSchedule("switch to deleted thread");
637 } else if (t->IsReady() || t->IsRunning()) {
638 Thread *current = __GetCurrentThread();
639 if (current && current->IsRunning()) {
640 __KernelChangeReadyState(current, g_current_thread, true);
641 }
642 __KernelSwitchContext(t, reason);
643 return true;
644 } else {
645 HLE::ReSchedule("switch to waiting thread");
646 }
647 return false;
648}
649
611/// Sets up the root (primary) thread of execution 650/// Sets up the root (primary) thread of execution
612UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) { 651UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
613 UID id; 652 UID id;
@@ -633,7 +672,7 @@ UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
633 // NOTE(bunnei): Not sure this is really correct, ignore args for now... 672 // NOTE(bunnei): Not sure this is really correct, ignore args for now...
634 //Core::g_app_core->SetReg(0, args); 673 //Core::g_app_core->SetReg(0, args);
635 //Core::g_app_core->SetReg(13, (args + 0xf) & ~0xf); // Setup SP - probably not correct 674 //Core::g_app_core->SetReg(13, (args + 0xf) & ~0xf); // Setup SP - probably not correct
636 //u32 location = Core::g_app_core->GetReg(13); // SP 675 //u32 location = Core::g_app_core->GetReg(13); // SP
637 //Core::g_app_core->SetReg(1, location); 676 //Core::g_app_core->SetReg(1, location);
638 677
639 //if (argp) 678 //if (argp)
@@ -644,6 +683,33 @@ UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) {
644 return id; 683 return id;
645} 684}
646 685
686int __KernelRotateThreadReadyQueue(int priority) {
687 Thread *cur = __GetCurrentThread();
688
689 // 0 is special, it means "my current priority."
690 if (priority == 0) {
691 priority = cur->nt.current_priority;
692 }
693 //if (priority <= 0x07 || priority > 0x77)
694 // return SCE_KERNEL_ERROR_ILLEGAL_PRIORITY;
695
696 if (!g_thread_ready_queue.empty(priority)) {
697 // In other words, yield to everyone else.
698 if (cur->nt.current_priority == priority) {
699 g_thread_ready_queue.push_back(priority, g_current_thread);
700 cur->nt.status = (cur->nt.status & ~THREADSTATUS_RUNNING) | THREADSTATUS_READY;
701
702 // Yield the next thread of this priority to all other threads of same priority.
703 } else {
704 g_thread_ready_queue.rotate(priority);
705 }
706 }
707 HLE::EatCycles(250);
708 HLE::ReSchedule("rotatethreadreadyqueue");
709
710 return 0;
711}
712
647void __KernelThreadingInit() { 713void __KernelThreadingInit() {
648} 714}
649 715
diff --git a/src/core/hle/kernel/thread.h b/src/core/hle/kernel/thread.h
index 1731248cc..05468fb2e 100644
--- a/src/core/hle/kernel/thread.h
+++ b/src/core/hle/kernel/thread.h
@@ -30,6 +30,10 @@ class Thread;
30 30
31Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint, 31Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint,
32 u32 arg, u32 stack_top, u32 processor_id, int stack_size=0x4000); 32 u32 arg, u32 stack_top, u32 processor_id, int stack_size=0x4000);
33
34UID __KernelCreateThread(UID module_id, const char* name, u32 priority, u32 entry_point, u32 arg,
35 u32 stack_top, u32 processor_id, int stack_size=0x4000);
36
33void __KernelResetThread(Thread *t, int lowest_priority); 37void __KernelResetThread(Thread *t, int lowest_priority);
34void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready); 38void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready);
35void __KernelChangeReadyState(UID thread_id, bool ready); 39void __KernelChangeReadyState(UID thread_id, bool ready);
@@ -37,7 +41,9 @@ Thread* __KernelNextThread();
37void __KernelSaveContext(ThreadContext *ctx); 41void __KernelSaveContext(ThreadContext *ctx);
38void __KernelLoadContext(ThreadContext *ctx); 42void __KernelLoadContext(ThreadContext *ctx);
39void __KernelSwitchContext(Thread *target, const char *reason); 43void __KernelSwitchContext(Thread *target, const char *reason);
44bool __KernelSwitchToThread(UID thread_id, const char *reason);
40UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000); 45UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000);
46int __KernelRotateThreadReadyQueue(int priority=0);
41 47
42void __KernelThreadingInit(); 48void __KernelThreadingInit();
43void __KernelThreadingShutdown(); 49void __KernelThreadingShutdown();