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
|
// 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
|
// 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_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_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> 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));
|
ASSERT(!BAN::Math::will_multiplication_overflow<uint64_t>(timeout_ms, 1'000'000));
|
||||||
return sleep_or_eintr_ns(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)
|
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 bool pre_scheduler_sleep_needs_lock() const override;
|
||||||
virtual void pre_scheduler_sleep_ns(uint64_t) 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_for_ns(uint64_t timeout_ns) const;
|
||||||
void sleep_ns(uint64_t 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; }
|
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)
|
if (IO::inw(fadt().pm1a_cnt_blk) & PM1_CNT_SCI_EN)
|
||||||
break;
|
break;
|
||||||
SystemTimer::get().sleep_ms(10);
|
SystemTimer::get().sleep_for_ms(10);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(IO::inw(fadt().pm1a_cnt_blk) & PM1_CNT_SCI_EN))
|
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)));
|
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;
|
const uint64_t waketime_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())
|
while (SystemTimer::get().ms_since_boot() < waketime_ms)
|
||||||
SystemTimer::get().sleep_ms(wakeup_ms - curr_ms);
|
SystemTimer::get().sleep_until_ms(waketime_ms);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
@@ -2392,7 +2392,7 @@ namespace Kernel::ACPI::AML
|
|||||||
result.type = Node::Type::Integer;
|
result.type = Node::Type::Integer;
|
||||||
result.as.integer.value = BAN::numeric_limits<uint64_t>::max();
|
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()
|
? BAN::numeric_limits<uint64_t>::max()
|
||||||
: SystemTimer::get().ms_since_boot() + timeout_ms;
|
: SystemTimer::get().ms_since_boot() + timeout_ms;
|
||||||
|
|
||||||
@@ -2401,9 +2401,9 @@ namespace Kernel::ACPI::AML
|
|||||||
{
|
{
|
||||||
if (sync_object->node.as.mutex->mutex.try_lock())
|
if (sync_object->node.as.mutex->mutex.try_lock())
|
||||||
break;
|
break;
|
||||||
if (SystemTimer::get().ms_since_boot() >= wake_time_ms)
|
if (SystemTimer::get().ms_since_boot() >= waketime_ms)
|
||||||
return result;
|
return result;
|
||||||
SystemTimer::get().sleep_ms(1);
|
Processor::yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sync_object->node.as.mutex->global_lock)
|
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
|
// 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
|
// before assuming that codecs have all made status change requests and have been
|
||||||
// registered by the controller
|
// registered by the controller
|
||||||
SystemTimer::get().sleep_ms(1);
|
SystemTimer::get().sleep_for_ns(521'000);
|
||||||
|
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -50,6 +50,7 @@ namespace Kernel
|
|||||||
[](void* _devfs)
|
[](void* _devfs)
|
||||||
{
|
{
|
||||||
auto* devfs = static_cast<DevFileSystem*>(_devfs);
|
auto* devfs = static_cast<DevFileSystem*>(_devfs);
|
||||||
|
uint64_t next_update_ms = SystemTimer::get().ms_since_boot();
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
{
|
{
|
||||||
@@ -57,7 +58,8 @@ namespace Kernel
|
|||||||
for (auto& device : devfs->m_devices)
|
for (auto& device : devfs->m_devices)
|
||||||
device->update();
|
device->update();
|
||||||
}
|
}
|
||||||
SystemTimer::get().sleep_ms(10);
|
SystemTimer::get().sleep_until_ms(next_update_ms);
|
||||||
|
next_update_ms += 10;
|
||||||
}
|
}
|
||||||
}, s_instance
|
}, s_instance
|
||||||
));
|
));
|
||||||
|
|||||||
@@ -157,7 +157,7 @@ namespace Kernel
|
|||||||
if (i == 4)
|
if (i == 4)
|
||||||
dwarnln("Could not find specified root device, waiting for it to get loaded...");
|
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);
|
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();
|
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||||
if (current_ms >= wake_time_ms)
|
if (current_ms >= wake_time_ms)
|
||||||
break;
|
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();
|
const uint64_t current_ms = SystemTimer::get().ms_since_boot();
|
||||||
@@ -1070,7 +1070,7 @@ namespace Kernel
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
const uint64_t wake_time_ns = SystemTimer::get().ns_since_boot() + sleep_ns;
|
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();
|
const uint64_t current_ns = SystemTimer::get().ns_since_boot();
|
||||||
if (current_ns < wake_time_ns)
|
if (current_ns < wake_time_ns)
|
||||||
|
|||||||
@@ -66,7 +66,7 @@ namespace Kernel
|
|||||||
|
|
||||||
static void select_delay()
|
static void select_delay()
|
||||||
{
|
{
|
||||||
SystemTimer::get().sleep_ns(400);
|
SystemTimer::get().sleep_for_ns(400);
|
||||||
}
|
}
|
||||||
|
|
||||||
void ATABus::select_device(bool is_secondary)
|
void ATABus::select_device(bool is_secondary)
|
||||||
@@ -87,7 +87,7 @@ namespace Kernel
|
|||||||
io_write(ATA_PORT_LBA1, 0);
|
io_write(ATA_PORT_LBA1, 0);
|
||||||
io_write(ATA_PORT_LBA2, 0);
|
io_write(ATA_PORT_LBA2, 0);
|
||||||
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY);
|
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY);
|
||||||
SystemTimer::get().sleep_ms(1);
|
SystemTimer::get().sleep_for_ms(1);
|
||||||
|
|
||||||
// No device on port
|
// No device on port
|
||||||
if (io_read(ATA_PORT_STATUS) == 0)
|
if (io_read(ATA_PORT_STATUS) == 0)
|
||||||
@@ -112,7 +112,7 @@ namespace Kernel
|
|||||||
}
|
}
|
||||||
|
|
||||||
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY_PACKET);
|
io_write(ATA_PORT_COMMAND, ATA_COMMAND_IDENTIFY_PACKET);
|
||||||
SystemTimer::get().sleep_ms(1);
|
SystemTimer::get().sleep_for_ms(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRY(wait(true));
|
TRY(wait(true));
|
||||||
|
|||||||
@@ -863,11 +863,21 @@ namespace Kernel
|
|||||||
return {};
|
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))
|
if (is_interrupted_by_signal(true))
|
||||||
return BAN::Error::from_errno(EINTR);
|
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))
|
if (is_interrupted_by_signal(true))
|
||||||
return BAN::Error::from_errno(EINTR);
|
return BAN::Error::from_errno(EINTR);
|
||||||
return {};
|
return {};
|
||||||
|
|||||||
@@ -229,11 +229,18 @@ namespace Kernel
|
|||||||
return m_timer->pre_scheduler_sleep_ns(ns);
|
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;
|
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
|
timespec SystemTimer::real_time() const
|
||||||
|
|||||||
Reference in New Issue
Block a user