diff options
Diffstat (limited to 'kernel/kapi/interrupts.tests.cpp')
| -rw-r--r-- | kernel/kapi/interrupts.tests.cpp | 189 |
1 files changed, 189 insertions, 0 deletions
diff --git a/kernel/kapi/interrupts.tests.cpp b/kernel/kapi/interrupts.tests.cpp new file mode 100644 index 00000000..e87c6a00 --- /dev/null +++ b/kernel/kapi/interrupts.tests.cpp @@ -0,0 +1,189 @@ +#include <kapi/interrupts.hpp> + +#include <kapi/tracked_mutex.hpp> + +#include <kstd/mutex.hpp> + +#include <catch2/catch_test_macros.hpp> + +SCENARIO("irq_lock semantics", "[kapi][interrupts]") +{ + GIVEN("a simple irq_lock") + { + auto lock = kapi::interrupts::irq_lock{}; + + AND_GIVEN("IRQs are currently disabled") + { + kapi::interrupts::enabled(false); + REQUIRE_FALSE(kapi::interrupts::enabled()); + + WHEN("locking the irq_lock") + { + lock.lock(); + + THEN("IRQs are still disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + + AND_WHEN("unlocking the irq_lock") + { + lock.unlock(); + + THEN("IRQs are still disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + } + } + } + + THEN("the irq_lock is locked") + { + REQUIRE_FALSE(lock.try_lock()); + lock.unlock(); + } + } + + THEN("the irq_lock can be locked") + { + REQUIRE(lock.try_lock()); + lock.unlock(); + } + } + + AND_GIVEN("IRQs are currently enabled") + { + kapi::interrupts::enabled(true); + REQUIRE(kapi::interrupts::enabled()); + + WHEN("locking the irq_lock") + { + lock.lock(); + + THEN("IRQs are disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + + AND_WHEN("unlocking the irq_lock") + { + lock.unlock(); + + THEN("IRQs are enabled again") + { + REQUIRE(kapi::interrupts::enabled()); + } + } + } + } + } + } + + GIVEN("a wrapping irq_lock") + { + auto mutex = kapi::tracked_mutex{}; + auto lock = kapi::interrupts::irq_lock{mutex}; + + AND_GIVEN("IRQs are currently disabled") + { + kapi::interrupts::enabled(false); + REQUIRE_FALSE(kapi::interrupts::enabled()); + + WHEN("locking the irq_lock") + { + lock.lock(); + + THEN("IRQs are still disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + + AND_WHEN("unlocking the irq_lock") + { + lock.unlock(); + + THEN("IRQs are still disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + } + + THEN("the inner mutex is unlocked") + { + REQUIRE(mutex.try_lock()); + mutex.unlock(); + } + } + } + + THEN("the irq_lock is locked") + { + REQUIRE_FALSE(lock.try_lock()); + lock.unlock(); + } + + THEN("the inner mutex is locked") + { + REQUIRE_FALSE(mutex.try_lock()); + lock.unlock(); + } + } + + THEN("the irq_lock can be locked") + { + REQUIRE(lock.try_lock()); + lock.unlock(); + } + } + + AND_GIVEN("IRQs are currently enabled") + { + kapi::interrupts::enabled(true); + REQUIRE(kapi::interrupts::enabled()); + + WHEN("locking the irq_lock") + { + lock.lock(); + + THEN("IRQs are disabled") + { + REQUIRE_FALSE(kapi::interrupts::enabled()); + + AND_WHEN("unlocking the irq_lock") + { + lock.unlock(); + + THEN("IRQs are enabled again") + { + REQUIRE(kapi::interrupts::enabled()); + } + + THEN("the inner mutex is unlocked") + { + REQUIRE(mutex.try_lock()); + mutex.unlock(); + } + } + } + + THEN("the irq_lock is locked") + { + REQUIRE_FALSE(lock.try_lock()); + lock.unlock(); + } + + THEN("the inner mutex is locked") + { + REQUIRE_FALSE(mutex.try_lock()); + lock.unlock(); + } + } + } + + AND_GIVEN("the inner mutex is already locked") + { + auto guard = kstd::lock_guard{mutex}; + + THEN("the irq_lock cannot be locked") + { + REQUIRE_FALSE(lock.try_lock()); + } + } + } +}
\ No newline at end of file |
