Kernel: Rework sleeping API
instead of sleep_{ns,ms} we now have sleep_{for,until}_{ns,ms}. This
makes code cleaner that just wants to sleep until some timestamp
This commit is contained in:
@@ -77,15 +77,21 @@ namespace Kernel
|
||||
|
||||
// blocks current thread and returns either on unblock, eintr, spuriously or after timeout
|
||||
// if mutex is not nullptr, it will be atomically freed before blocking and automatically locked on wake
|
||||
BAN::ErrorOr<void> sleep_or_eintr_ns(uint64_t ns);
|
||||
BAN::ErrorOr<void> sleep_or_eintr_for_ns(uint64_t timeout_ns);
|
||||
BAN::ErrorOr<void> sleep_or_eintr_until_ns(uint64_t waketime_ns);
|
||||
BAN::ErrorOr<void> block_or_eintr_indefinite(ThreadBlocker& thread_blocker, BaseMutex* mutex);
|
||||
BAN::ErrorOr<void> block_or_eintr_or_timeout_ns(ThreadBlocker& thread_blocker, uint64_t timeout_ns, bool etimedout, BaseMutex* mutex);
|
||||
BAN::ErrorOr<void> block_or_eintr_or_waketime_ns(ThreadBlocker& thread_blocker, uint64_t wake_time_ns, bool etimedout, BaseMutex* mutex);
|
||||
|
||||
BAN::ErrorOr<void> sleep_or_eintr_ms(uint64_t ms)
|
||||
BAN::ErrorOr<void> sleep_or_eintr_for_ms(uint64_t timeout_ms)
|
||||
{
|
||||
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(ms, 1'000'000));
|
||||
return sleep_or_eintr_ns(ms * 1'000'000);
|
||||
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000));
|
||||
return sleep_or_eintr_for_ns(timeout_ms * 1'000'000);
|
||||
}
|
||||
BAN::ErrorOr<void> sleep_or_eintr_until_ms(uint64_t waketime_ms)
|
||||
{
|
||||
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(waketime_ms, 1'000'000));
|
||||
return sleep_or_eintr_until_ns(waketime_ms * 1'000'000);
|
||||
}
|
||||
BAN::ErrorOr<void> block_or_eintr_or_timeout_ms(ThreadBlocker& thread_blocker, uint64_t timeout_ms, bool etimedout, BaseMutex* mutex)
|
||||
{
|
||||
|
||||
@@ -52,8 +52,19 @@ namespace Kernel
|
||||
virtual bool pre_scheduler_sleep_needs_lock() const override;
|
||||
virtual void pre_scheduler_sleep_ns(uint64_t) override;
|
||||
|
||||
void sleep_ms(uint64_t ms) const { ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(ms, 1'000'000)); return sleep_ns(ms * 1'000'000); }
|
||||
void sleep_ns(uint64_t ns) const;
|
||||
void sleep_for_ns(uint64_t timeout_ns) const;
|
||||
void sleep_until_ns(uint64_t waketime_ns) const;
|
||||
|
||||
void sleep_for_ms(uint64_t timeout_ms) const
|
||||
{
|
||||
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000));
|
||||
return sleep_for_ns(timeout_ms * 1'000'000);
|
||||
}
|
||||
void sleep_until_ms(uint64_t waketime_ms) const
|
||||
{
|
||||
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(waketime_ms, 1'000'000));
|
||||
return sleep_until_ns(waketime_ms * 1'000'000);
|
||||
}
|
||||
|
||||
void dont_invoke_scheduler() { m_timer->m_should_invoke_scheduler = false; }
|
||||
|
||||
|
||||
@@ -952,7 +952,7 @@ acpi_release_global_lock:
|
||||
{
|
||||
if (IO::inw(fadt().pm1a_cnt_blk) & PM1_CNT_SCI_EN)
|
||||
break;
|
||||
SystemTimer::get().sleep_ms(10);
|
||||
SystemTimer::get().sleep_for_ms(10);
|
||||
}
|
||||
|
||||
if (!(IO::inw(fadt().pm1a_cnt_blk) & PM1_CNT_SCI_EN))
|
||||
|
||||
@@ -2146,9 +2146,9 @@ namespace Kernel::ACPI::AML
|
||||
|
||||
auto milliseconds = TRY(convert_node(TRY(parse_node(context)), ConvInteger, sizeof(uint64_t)));
|
||||
|
||||
const uint64_t wakeup_ms = SystemTimer::get().ms_since_boot() + milliseconds.as.integer.value;
|
||||
for (uint64_t curr_ms = SystemTimer::get().ms_since_boot(); curr_ms < wakeup_ms; curr_ms = SystemTimer::get().ms_since_boot())
|
||||
SystemTimer::get().sleep_ms(wakeup_ms - curr_ms);
|
||||
const uint64_t waketime_ms = SystemTimer::get().ms_since_boot() + milliseconds.as.integer.value;
|
||||
while (SystemTimer::get().ms_since_boot() < waketime_ms)
|
||||
SystemTimer::get().sleep_until_ms(waketime_ms);
|
||||
|
||||
return {};
|
||||
}
|
||||
@@ -2392,7 +2392,7 @@ namespace Kernel::ACPI::AML
|
||||
result.type = Node::Type::Integer;
|
||||
result.as.integer.value = BAN::numeric_limits<uint64_t>::max();
|
||||
|
||||
const uint64_t wake_time_ms = (timeout_ms >= 0xFFFF)
|
||||
const uint64_t waketime_ms = (timeout_ms >= 0xFFFF)
|
||||
? BAN::numeric_limits<uint64_t>::max()
|
||||
: SystemTimer::get().ms_since_boot() + timeout_ms;
|
||||
|
||||
@@ -2401,9 +2401,9 @@ namespace Kernel::ACPI::AML
|
||||
{
|
||||
if (sync_object->node.as.mutex->mutex.try_lock())
|
||||
break;
|
||||
if (SystemTimer::get().ms_since_boot() >= wake_time_ms)
|
||||
if (SystemTimer::get().ms_since_boot() >= waketime_ms)
|
||||
return result;
|
||||
SystemTimer::get().sleep_ms(1);
|
||||
Processor::yield();
|
||||
}
|
||||
|
||||
if (sync_object->node.as.mutex->global_lock)
|
||||
|
||||
@@ -113,7 +113,7 @@ namespace Kernel
|
||||
// 4.3 The software must wait at least 521 us (25 frames) after reading CRST as a 1
|
||||
// before assuming that codecs have all made status change requests and have been
|
||||
// registered by the controller
|
||||
SystemTimer::get().sleep_ms(1);
|
||||
SystemTimer::get().sleep_for_ns(521'000);
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ namespace Kernel
|
||||
[](void* _devfs)
|
||||
{
|
||||
auto* devfs = static_cast<DevFileSystem*>(_devfs);
|
||||
uint64_t next_update_ms = SystemTimer::get().ms_since_boot();
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
@@ -57,7 +58,8 @@ namespace Kernel
|
||||
for (auto& device : devfs->m_devices)
|
||||
device->update();
|
||||
}
|
||||
SystemTimer::get().sleep_ms(10);
|
||||
SystemTimer::get().sleep_until_ms(next_update_ms);
|
||||
next_update_ms += 10;
|
||||
}
|
||||
}, s_instance
|
||||
));
|
||||
|
||||
@@ -157,7 +157,7 @@ namespace Kernel
|
||||
if (i == 4)
|
||||
dwarnln("Could not find specified root device, waiting for it to get loaded...");
|
||||
|
||||
SystemTimer::get().sleep_ms(sleep_ms);
|
||||
SystemTimer::get().sleep_for_ms(sleep_ms);
|
||||
}
|
||||
|
||||
derrorln("Could not find root device '{}' after {} ms", root_path, timeout_ms);
|
||||
|
||||
@@ -1048,7 +1048,7 @@ namespace Kernel
|
||||
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||
if (current_ms >= wake_time_ms)
|
||||
break;
|
||||
SystemTimer::get().sleep_ms(wake_time_ms - current_ms);
|
||||
SystemTimer::get().sleep_until_ms(wake_time_ms);
|
||||
}
|
||||
|
||||
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||
@@ -1070,7 +1070,7 @@ namespace Kernel
|
||||
return 0;
|
||||
|
||||
const uint64_t wake_time_ns = SystemTimer::get().ns_since_boot() + sleep_ns;
|
||||
SystemTimer::get().sleep_ns(sleep_ns);
|
||||
SystemTimer::get().sleep_until_ns(wake_time_ns);
|
||||
|
||||
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
||||
if (current_ns < wake_time_ns)
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Kernel
|
||||
|
||||
static void select_delay()
|
||||
{
|
||||
SystemTimer::get().sleep_ns(400);
|
||||
SystemTimer::get().sleep_for_ns(400);
|
||||
}
|
||||
|
||||
void ATABus::select_device(bool is_secondary)
|
||||
@@ -87,7 +87,7 @@ namespace Kernel
|
||||
io_write(ATA_PORT_LBA1, 0);
|
||||
io_write(ATA_PORT_LBA2, 0);
|
||||
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY);
|
||||
SystemTimer::get().sleep_ms(1);
|
||||
SystemTimer::get().sleep_for_ms(1);
|
||||
|
||||
// No device on port
|
||||
if (io_read(ATA_PORT_STATUS) == 0)
|
||||
@@ -112,7 +112,7 @@ namespace Kernel
|
||||
}
|
||||
|
||||
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY_PACKET);
|
||||
SystemTimer::get().sleep_ms(1);
|
||||
SystemTimer::get().sleep_for_ms(1);
|
||||
}
|
||||
|
||||
TRY(wait(true));
|
||||
|
||||
@@ -863,11 +863,21 @@ namespace Kernel
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Thread::sleep_or_eintr_ns(uint64_t ns)
|
||||
BAN::ErrorOr<void> Thread::sleep_or_eintr_for_ns(uint64_t timeout_ns)
|
||||
{
|
||||
if (is_interrupted_by_signal(true))
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
SystemTimer::get().sleep_ns(ns);
|
||||
SystemTimer::get().sleep_for_ns(timeout_ns);
|
||||
if (is_interrupted_by_signal(true))
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
return {};
|
||||
}
|
||||
|
||||
BAN::ErrorOr<void> Thread::sleep_or_eintr_until_ns(uint64_t waketime_ns)
|
||||
{
|
||||
if (is_interrupted_by_signal(true))
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
SystemTimer::get().sleep_until_ns(waketime_ns);
|
||||
if (is_interrupted_by_signal(true))
|
||||
return BAN::Error::from_errno(EINTR);
|
||||
return {};
|
||||
|
||||
@@ -229,11 +229,18 @@ namespace Kernel
|
||||
return m_timer->pre_scheduler_sleep_ns(ns);
|
||||
}
|
||||
|
||||
void SystemTimer::sleep_ns(uint64_t ns) const
|
||||
void SystemTimer::sleep_for_ns(uint64_t timeout_ns) const
|
||||
{
|
||||
if (ns == 0)
|
||||
const uint64_t base_ns = ns_since_boot();
|
||||
ASSERT(!BAN::Math::will_addition_overflow(base_ns, timeout_ns));
|
||||
Processor::scheduler().block_current_thread(nullptr, base_ns + timeout_ns, nullptr);
|
||||
}
|
||||
|
||||
void SystemTimer::sleep_until_ns(uint64_t waketime_ns) const
|
||||
{
|
||||
if (ns_since_boot() >= waketime_ns)
|
||||
return;
|
||||
Processor::scheduler().block_current_thread(nullptr, ns_since_boot() + ns, nullptr);
|
||||
Processor::scheduler().block_current_thread(nullptr, waketime_ns, nullptr);
|
||||
}
|
||||
|
||||
timespec SystemTimer::real_time() const
|
||||
|
||||
Reference in New Issue
Block a user