Fixed some libultra thread implementation issues, fixed flash implementation not getting detected by the game
This commit is contained in:
parent
ba37150ed1
commit
d994bd381d
|
@ -167,7 +167,12 @@ XCOPY "$(ProjectDir)lib\SDL2-2.24.0\lib\$(Platform)\SDL2.dll" "$(TargetDir)" /S
|
|||
</PostBuildEvent>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="portultra\audio.cpp" />
|
||||
<ClCompile Include="portultra\audio.cpp">
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">MaxSpeed</Optimization>
|
||||
<Optimization Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">MaxSpeed</Optimization>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Default</BasicRuntimeChecks>
|
||||
<BasicRuntimeChecks Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">Default</BasicRuntimeChecks>
|
||||
</ClCompile>
|
||||
<ClCompile Include="portultra\events.cpp" />
|
||||
<ClCompile Include="portultra\mesgqueue.cpp" />
|
||||
<ClCompile Include="portultra\misc_ultra.cpp" />
|
||||
|
|
|
@ -97,6 +97,7 @@
|
|||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
|
@ -118,6 +119,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PrecompiledHeaderFile />
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
|
@ -136,6 +138,7 @@
|
|||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<EnableParallelCodeGeneration>true</EnableParallelCodeGeneration>
|
||||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
|
@ -157,6 +160,7 @@
|
|||
<MultiProcessorCompilation>true</MultiProcessorCompilation>
|
||||
<WholeProgramOptimization>false</WholeProgramOptimization>
|
||||
<PrecompiledHeaderFile />
|
||||
<ExceptionHandling>SyncCThrow</ExceptionHandling>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -73,7 +73,7 @@ void handle_thread_stopping(thread_queue_t& running_thread_queue) {
|
|||
}
|
||||
}
|
||||
|
||||
void handle_thread_cleanup(thread_queue_t& running_thread_queue) {
|
||||
void handle_thread_cleanup(thread_queue_t& running_thread_queue, OSThread*& cur_running_thread) {
|
||||
std::lock_guard lock{scheduler_context.mutex};
|
||||
|
||||
while (!scheduler_context.to_cleanup.empty()) {
|
||||
|
@ -83,8 +83,20 @@ void handle_thread_cleanup(thread_queue_t& running_thread_queue) {
|
|||
|
||||
debug_printf("[Scheduler] Destroying thread %d\n", to_cleanup->id);
|
||||
running_thread_queue.remove(to_cleanup);
|
||||
// If the cleaned up thread was the running thread, schedule a new one to run.
|
||||
if (to_cleanup == cur_running_thread) {
|
||||
// If there's a thread queued to run, set it as the new running thread.
|
||||
if (!running_thread_queue.empty()) {
|
||||
cur_running_thread = running_thread_queue.top();
|
||||
}
|
||||
// Otherwise, set the running thread to null so the next thread that can be run gets started.
|
||||
else {
|
||||
cur_running_thread = nullptr;
|
||||
}
|
||||
}
|
||||
to_cleanup->context->host_thread.join();
|
||||
delete to_cleanup->context;
|
||||
to_cleanup->context = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -153,7 +165,7 @@ void scheduler_func() {
|
|||
handle_thread_stopping(running_thread_queue);
|
||||
|
||||
// Handle cleaning up threads
|
||||
handle_thread_cleanup(running_thread_queue);
|
||||
handle_thread_cleanup(running_thread_queue, cur_running_thread);
|
||||
|
||||
// Handle queueing threads to run
|
||||
handle_thread_queueing(running_thread_queue);
|
||||
|
|
|
@ -41,6 +41,8 @@ void run_thread_function(uint8_t* rdram, uint64_t addr, uint64_t sp, uint64_t ar
|
|||
#define run_thread_function(func, sp, arg) func(arg)
|
||||
#endif
|
||||
|
||||
struct thread_terminated : std::exception {};
|
||||
|
||||
static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entrypoint, PTR(void) arg) {
|
||||
OSThread *self = TO_PTR(OSThread, self_);
|
||||
debug_printf("[Thread] Thread created: %d\n", self->id);
|
||||
|
@ -72,8 +74,12 @@ static void _thread_func(RDRAM_ARG PTR(OSThread) self_, PTR(thread_func_t) entry
|
|||
|
||||
debug_printf("[Thread] Thread started: %d\n", self->id);
|
||||
|
||||
// Run the thread's function with the provided argument.
|
||||
run_thread_function(PASS_RDRAM entrypoint, self->sp, arg);
|
||||
try {
|
||||
// Run the thread's function with the provided argument.
|
||||
run_thread_function(PASS_RDRAM entrypoint, self->sp, arg);
|
||||
} catch (thread_terminated& terminated) {
|
||||
|
||||
}
|
||||
|
||||
// Dispose of this thread after it completes.
|
||||
Multilibultra::cleanup_thread(self);
|
||||
|
@ -110,6 +116,7 @@ extern "C" void osCreateThread(RDRAM_ARG PTR(OSThread) t_, OSId id, PTR(thread_f
|
|||
t->id = id;
|
||||
t->state = OSThreadState::PAUSED;
|
||||
t->sp = sp - 0x10; // Set up the first stack frame
|
||||
t->destroyed = false;
|
||||
|
||||
// Spawn a new thread, which will immediately pause itself and wait until it's been started.
|
||||
t->context = new UltraThreadContext{};
|
||||
|
@ -124,7 +131,16 @@ extern "C" void osStopThread(RDRAM_ARG PTR(OSThread) t_) {
|
|||
}
|
||||
|
||||
extern "C" void osDestroyThread(RDRAM_ARG PTR(OSThread) t_) {
|
||||
assert(false);
|
||||
// Check if the thread is destroying itself (arg is null or thread_self)
|
||||
if (t_ == NULLPTR || t_ == thread_self) {
|
||||
throw thread_terminated{};
|
||||
}
|
||||
// Otherwise, mark the target thread as destroyed. Next time it reaches a stopping point,
|
||||
// it'll check this and terminate itself instead of pausing.
|
||||
else {
|
||||
OSThread* t = TO_PTR(OSThread, t_);
|
||||
t->destroyed = true;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" void osSetThreadPri(RDRAM_ARG PTR(OSThread) t, OSPri pri) {
|
||||
|
@ -168,8 +184,16 @@ void Multilibultra::set_self_paused(RDRAM_ARG1) {
|
|||
TO_PTR(OSThread, thread_self)->context->running.notify_all();
|
||||
}
|
||||
|
||||
void check_destroyed(OSThread* t) {
|
||||
if (t->destroyed) {
|
||||
throw thread_terminated{};
|
||||
}
|
||||
}
|
||||
|
||||
void Multilibultra::wait_for_resumed(RDRAM_ARG1) {
|
||||
check_destroyed(TO_PTR(OSThread, thread_self));
|
||||
TO_PTR(OSThread, thread_self)->context->running.wait(false);
|
||||
check_destroyed(TO_PTR(OSThread, thread_self));
|
||||
}
|
||||
|
||||
void Multilibultra::pause_thread_impl(OSThread* t) {
|
||||
|
|
|
@ -163,11 +163,6 @@ extern "C" OSTime osGetTime() {
|
|||
extern "C" int osSetTimer(RDRAM_ARG PTR(OSTimer) t_, OSTime countdown, OSTime interval, PTR(OSMesgQueue) mq, OSMesg msg) {
|
||||
OSTimer* t = TO_PTR(OSTimer, t_);
|
||||
|
||||
// HACK: Skip the RCP timeout detection
|
||||
if ((countdown == 140625000 || countdown == 1500000) && (uintptr_t)msg == 666) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Determine the time when this timer will trigger off
|
||||
if (countdown == 0) {
|
||||
// Set the timestamp based on the interval
|
||||
|
|
|
@ -93,6 +93,7 @@ typedef struct OSThread_t {
|
|||
int32_t pad3;
|
||||
UltraThreadContext* context; // An actual pointer regardless of platform
|
||||
int32_t sp;
|
||||
bool destroyed;
|
||||
} OSThread;
|
||||
|
||||
typedef u32 OSEvent;
|
||||
|
|
|
@ -31,8 +31,9 @@ extern "C" void osFlashReadId_recomp(uint8_t * rdram, recomp_context * ctx) {
|
|||
PTR(u32) flash_type = ctx->r4;
|
||||
PTR(u32) flash_maker = ctx->r5;
|
||||
|
||||
MEM_B(0, flash_type) = 0;
|
||||
MEM_B(0, flash_maker) = 0;
|
||||
// Mimic a real flash chip's type and maker, as some games actually check if one is present.
|
||||
MEM_W(0, flash_type) = 0x11118001;
|
||||
MEM_W(0, flash_maker) = 0x00C2001E;
|
||||
}
|
||||
|
||||
extern "C" void osFlashClearStatus_recomp(uint8_t * rdram, recomp_context * ctx) {
|
||||
|
|
Loading…
Reference in New Issue