diff options
| author | 2014-05-14 20:50:30 -0400 | |
|---|---|---|
| committer | 2014-05-14 20:50:30 -0400 | |
| commit | b99a5da65b76ce16e40fe05feb786aac11931904 (patch) | |
| tree | c4e59e9fe73417ac931b99b468004219286b2560 | |
| parent | changed primary thread priority to 0x30 - this is typical, not 0x31 (diff) | |
| download | yuzu-b99a5da65b76ce16e40fe05feb786aac11931904.tar.gz yuzu-b99a5da65b76ce16e40fe05feb786aac11931904.tar.xz yuzu-b99a5da65b76ce16e40fe05feb786aac11931904.zip | |
- added helper function for __KernelCreateThread
- added __KernelSwitchToThread for enabling a thread
- added __KernelRotateThreadReadyQueue
| -rw-r--r-- | src/core/hle/kernel/thread.cpp | 74 | ||||
| -rw-r--r-- | src/core/hle/kernel/thread.h | 6 |
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 |
| 434 | Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, | 436 | Thread* __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 | ||
| 464 | UID __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 |
| 463 | void __KernelResetThread(Thread *t, int lowest_priority) { | 477 | void __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 | ||
| 625 | bool __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 |
| 612 | UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size) { | 651 | UID __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 | ||
| 686 | int __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 | |||
| 647 | void __KernelThreadingInit() { | 713 | void __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 | ||
| 31 | Thread* __KernelCreateThread(UID& id, UID module_id, const char* name, u32 priority, u32 entrypoint, | 31 | Thread* __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 | |||
| 34 | UID __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 | |||
| 33 | void __KernelResetThread(Thread *t, int lowest_priority); | 37 | void __KernelResetThread(Thread *t, int lowest_priority); |
| 34 | void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready); | 38 | void __KernelChangeReadyState(Thread *thread, UID thread_id, bool ready); |
| 35 | void __KernelChangeReadyState(UID thread_id, bool ready); | 39 | void __KernelChangeReadyState(UID thread_id, bool ready); |
| @@ -37,7 +41,9 @@ Thread* __KernelNextThread(); | |||
| 37 | void __KernelSaveContext(ThreadContext *ctx); | 41 | void __KernelSaveContext(ThreadContext *ctx); |
| 38 | void __KernelLoadContext(ThreadContext *ctx); | 42 | void __KernelLoadContext(ThreadContext *ctx); |
| 39 | void __KernelSwitchContext(Thread *target, const char *reason); | 43 | void __KernelSwitchContext(Thread *target, const char *reason); |
| 44 | bool __KernelSwitchToThread(UID thread_id, const char *reason); | ||
| 40 | UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000); | 45 | UID __KernelSetupRootThread(UID module_id, int arg, int prio, int stack_size=0x4000); |
| 46 | int __KernelRotateThreadReadyQueue(int priority=0); | ||
| 41 | 47 | ||
| 42 | void __KernelThreadingInit(); | 48 | void __KernelThreadingInit(); |
| 43 | void __KernelThreadingShutdown(); | 49 | void __KernelThreadingShutdown(); |