Skip to content

Instantly share code, notes, and snippets.

@Subv
Created September 30, 2017 14:18
Show Gist options
  • Save Subv/85d15c0daa975cf4e690912d83109b36 to your computer and use it in GitHub Desktop.
Save Subv/85d15c0daa975cf4e690912d83109b36 to your computer and use it in GitHub Desktop.
// Copyright 2017 Citra Emulator Project
// Licensed under GPLv2 or any later version
// Refer to the license.txt file included.
#include <memory>
#include <vector>
#include <catch.hpp>
#include "core/core.h"
#include "core/core_timing.h"
#include "core/hle/kernel/event.h"
#include "core/hle/kernel/process.h"
#include "core/hle/kernel/thread.h"
#include "core/memory.h"
namespace Kernel {
static SharedPtr<Event> MakeEvent() {
return Event::Create(ResetType::OneShot);
}
TEST_CASE("WaitObject::WakeupAllWaitingThreads", "[core][kernel]") {
static constexpr u32 system_mode = 2;
CoreTiming::Init();
Kernel::Init(system_mode);
Kernel::g_current_process = Process::Create(CodeSet::Create("", 0));
auto& vm_manager = Kernel::g_current_process->vm_manager;
Memory::SetCurrentPageTable(&vm_manager.page_table);
auto process_memory = std::make_shared<std::vector<u8>>(Memory::PAGE_SIZE);
vm_manager.MapMemoryBlock(Memory::PROCESS_IMAGE_VADDR, process_memory, 0,
process_memory->size(), MemoryState::Code);
auto result = Thread::Create("Test thread", Memory::PROCESS_IMAGE_VADDR, THREADPRIO_DEFAULT, 0,
THREADPROCESSORID_0, Memory::HEAP_VADDR_END);
REQUIRE(result.Succeeded());
auto thread = result.Unwrap();
SECTION("wake up callback is properly invoked") {
bool callback_called = false;
auto event = MakeEvent();
REQUIRE(thread->status == THREADSTATUS_READY);
// Set up the callback, it should be called when the object is signaled.
thread->wakeup_callback = [&callback_called,
&event](ThreadWakeupReason reason,
Kernel::SharedPtr<Kernel::Thread> thread,
Kernel::SharedPtr<Kernel::WaitObject> object) {
CHECK(thread->status == THREADSTATUS_WAIT_SYNCH_ANY);
CHECK(reason == ThreadWakeupReason::Signal);
CHECK(object == event);
CHECK(callback_called == false);
callback_called = true;
};
thread->wait_objects = {event};
event->AddWaitingThread(thread);
thread->status = THREADSTATUS_WAIT_SYNCH_ANY;
event->Signal();
CHECK(callback_called);
CHECK(thread->wait_objects.empty());
CHECK(thread->status == THREADSTATUS_READY);
}
}
} // namespace Kernel
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment