diff options
| author | 2015-01-23 02:19:33 -0200 | |
|---|---|---|
| committer | 2015-01-30 11:47:07 -0200 | |
| commit | ad80ff1e322430634e04ffcb39ffef268411ea6b (patch) | |
| tree | d9f7c1db67286a11812ffcc1e26f1abb5c02a033 /src | |
| parent | Kernel: Convert Mutex to not use Handles (diff) | |
| download | yuzu-ad80ff1e322430634e04ffcb39ffef268411ea6b.tar.gz yuzu-ad80ff1e322430634e04ffcb39ffef268411ea6b.tar.xz yuzu-ad80ff1e322430634e04ffcb39ffef268411ea6b.zip | |
Kernel: Convert Timer to (mostly) not use Handles
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 107 | ||||
| -rw-r--r-- | src/core/hle/kernel/timer.h | 69 | ||||
| -rw-r--r-- | src/core/hle/svc.cpp | 47 |
3 files changed, 112 insertions, 111 deletions
diff --git a/src/core/hle/kernel/timer.cpp b/src/core/hle/kernel/timer.cpp index aee5dc599..503a5d2ce 100644 --- a/src/core/hle/kernel/timer.cpp +++ b/src/core/hle/kernel/timer.cpp | |||
| @@ -13,75 +13,54 @@ | |||
| 13 | 13 | ||
| 14 | namespace Kernel { | 14 | namespace Kernel { |
| 15 | 15 | ||
| 16 | class Timer : public WaitObject { | 16 | /// The event type of the generic timer callback event |
| 17 | public: | 17 | static int timer_callback_event_type = -1; |
| 18 | std::string GetTypeName() const override { return "Timer"; } | ||
| 19 | std::string GetName() const override { return name; } | ||
| 20 | |||
| 21 | static const HandleType HANDLE_TYPE = HandleType::Timer; | ||
| 22 | HandleType GetHandleType() const override { return HANDLE_TYPE; } | ||
| 23 | |||
| 24 | ResetType reset_type; ///< The ResetType of this timer | ||
| 25 | |||
| 26 | bool signaled; ///< Whether the timer has been signaled or not | ||
| 27 | std::string name; ///< Name of timer (optional) | ||
| 28 | |||
| 29 | u64 initial_delay; ///< The delay until the timer fires for the first time | ||
| 30 | u64 interval_delay; ///< The delay until the timer fires after the first time | ||
| 31 | |||
| 32 | bool ShouldWait() override { | ||
| 33 | return !signaled; | ||
| 34 | } | ||
| 35 | |||
| 36 | void Acquire() override { | ||
| 37 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); | ||
| 38 | } | ||
| 39 | }; | ||
| 40 | |||
| 41 | /** | ||
| 42 | * Creates a timer. | ||
| 43 | * @param handle Reference to handle for the newly created timer | ||
| 44 | * @param reset_type ResetType describing how to create timer | ||
| 45 | * @param name Optional name of timer | ||
| 46 | * @return Newly created Timer object | ||
| 47 | */ | ||
| 48 | static Timer* CreateTimer(Handle& handle, const ResetType reset_type, const std::string& name) { | ||
| 49 | Timer* timer = new Timer; | ||
| 50 | 18 | ||
| 51 | handle = Kernel::g_handle_table.Create(timer).ValueOr(INVALID_HANDLE); | 19 | ResultVal<SharedPtr<Timer>> Timer::Create(ResetType reset_type, std::string name) { |
| 20 | SharedPtr<Timer> timer(new Timer); | ||
| 21 | // TOOD(yuriks): Don't create Handle (see Thread::Create()) | ||
| 22 | CASCADE_RESULT(auto unused, Kernel::g_handle_table.Create(timer)); | ||
| 52 | 23 | ||
| 53 | timer->reset_type = reset_type; | 24 | timer->reset_type = reset_type; |
| 54 | timer->signaled = false; | 25 | timer->signaled = false; |
| 55 | timer->name = name; | 26 | timer->name = std::move(name); |
| 56 | timer->initial_delay = 0; | 27 | timer->initial_delay = 0; |
| 57 | timer->interval_delay = 0; | 28 | timer->interval_delay = 0; |
| 58 | return timer; | 29 | return MakeResult<SharedPtr<Timer>>(timer); |
| 59 | } | 30 | } |
| 60 | 31 | ||
| 61 | ResultCode CreateTimer(Handle* handle, const ResetType reset_type, const std::string& name) { | 32 | bool Timer::ShouldWait() { |
| 62 | CreateTimer(*handle, reset_type, name); | 33 | return !signaled; |
| 63 | return RESULT_SUCCESS; | ||
| 64 | } | 34 | } |
| 65 | 35 | ||
| 66 | ResultCode ClearTimer(Handle handle) { | 36 | void Timer::Acquire() { |
| 67 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | 37 | _assert_msg_(Kernel, !ShouldWait(), "object unavailable!"); |
| 68 | 38 | } | |
| 69 | if (timer == nullptr) | ||
| 70 | return InvalidHandle(ErrorModule::Kernel); | ||
| 71 | 39 | ||
| 72 | timer->signaled = false; | 40 | void Timer::Set(s64 initial, s64 interval) { |
| 73 | return RESULT_SUCCESS; | 41 | initial_delay = initial; |
| 42 | interval_delay = interval; | ||
| 43 | |||
| 44 | u64 initial_microseconds = initial / 1000; | ||
| 45 | // TODO(yuriks): Figure out a replacement for GetHandle here | ||
| 46 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), timer_callback_event_type, | ||
| 47 | GetHandle()); | ||
| 74 | } | 48 | } |
| 75 | 49 | ||
| 76 | /// The event type of the generic timer callback event | 50 | void Timer::Cancel() { |
| 77 | static int TimerCallbackEventType = -1; | 51 | CoreTiming::UnscheduleEvent(timer_callback_event_type, GetHandle()); |
| 52 | } | ||
| 53 | |||
| 54 | void Timer::Clear() { | ||
| 55 | signaled = false; | ||
| 56 | } | ||
| 78 | 57 | ||
| 79 | /// The timer callback event, called when a timer is fired | 58 | /// The timer callback event, called when a timer is fired |
| 80 | static void TimerCallback(u64 timer_handle, int cycles_late) { | 59 | static void TimerCallback(u64 timer_handle, int cycles_late) { |
| 81 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle); | 60 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(timer_handle); |
| 82 | 61 | ||
| 83 | if (timer == nullptr) { | 62 | if (timer == nullptr) { |
| 84 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %u", timer_handle); | 63 | LOG_CRITICAL(Kernel, "Callback fired for invalid timer %08X", timer_handle); |
| 85 | return; | 64 | return; |
| 86 | } | 65 | } |
| 87 | 66 | ||
| @@ -99,36 +78,12 @@ static void TimerCallback(u64 timer_handle, int cycles_late) { | |||
| 99 | // Reschedule the timer with the interval delay | 78 | // Reschedule the timer with the interval delay |
| 100 | u64 interval_microseconds = timer->interval_delay / 1000; | 79 | u64 interval_microseconds = timer->interval_delay / 1000; |
| 101 | CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, | 80 | CoreTiming::ScheduleEvent(usToCycles(interval_microseconds) - cycles_late, |
| 102 | TimerCallbackEventType, timer_handle); | 81 | timer_callback_event_type, timer_handle); |
| 103 | } | 82 | } |
| 104 | } | 83 | } |
| 105 | 84 | ||
| 106 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval) { | ||
| 107 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||
| 108 | |||
| 109 | if (timer == nullptr) | ||
| 110 | return InvalidHandle(ErrorModule::Kernel); | ||
| 111 | |||
| 112 | timer->initial_delay = initial; | ||
| 113 | timer->interval_delay = interval; | ||
| 114 | |||
| 115 | u64 initial_microseconds = initial / 1000; | ||
| 116 | CoreTiming::ScheduleEvent(usToCycles(initial_microseconds), TimerCallbackEventType, handle); | ||
| 117 | return RESULT_SUCCESS; | ||
| 118 | } | ||
| 119 | |||
| 120 | ResultCode CancelTimer(Handle handle) { | ||
| 121 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||
| 122 | |||
| 123 | if (timer == nullptr) | ||
| 124 | return InvalidHandle(ErrorModule::Kernel); | ||
| 125 | |||
| 126 | CoreTiming::UnscheduleEvent(TimerCallbackEventType, handle); | ||
| 127 | return RESULT_SUCCESS; | ||
| 128 | } | ||
| 129 | |||
| 130 | void TimersInit() { | 85 | void TimersInit() { |
| 131 | TimerCallbackEventType = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); | 86 | timer_callback_event_type = CoreTiming::RegisterEvent("TimerCallback", TimerCallback); |
| 132 | } | 87 | } |
| 133 | 88 | ||
| 134 | void TimersShutdown() { | 89 | void TimersShutdown() { |
diff --git a/src/core/hle/kernel/timer.h b/src/core/hle/kernel/timer.h index 8170e82d4..24552b4b9 100644 --- a/src/core/hle/kernel/timer.h +++ b/src/core/hle/kernel/timer.h | |||
| @@ -11,37 +11,50 @@ | |||
| 11 | 11 | ||
| 12 | namespace Kernel { | 12 | namespace Kernel { |
| 13 | 13 | ||
| 14 | /** | 14 | class Timer : public WaitObject { |
| 15 | * Cancels a timer | 15 | public: |
| 16 | * @param handle Handle of the timer to cancel | 16 | /** |
| 17 | */ | 17 | * Creates a timer |
| 18 | ResultCode CancelTimer(Handle handle); | 18 | * @param reset_type ResetType describing how to create the timer |
| 19 | 19 | * @param name Optional name of timer | |
| 20 | /** | 20 | * @return The created Timer |
| 21 | * Starts a timer with the specified initial delay and interval | 21 | */ |
| 22 | * @param handle Handle of the timer to start | 22 | static ResultVal<SharedPtr<Timer>> Create(ResetType reset_type, std::string name = "Unknown"); |
| 23 | * @param initial Delay until the timer is first fired | 23 | |
| 24 | * @param interval Delay until the timer is fired after the first time | 24 | std::string GetTypeName() const override { return "Timer"; } |
| 25 | */ | 25 | std::string GetName() const override { return name; } |
| 26 | ResultCode SetTimer(Handle handle, s64 initial, s64 interval); | 26 | |
| 27 | 27 | static const HandleType HANDLE_TYPE = HandleType::Timer; | |
| 28 | /** | 28 | HandleType GetHandleType() const override { return HANDLE_TYPE; } |
| 29 | * Clears a timer | 29 | |
| 30 | * @param handle Handle of the timer to clear | 30 | ResetType reset_type; ///< The ResetType of this timer |
| 31 | */ | 31 | |
| 32 | ResultCode ClearTimer(Handle handle); | 32 | bool signaled; ///< Whether the timer has been signaled or not |
| 33 | 33 | std::string name; ///< Name of timer (optional) | |
| 34 | /** | 34 | |
| 35 | * Creates a timer | 35 | u64 initial_delay; ///< The delay until the timer fires for the first time |
| 36 | * @param handle Handle to the newly created Timer object | 36 | u64 interval_delay; ///< The delay until the timer fires after the first time |
| 37 | * @param reset_type ResetType describing how to create the timer | 37 | |
| 38 | * @param name Optional name of timer | 38 | bool ShouldWait() override; |
| 39 | * @return ResultCode of the error | 39 | void Acquire() override; |
| 40 | */ | 40 | |
| 41 | ResultCode CreateTimer(Handle* handle, const ResetType reset_type, const std::string& name="Unknown"); | 41 | /** |
| 42 | * Starts the timer, with the specified initial delay and interval. | ||
| 43 | * @param initial Delay until the timer is first fired | ||
| 44 | * @param interval Delay until the timer is fired after the first time | ||
| 45 | */ | ||
| 46 | void Set(s64 initial, s64 interval); | ||
| 47 | |||
| 48 | void Cancel(); | ||
| 49 | void Clear(); | ||
| 50 | |||
| 51 | private: | ||
| 52 | Timer() = default; | ||
| 53 | }; | ||
| 42 | 54 | ||
| 43 | /// Initializes the required variables for timers | 55 | /// Initializes the required variables for timers |
| 44 | void TimersInit(); | 56 | void TimersInit(); |
| 45 | /// Tears down the timer variables | 57 | /// Tears down the timer variables |
| 46 | void TimersShutdown(); | 58 | void TimersShutdown(); |
| 59 | |||
| 47 | } // namespace | 60 | } // namespace |
diff --git a/src/core/hle/svc.cpp b/src/core/hle/svc.cpp index 76ce59b29..95403644b 100644 --- a/src/core/hle/svc.cpp +++ b/src/core/hle/svc.cpp | |||
| @@ -479,28 +479,61 @@ static Result ClearEvent(Handle evt) { | |||
| 479 | 479 | ||
| 480 | /// Creates a timer | 480 | /// Creates a timer |
| 481 | static Result CreateTimer(Handle* handle, u32 reset_type) { | 481 | static Result CreateTimer(Handle* handle, u32 reset_type) { |
| 482 | ResultCode res = Kernel::CreateTimer(handle, static_cast<ResetType>(reset_type)); | 482 | using Kernel::Timer; |
| 483 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", | 483 | |
| 484 | reset_type, *handle); | 484 | auto timer_res = Timer::Create(static_cast<ResetType>(reset_type)); |
| 485 | return res.raw; | 485 | if (timer_res.Failed()) |
| 486 | return timer_res.Code().raw; | ||
| 487 | |||
| 488 | auto handle_res = Kernel::g_handle_table.Create(timer_res.MoveFrom()); | ||
| 489 | if (handle_res.Failed()) | ||
| 490 | return handle_res.Code().raw; | ||
| 491 | *handle = handle_res.MoveFrom(); | ||
| 492 | |||
| 493 | LOG_TRACE(Kernel_SVC, "called reset_type=0x%08X : created handle=0x%08X", reset_type, *handle); | ||
| 494 | return RESULT_SUCCESS.raw; | ||
| 486 | } | 495 | } |
| 487 | 496 | ||
| 488 | /// Clears a timer | 497 | /// Clears a timer |
| 489 | static Result ClearTimer(Handle handle) { | 498 | static Result ClearTimer(Handle handle) { |
| 499 | using Kernel::Timer; | ||
| 500 | |||
| 490 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); | 501 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); |
| 491 | return Kernel::ClearTimer(handle).raw; | 502 | |
| 503 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||
| 504 | if (timer == nullptr) | ||
| 505 | return InvalidHandle(ErrorModule::Kernel).raw; | ||
| 506 | |||
| 507 | timer->Clear(); | ||
| 508 | return RESULT_SUCCESS.raw; | ||
| 492 | } | 509 | } |
| 493 | 510 | ||
| 494 | /// Starts a timer | 511 | /// Starts a timer |
| 495 | static Result SetTimer(Handle handle, s64 initial, s64 interval) { | 512 | static Result SetTimer(Handle handle, s64 initial, s64 interval) { |
| 513 | using Kernel::Timer; | ||
| 514 | |||
| 496 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); | 515 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); |
| 497 | return Kernel::SetTimer(handle, initial, interval).raw; | 516 | |
| 517 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||
| 518 | if (timer == nullptr) | ||
| 519 | return InvalidHandle(ErrorModule::Kernel).raw; | ||
| 520 | |||
| 521 | timer->Set(initial, interval); | ||
| 522 | return RESULT_SUCCESS.raw; | ||
| 498 | } | 523 | } |
| 499 | 524 | ||
| 500 | /// Cancels a timer | 525 | /// Cancels a timer |
| 501 | static Result CancelTimer(Handle handle) { | 526 | static Result CancelTimer(Handle handle) { |
| 527 | using Kernel::Timer; | ||
| 528 | |||
| 502 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); | 529 | LOG_TRACE(Kernel_SVC, "called timer=0x%08X", handle); |
| 503 | return Kernel::CancelTimer(handle).raw; | 530 | |
| 531 | SharedPtr<Timer> timer = Kernel::g_handle_table.Get<Timer>(handle); | ||
| 532 | if (timer == nullptr) | ||
| 533 | return InvalidHandle(ErrorModule::Kernel).raw; | ||
| 534 | |||
| 535 | timer->Cancel(); | ||
| 536 | return RESULT_SUCCESS.raw; | ||
| 504 | } | 537 | } |
| 505 | 538 | ||
| 506 | /// Sleep the current thread | 539 | /// Sleep the current thread |