int main(int argc, char **argv) { OSReport("Main thread running on core %d", OSGetCoreId()); // Run thread on core 0 OSThread *threadCore0 = OSGetDefaultThread(0); const char *core0Args[] = { "Core 0" }; OSRunThread(threadCore0, CoreEntryPoint, 0, core0Args); // Run thread on core 2 OSThread *threadCore2 = OSGetDefaultThread(2); const char *core2Args[] = { "Core 2" }; OSRunThread(threadCore2, CoreEntryPoint, 2, core2Args); // Wait for threads to return int resultCore0 = -1, resultCore2 = -1; OSJoinThread(threadCore0, &resultCore0); OSJoinThread(threadCore2, &resultCore2); OSReport("Core 0 thread returned %d", resultCore0); OSReport("Core 2 thread returned %d", resultCore2); return 0; }
void GameLoaderRun() { auto appModule = gLoader.loadRPL(gGameRpx.c_str()); if (!appModule) { gLog->error("Could not load {}", gGameRpx); return; } gSystem.setUserModule(appModule); gDebugControl.preLaunch(); gLog->debug("Succesfully loaded {}", gGameRpx); // Call the RPX __preinit_user if it is defined auto userPreinit = appModule->findFuncExport<void, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*, be_ptr<CommonHeap>*>("__preinit_user"); if (userPreinit) { struct HeapHandles { be_ptr<CommonHeap> mem1Heap; be_ptr<CommonHeap> fgHeap; be_ptr<CommonHeap> mem2Heap; }; HeapHandles *wiiHandles = OSAllocFromSystem<HeapHandles>(); wiiHandles->mem1Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM1); wiiHandles->fgHeap = MEMGetBaseHeapHandle(BaseHeapType::FG); wiiHandles->mem2Heap = MEMGetBaseHeapHandle(BaseHeapType::MEM2); userPreinit(&wiiHandles->mem1Heap, &wiiHandles->fgHeap, &wiiHandles->mem2Heap); MEMSetBaseHeapHandle(BaseHeapType::MEM1, wiiHandles->mem1Heap); MEMSetBaseHeapHandle(BaseHeapType::FG, wiiHandles->fgHeap); MEMSetBaseHeapHandle(BaseHeapType::MEM2, wiiHandles->mem2Heap); OSFreeToSystem(wiiHandles); } // Create default threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = appModule->defaultStackSize; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Default Thread %d", i); OSCreateThread(thread, 0u, 0, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, 16, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetDefaultThread(i, thread); OSSetThreadName(thread, name); } // Create interrupt threads for (auto i = 0u; i < CoreCount; ++i) { auto thread = OSAllocFromSystem<OSThread>(); auto stackSize = 16 * 1024; auto stack = reinterpret_cast<uint8_t*>(OSAllocFromSystem(stackSize, 8)); auto name = OSSprintfFromSystem("Interrupt Thread %d", i); OSCreateThread(thread, InterruptThreadEntryPoint, i, nullptr, reinterpret_cast<be_val<uint32_t>*>(stack + stackSize), stackSize, -1, static_cast<OSThreadAttributes::Flags>(1 << i)); OSSetInterruptThread(i, thread); OSSetThreadName(thread, name); OSResumeThread(thread); } // Run thread 1 OSRunThread(OSGetDefaultThread(1), appModule->entryPoint, 0, nullptr); }