mirror of
https://github.com/citra-emu/citra.git
synced 2024-11-25 18:50:14 +00:00
Implement Event signaling delay
This commit is contained in:
parent
cc7f1155a8
commit
e8cc3c816c
@ -3,15 +3,23 @@
|
||||
// Refer to the license.txt file included.
|
||||
|
||||
#include <algorithm>
|
||||
#include <cinttypes>
|
||||
#include <map>
|
||||
#include <vector>
|
||||
#include "common/assert.h"
|
||||
#include "core/core_timing.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/thread.h"
|
||||
|
||||
namespace Kernel {
|
||||
|
||||
/// The event type of the generic event callback
|
||||
static int event_callback_event_type;
|
||||
// TODO(yuriks): This can be removed if Event objects are explicitly pooled in the future, allowing
|
||||
// us to simply use a pool index or similar.
|
||||
static Kernel::HandleTable event_callback_handle_table;
|
||||
|
||||
Event::Event() {}
|
||||
Event::~Event() {}
|
||||
|
||||
@ -21,6 +29,7 @@ SharedPtr<Event> Event::Create(ResetType reset_type, std::string name) {
|
||||
evt->signaled = false;
|
||||
evt->reset_type = reset_type;
|
||||
evt->name = std::move(name);
|
||||
evt->callback_handle = event_callback_handle_table.Create(evt).MoveFrom();
|
||||
|
||||
return evt;
|
||||
}
|
||||
@ -37,6 +46,16 @@ void Event::Acquire() {
|
||||
signaled = false;
|
||||
}
|
||||
|
||||
void Event::Delay(u64 delay) {
|
||||
// Ensure we get rid of any previous scheduled event
|
||||
Cancel();
|
||||
|
||||
u64 microseconds = delay / 1000;
|
||||
CoreTiming::ScheduleEvent(usToCycles(microseconds), event_callback_event_type, callback_handle);
|
||||
|
||||
HLE::Reschedule(__func__);
|
||||
}
|
||||
|
||||
void Event::Signal() {
|
||||
signaled = true;
|
||||
WakeupAllWaitingThreads();
|
||||
@ -46,4 +65,35 @@ void Event::Clear() {
|
||||
signaled = false;
|
||||
}
|
||||
|
||||
void Event::Cancel() {
|
||||
CoreTiming::UnscheduleEvent(event_callback_event_type, callback_handle);
|
||||
|
||||
HLE::Reschedule(__func__);
|
||||
}
|
||||
|
||||
/// The event callback event
|
||||
static void EventCallback(u64 event_handle, int /*cycles_late*/) {
|
||||
SharedPtr<Event> event =
|
||||
event_callback_handle_table.Get<Event>(static_cast<Handle>(event_handle));
|
||||
|
||||
if (event == nullptr) {
|
||||
LOG_CRITICAL(Kernel, "Callback fired for invalid event %08" PRIx64, event_handle);
|
||||
return;
|
||||
}
|
||||
|
||||
LOG_TRACE(Kernel, "Event %08" PRIx64 " signaled", event_handle);
|
||||
|
||||
event->signaled = true;
|
||||
|
||||
// Resume all waiting threads
|
||||
event->WakeupAllWaitingThreads();
|
||||
}
|
||||
|
||||
void EventsInit() {
|
||||
event_callback_handle_table.Clear();
|
||||
event_callback_event_type = CoreTiming::RegisterEvent("EventCallback", EventCallback);
|
||||
}
|
||||
|
||||
void EventsShutdown() {}
|
||||
|
||||
} // namespace
|
||||
|
@ -38,12 +38,22 @@ public:
|
||||
bool ShouldWait() override;
|
||||
void Acquire() override;
|
||||
|
||||
void Delay(u64 delay);
|
||||
void Signal();
|
||||
void Clear();
|
||||
void Cancel();
|
||||
|
||||
private:
|
||||
Event();
|
||||
~Event() override;
|
||||
|
||||
/// Handle used as userdata to reference this object when inserting into the CoreTiming queue.
|
||||
Handle callback_handle;
|
||||
};
|
||||
|
||||
/// Initializes the required variables for events
|
||||
void EventsInit();
|
||||
/// Tears down the event variables
|
||||
void EventsShutdown();
|
||||
|
||||
} // namespace
|
||||
|
@ -6,6 +6,7 @@
|
||||
#include "common/assert.h"
|
||||
#include "common/logging/log.h"
|
||||
#include "core/hle/config_mem.h"
|
||||
#include "core/hle/kernel/event.h"
|
||||
#include "core/hle/kernel/kernel.h"
|
||||
#include "core/hle/kernel/memory.h"
|
||||
#include "core/hle/kernel/process.h"
|
||||
@ -135,6 +136,7 @@ void Init() {
|
||||
Kernel::ResourceLimitsInit();
|
||||
Kernel::ThreadingInit();
|
||||
Kernel::TimersInit();
|
||||
Kernel::EventsInit();
|
||||
|
||||
Object::next_object_id = 0;
|
||||
// TODO(Subv): Start the process ids from 10 for now, as lower PIDs are
|
||||
@ -149,6 +151,7 @@ void Shutdown() {
|
||||
Kernel::ThreadingShutdown();
|
||||
g_current_process = nullptr;
|
||||
|
||||
Kernel::EventsShutdown();
|
||||
Kernel::TimersShutdown();
|
||||
Kernel::ResourceLimitsShutdown();
|
||||
Kernel::MemoryShutdown();
|
||||
|
@ -247,7 +247,7 @@ static void SetTransferEndInterrupt(Service::Interface* self) {
|
||||
cmd_buff[0] = IPC::MakeHeader(0xD, 1, 0);
|
||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||
|
||||
LOG_WARNING(Service_Y2R, "(STUBBED) called");
|
||||
LOG_WARNING(Service_Y2R, "(STUBBED) called, enabled = %u", transfer_end_interrupt_enabled);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -591,7 +591,7 @@ static void StartConversion(Service::Interface* self) {
|
||||
|
||||
HW::Y2R::PerformConversion(conversion);
|
||||
|
||||
completion_event->Signal();
|
||||
completion_event->Delay(1000);
|
||||
|
||||
cmd_buff[0] = IPC::MakeHeader(0x26, 1, 0);
|
||||
cmd_buff[1] = RESULT_SUCCESS.raw;
|
||||
|
Loading…
Reference in New Issue
Block a user