diff options
author | Ben Wiederhake <BenWiederhake.GitHub@gmx.de> | 2021-02-27 23:56:16 +0100 |
---|---|---|
committer | Andreas Kling <kling@serenityos.org> | 2021-03-02 08:36:08 +0100 |
commit | 2b6546c40a7ea7738a3bda81f57e396ab3a305ea (patch) | |
tree | 06416116c6faf30423fb074fa862a34e46139e6a /Kernel | |
parent | 65b36e42b8dc92a2be7324b38a19956da110b7f1 (diff) | |
download | serenity-2b6546c40a7ea7738a3bda81f57e396ab3a305ea.zip |
Kernel: Make Thread use AK::Time internally
This commit is very invasive, because Thread likes to take a pointer and write
to it. This means that translating between timespec/timeval/Time would have been
more difficult than just changing everything that hands a raw pointer to Thread,
in bulk.
Diffstat (limited to 'Kernel')
-rw-r--r-- | Kernel/Devices/AsyncDeviceRequest.cpp | 2 | ||||
-rw-r--r-- | Kernel/Devices/AsyncDeviceRequest.h | 2 | ||||
-rw-r--r-- | Kernel/Devices/USB/UHCIController.cpp | 6 | ||||
-rw-r--r-- | Kernel/Syscalls/alarm.cpp | 10 | ||||
-rw-r--r-- | Kernel/Syscalls/beep.cpp | 2 | ||||
-rw-r--r-- | Kernel/Syscalls/clock.cpp | 11 | ||||
-rw-r--r-- | Kernel/Syscalls/futex.cpp | 4 | ||||
-rw-r--r-- | Kernel/Syscalls/select.cpp | 8 | ||||
-rw-r--r-- | Kernel/Tasks/SyncTask.cpp | 2 | ||||
-rw-r--r-- | Kernel/Thread.cpp | 4 | ||||
-rw-r--r-- | Kernel/Thread.h | 49 | ||||
-rw-r--r-- | Kernel/ThreadBlockers.cpp | 31 | ||||
-rw-r--r-- | Kernel/TimerQueue.cpp | 12 | ||||
-rw-r--r-- | Kernel/TimerQueue.h | 5 |
14 files changed, 66 insertions, 82 deletions
diff --git a/Kernel/Devices/AsyncDeviceRequest.cpp b/Kernel/Devices/AsyncDeviceRequest.cpp index 28e6bea121..1a4430de3e 100644 --- a/Kernel/Devices/AsyncDeviceRequest.cpp +++ b/Kernel/Devices/AsyncDeviceRequest.cpp @@ -68,7 +68,7 @@ void AsyncDeviceRequest::request_finished() m_queue.wake_all(); } -auto AsyncDeviceRequest::wait(timeval* timeout) -> RequestWaitResult +auto AsyncDeviceRequest::wait(Time* timeout) -> RequestWaitResult { VERIFY(!m_parent_request); auto request_result = get_request_result(); diff --git a/Kernel/Devices/AsyncDeviceRequest.h b/Kernel/Devices/AsyncDeviceRequest.h index 0577a3aa17..ec3d7c4e92 100644 --- a/Kernel/Devices/AsyncDeviceRequest.h +++ b/Kernel/Devices/AsyncDeviceRequest.h @@ -76,7 +76,7 @@ public: void add_sub_request(NonnullRefPtr<AsyncDeviceRequest>); - [[nodiscard]] RequestWaitResult wait(timeval* = nullptr); + [[nodiscard]] RequestWaitResult wait(Time* = nullptr); void do_start(Badge<Device>) { diff --git a/Kernel/Devices/USB/UHCIController.cpp b/Kernel/Devices/USB/UHCIController.cpp index 51430d35b1..852f389aa9 100644 --- a/Kernel/Devices/USB/UHCIController.cpp +++ b/Kernel/Devices/USB/UHCIController.cpp @@ -398,10 +398,8 @@ void UHCIController::do_debug_transfer() void UHCIController::spawn_port_proc() { RefPtr<Thread> usb_hotplug_thread; - timespec sleep_time {}; - sleep_time.tv_sec = 1; - Process::create_kernel_process(usb_hotplug_thread, "UHCIHotplug", [&, sleep_time] { + Process::create_kernel_process(usb_hotplug_thread, "UHCIHotplug", [&] { for (;;) { for (int port = 0; port < UHCI_ROOT_PORT_COUNT; port++) { u16 port_data = 0; @@ -448,7 +446,7 @@ void UHCIController::spawn_port_proc() } } } - (void)Thread::current()->sleep(sleep_time); + (void)Thread::current()->sleep(Time::from_seconds(1)); } }); } diff --git a/Kernel/Syscalls/alarm.cpp b/Kernel/Syscalls/alarm.cpp index e195de65fd..ff3de1350c 100644 --- a/Kernel/Syscalls/alarm.cpp +++ b/Kernel/Syscalls/alarm.cpp @@ -36,9 +36,8 @@ KResultOr<unsigned> Process::sys$alarm(unsigned seconds) if (auto alarm_timer = move(m_alarm_timer)) { if (TimerQueue::the().cancel_timer(*alarm_timer)) { // The timer hasn't fired. Round up the remaining time (if any) - timespec remaining; - timespec_add(alarm_timer->remaining(), { 0, 1000000000 - 1 }, remaining); - previous_alarm_remaining = remaining.tv_sec; + Time remaining = alarm_timer->remaining() + Time::from_nanoseconds(999'999'999); + previous_alarm_remaining = remaining.to_truncated_seconds(); } // We had an existing alarm, must return a non-zero value here! if (previous_alarm_remaining == 0) @@ -46,8 +45,9 @@ KResultOr<unsigned> Process::sys$alarm(unsigned seconds) } if (seconds > 0) { - auto deadline = TimeManagement::the().current_time(CLOCK_REALTIME_COARSE).value(); - timespec_add(deadline, { seconds, 0 }, deadline); + // FIXME: Should use AK::Time internally + auto deadline = Time::from_timespec(TimeManagement::the().current_time(CLOCK_REALTIME_COARSE).value()); + deadline = deadline + Time::from_seconds(seconds); m_alarm_timer = TimerQueue::the().add_timer_without_id(CLOCK_REALTIME_COARSE, deadline, [this]() { [[maybe_unused]] auto rc = send_signal(SIGALRM, nullptr); }); diff --git a/Kernel/Syscalls/beep.cpp b/Kernel/Syscalls/beep.cpp index a94df54079..c614a0e47f 100644 --- a/Kernel/Syscalls/beep.cpp +++ b/Kernel/Syscalls/beep.cpp @@ -32,7 +32,7 @@ namespace Kernel { KResultOr<int> Process::sys$beep() { PCSpeaker::tone_on(440); - auto result = Thread::current()->sleep({ 0, 200 }); + auto result = Thread::current()->sleep(Time::from_nanoseconds(200'000'000)); PCSpeaker::tone_off(); if (result.was_interrupted()) return EINTR; diff --git a/Kernel/Syscalls/clock.cpp b/Kernel/Syscalls/clock.cpp index 4e780706c4..d883e6ac04 100644 --- a/Kernel/Syscalls/clock.cpp +++ b/Kernel/Syscalls/clock.cpp @@ -94,13 +94,12 @@ KResultOr<int> Process::sys$clock_nanosleep(Userspace<const Syscall::SC_clock_na bool was_interrupted; if (is_absolute) { - // FIXME: Should use AK::Time internally - was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep->to_timespec()).was_interrupted(); + was_interrupted = Thread::current()->sleep_until(params.clock_id, requested_sleep.value()).was_interrupted(); } else { - timespec remaining_sleep; - // FIXME: Should use AK::Time internally - was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep->to_timespec(), &remaining_sleep).was_interrupted(); - if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep)) + Time remaining_sleep; + was_interrupted = Thread::current()->sleep(params.clock_id, requested_sleep.value(), &remaining_sleep).was_interrupted(); + timespec remaining_sleep_ts = remaining_sleep.to_timespec(); + if (was_interrupted && params.remaining_sleep && !copy_to_user(params.remaining_sleep, &remaining_sleep_ts)) return EFAULT; } if (was_interrupted) diff --git a/Kernel/Syscalls/futex.cpp b/Kernel/Syscalls/futex.cpp index 08ec27d49c..c030a2c59b 100644 --- a/Kernel/Syscalls/futex.cpp +++ b/Kernel/Syscalls/futex.cpp @@ -123,9 +123,7 @@ KResultOr<int> Process::sys$futex(Userspace<const Syscall::SC_futex_params*> use return EFAULT; clockid_t clock_id = (params.futex_op & FUTEX_CLOCK_REALTIME) ? CLOCK_REALTIME_COARSE : CLOCK_MONOTONIC_COARSE; bool is_absolute = cmd != FUTEX_WAIT; - // FIXME: Should use AK::Time internally - timespec timeout_copy = timeout_time->to_timespec(); - timeout = Thread::BlockTimeout(is_absolute, &timeout_copy, nullptr, clock_id); + timeout = Thread::BlockTimeout(is_absolute, &timeout_time.value(), nullptr, clock_id); } if (cmd == FUTEX_WAIT_BITSET && params.val3 == FUTEX_BITSET_MATCH_ANY) cmd = FUTEX_WAIT; diff --git a/Kernel/Syscalls/select.cpp b/Kernel/Syscalls/select.cpp index 3259e51f07..0b7014eb8b 100644 --- a/Kernel/Syscalls/select.cpp +++ b/Kernel/Syscalls/select.cpp @@ -48,9 +48,7 @@ KResultOr<int> Process::sys$select(Userspace<const Syscall::SC_select_params*> u Optional<Time> timeout_time = copy_time_from_user(params.timeout); if (!timeout_time.has_value()) return EFAULT; - auto timeout_copy = timeout_time->to_timespec(); - // FIXME: Should use AK::Time internally - timeout = Thread::BlockTimeout(false, &timeout_copy); + timeout = Thread::BlockTimeout(false, &timeout_time.value()); } auto current_thread = Thread::current(); @@ -156,9 +154,7 @@ KResultOr<int> Process::sys$poll(Userspace<const Syscall::SC_poll_params*> user_ auto timeout_time = copy_time_from_user(params.timeout); if (!timeout_time.has_value()) return EFAULT; - timespec timeout_copy = timeout_time->to_timespec(); - // FIXME: Should use AK::Time internally - timeout = Thread::BlockTimeout(false, &timeout_copy); + timeout = Thread::BlockTimeout(false, &timeout_time.value()); } sigset_t sigmask = {}; diff --git a/Kernel/Tasks/SyncTask.cpp b/Kernel/Tasks/SyncTask.cpp index 940790b103..78e0002aa4 100644 --- a/Kernel/Tasks/SyncTask.cpp +++ b/Kernel/Tasks/SyncTask.cpp @@ -38,7 +38,7 @@ void SyncTask::spawn() dbgln("SyncTask is running"); for (;;) { VFS::the().sync(); - (void)Thread::current()->sleep({ 1, 0 }); + (void)Thread::current()->sleep(Time::from_seconds(1)); } }); } diff --git a/Kernel/Thread.cpp b/Kernel/Thread.cpp index 7040315811..bd50f16dc9 100644 --- a/Kernel/Thread.cpp +++ b/Kernel/Thread.cpp @@ -333,13 +333,13 @@ void Thread::relock_process(LockMode previous_locked, u32 lock_count_to_restore) } } -auto Thread::sleep(clockid_t clock_id, const timespec& duration, timespec* remaining_time) -> BlockResult +auto Thread::sleep(clockid_t clock_id, const Time& duration, Time* remaining_time) -> BlockResult { VERIFY(state() == Thread::Running); return Thread::current()->block<Thread::SleepBlocker>({}, Thread::BlockTimeout(false, &duration, nullptr, clock_id), remaining_time); } -auto Thread::sleep_until(clockid_t clock_id, const timespec& deadline) -> BlockResult +auto Thread::sleep_until(clockid_t clock_id, const Time& deadline) -> BlockResult { VERIFY(state() == Thread::Running); return Thread::current()->block<Thread::SleepBlocker>({}, Thread::BlockTimeout(true, &deadline, nullptr, clock_id)); diff --git a/Kernel/Thread.h b/Kernel/Thread.h index 3f73e2591e..a40ee39748 100644 --- a/Kernel/Thread.h +++ b/Kernel/Thread.h @@ -208,44 +208,17 @@ public: : m_infinite(true) { } - explicit BlockTimeout(bool is_absolute, const timeval* time, const timespec* start_time = nullptr, clockid_t clock_id = CLOCK_MONOTONIC_COARSE) - : m_clock_id(clock_id) - , m_infinite(!time) - { - if (!m_infinite) { - if (time->tv_sec > 0 || time->tv_usec > 0) { - timeval_to_timespec(*time, m_time); - m_should_block = true; - } - m_start_time = start_time ? *start_time : TimeManagement::the().current_time(clock_id).value(); - if (!is_absolute) - timespec_add(m_time, m_start_time, m_time); - } - } - explicit BlockTimeout(bool is_absolute, const timespec* time, const timespec* start_time = nullptr, clockid_t clock_id = CLOCK_MONOTONIC_COARSE) - : m_clock_id(clock_id) - , m_infinite(!time) - { - if (!m_infinite) { - if (time->tv_sec > 0 || time->tv_nsec > 0) { - m_time = *time; - m_should_block = true; - } - m_start_time = start_time ? *start_time : TimeManagement::the().current_time(clock_id).value(); - if (!is_absolute) - timespec_add(m_time, m_start_time, m_time); - } - } + explicit BlockTimeout(bool is_absolute, const Time* time, const Time* start_time = nullptr, clockid_t clock_id = CLOCK_MONOTONIC_COARSE); - const timespec& absolute_time() const { return m_time; } - const timespec* start_time() const { return !m_infinite ? &m_start_time : nullptr; } + const Time& absolute_time() const { return m_time; } + const Time* start_time() const { return !m_infinite ? &m_start_time : nullptr; } clockid_t clock_id() const { return m_clock_id; } bool is_infinite() const { return m_infinite; } bool should_block() const { return m_infinite || m_should_block; }; private: - timespec m_time { 0, 0 }; - timespec m_start_time { 0, 0 }; + Time m_time {}; + Time m_start_time {}; clockid_t m_clock_id { CLOCK_MONOTONIC_COARSE }; bool m_infinite { false }; bool m_should_block { false }; @@ -640,7 +613,7 @@ public: class SleepBlocker final : public Blocker { public: - explicit SleepBlocker(const BlockTimeout&, timespec* = nullptr); + explicit SleepBlocker(const BlockTimeout&, Time* = nullptr); virtual const char* state_string() const override { return "Sleeping"; } virtual Type blocker_type() const override { return Type::Sleep; } virtual const BlockTimeout& override_timeout(const BlockTimeout&) override; @@ -652,7 +625,7 @@ public: void calculate_remaining(); BlockTimeout m_deadline; - timespec* m_remaining; + Time* m_remaining; }; class SelectBlocker final : public FileBlocker { @@ -955,13 +928,13 @@ public: return block<Thread::QueueBlocker>(timeout, wait_queue, forward<Args>(args)...); } - BlockResult sleep(clockid_t, const timespec&, timespec* = nullptr); - BlockResult sleep(const timespec& duration, timespec* remaining_time = nullptr) + BlockResult sleep(clockid_t, const Time&, Time* = nullptr); + BlockResult sleep(const Time& duration, Time* remaining_time = nullptr) { return sleep(CLOCK_MONOTONIC_COARSE, duration, remaining_time); } - BlockResult sleep_until(clockid_t, const timespec&); - BlockResult sleep_until(const timespec& duration) + BlockResult sleep_until(clockid_t, const Time&); + BlockResult sleep_until(const Time& duration) { return sleep_until(CLOCK_MONOTONIC_COARSE, duration); } diff --git a/Kernel/ThreadBlockers.cpp b/Kernel/ThreadBlockers.cpp index 3d56052c49..158dee8862 100644 --- a/Kernel/ThreadBlockers.cpp +++ b/Kernel/ThreadBlockers.cpp @@ -33,6 +33,22 @@ namespace Kernel { +Thread::BlockTimeout::BlockTimeout(bool is_absolute, const Time* time, const Time* start_time, clockid_t clock_id) + : m_clock_id(clock_id) + , m_infinite(!time) +{ + if (!m_infinite) { + if (*time > Time::zero()) { + m_time = *time; + m_should_block = true; + } + // FIXME: Should use AK::Time internally + m_start_time = start_time ? *start_time : Time::from_timespec(TimeManagement::the().current_time(clock_id).value()); + if (!is_absolute) + m_time = m_time + m_start_time; + } +} + bool Thread::Blocker::set_block_condition(Thread::BlockCondition& block_condition, void* data) { VERIFY(!m_block_condition); @@ -270,7 +286,9 @@ auto Thread::WriteBlocker::override_timeout(const BlockTimeout& timeout) -> cons if (description.is_socket()) { auto& socket = *description.socket(); if (socket.has_send_timeout()) { - m_timeout = BlockTimeout(false, &socket.send_timeout(), timeout.start_time(), timeout.clock_id()); + // FIXME: Should use AK::Time internally + Time send_timeout = Time::from_timeval(socket.send_timeout()); + m_timeout = BlockTimeout(false, &send_timeout, timeout.start_time(), timeout.clock_id()); if (timeout.is_infinite() || (!m_timeout.is_infinite() && m_timeout.absolute_time() < timeout.absolute_time())) return m_timeout; } @@ -289,7 +307,9 @@ auto Thread::ReadBlocker::override_timeout(const BlockTimeout& timeout) -> const if (description.is_socket()) { auto& socket = *description.socket(); if (socket.has_receive_timeout()) { - m_timeout = BlockTimeout(false, &socket.receive_timeout(), timeout.start_time(), timeout.clock_id()); + // FIXME: Should use AK::Time internally + Time receive_timeout = Time::from_timeval(socket.receive_timeout()); + m_timeout = BlockTimeout(false, &receive_timeout, timeout.start_time(), timeout.clock_id()); if (timeout.is_infinite() || (!m_timeout.is_infinite() && m_timeout.absolute_time() < timeout.absolute_time())) return m_timeout; } @@ -297,7 +317,7 @@ auto Thread::ReadBlocker::override_timeout(const BlockTimeout& timeout) -> const return timeout; } -Thread::SleepBlocker::SleepBlocker(const BlockTimeout& deadline, timespec* remaining) +Thread::SleepBlocker::SleepBlocker(const BlockTimeout& deadline, Time* remaining) : m_deadline(deadline) , m_remaining(remaining) { @@ -329,9 +349,10 @@ void Thread::SleepBlocker::calculate_remaining() { if (!m_remaining) return; - auto time_now = TimeManagement::the().current_time(m_deadline.clock_id()).value(); + // FIXME: Should use AK::Time internally + auto time_now = Time::from_timespec(TimeManagement::the().current_time(m_deadline.clock_id()).value()); if (time_now < m_deadline.absolute_time()) - timespec_sub(m_deadline.absolute_time(), time_now, *m_remaining); + *m_remaining = m_deadline.absolute_time() - time_now; else *m_remaining = {}; } diff --git a/Kernel/TimerQueue.cpp b/Kernel/TimerQueue.cpp index 3edd86f46b..fedba303f8 100644 --- a/Kernel/TimerQueue.cpp +++ b/Kernel/TimerQueue.cpp @@ -38,10 +38,9 @@ namespace Kernel { static AK::Singleton<TimerQueue> s_the; static SpinLock<u8> g_timerqueue_lock; -timespec Timer::remaining() const +Time Timer::remaining() const { - // FIXME: Should use AK::Time internally - return m_remaining.to_timespec(); + return m_remaining; } Time Timer::now(bool is_firing) const @@ -79,9 +78,10 @@ UNMAP_AFTER_INIT TimerQueue::TimerQueue() m_ticks_per_second = TimeManagement::the().ticks_per_second(); } -RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const timespec& deadline, Function<void()>&& callback) +RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const Time& deadline, Function<void()>&& callback) { - if (deadline <= TimeManagement::the().current_time(clock_id).value()) + // FIXME: Should use AK::Time internally + if (deadline <= Time::from_timespec(TimeManagement::the().current_time(clock_id).value())) return {}; // Because timer handlers can execute on any processor and there is @@ -89,7 +89,7 @@ RefPtr<Timer> TimerQueue::add_timer_without_id(clockid_t clock_id, const timespe // *must* be a RefPtr<Timer>. Otherwise calling cancel_timer() could // inadvertently cancel another timer that has been created between // returning from the timer handler and a call to cancel_timer(). - auto timer = adopt(*new Timer(clock_id, Time::from_timespec(deadline), move(callback))); + auto timer = adopt(*new Timer(clock_id, deadline, move(callback))); ScopedSpinLock lock(g_timerqueue_lock); timer->m_id = 0; // Don't generate a timer id diff --git a/Kernel/TimerQueue.h b/Kernel/TimerQueue.h index 9d8f87701d..ea3b3bf88e 100644 --- a/Kernel/TimerQueue.h +++ b/Kernel/TimerQueue.h @@ -55,7 +55,7 @@ public: VERIFY(!is_queued()); } - timespec remaining() const; + Time remaining() const; private: TimerId m_id; @@ -92,8 +92,7 @@ public: static TimerQueue& the(); TimerId add_timer(NonnullRefPtr<Timer>&&); - // FIXME: Should use AK::Time internally - RefPtr<Timer> add_timer_without_id(clockid_t, const timespec&, Function<void()>&&); + RefPtr<Timer> add_timer_without_id(clockid_t, const Time&, Function<void()>&&); TimerId add_timer(clockid_t, timeval& timeout, Function<void()>&& callback); bool cancel_timer(TimerId id); bool cancel_timer(Timer&); |