diff options
| author | 2015-01-23 02:19:33 -0200 | |
|---|---|---|
| committer | 2015-01-30 11:47:07 -0200 | |
| commit | ad80ff1e322430634e04ffcb39ffef268411ea6b (patch) | |
| tree | d9f7c1db67286a11812ffcc1e26f1abb5c02a033 /src/core/hle/kernel/timer.cpp | |
| 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/core/hle/kernel/timer.cpp')
| -rw-r--r-- | src/core/hle/kernel/timer.cpp | 107 |
1 files changed, 31 insertions, 76 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() { |