From e99eb52d9923606dd325862a5f2e649eee0b2d3e Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Fri, 24 Jul 2026 17:50:16 +0200 Subject: kapi: formally extract device registry --- kernel/kapi/devices/bus.cpp | 2 +- kernel/kapi/devices/device_registry.cpp | 106 ++++++++++++++++++++++++++ kernel/kapi/devices/driver.tests.cpp | 4 +- kernel/kapi/devices/driver_registry.cpp | 4 +- kernel/kapi/devices/driver_registry.tests.cpp | 8 +- 5 files changed, 115 insertions(+), 9 deletions(-) create mode 100644 kernel/kapi/devices/device_registry.cpp (limited to 'kernel/kapi/devices') diff --git a/kernel/kapi/devices/bus.cpp b/kernel/kapi/devices/bus.cpp index db693eac..1b3ad4bf 100644 --- a/kernel/kapi/devices/bus.cpp +++ b/kernel/kapi/devices/bus.cpp @@ -21,7 +21,7 @@ namespace kapi::devices { child->set_parent(kstd::static_pointer_cast(shared_from_this())); - if (!kapi::devices::register_device(child)) + if (!kapi::devices::device_registry::get().add(child)) { kapi::system::panic("[OS:DEV] Failed to register child device {}", child->name()); } diff --git a/kernel/kapi/devices/device_registry.cpp b/kernel/kapi/devices/device_registry.cpp new file mode 100644 index 00000000..aca0e7fe --- /dev/null +++ b/kernel/kapi/devices/device_registry.cpp @@ -0,0 +1,106 @@ +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include + +namespace kapi::devices +{ + + namespace + { + auto constinit instance = std::optional{}; + } + + auto device_registry::init() -> void + { + if (instance) + { + system::panic("[OS:DEV] Device registry has already been initialized"); + } + + instance = device_registry{}; + } + + auto device_registry::get() -> device_registry & + { + if (!instance) + { + system::panic("[OS:DEV] Device registry has not been initialized"); + } + + return *instance; + } + + auto device_registry::add(kstd::shared_ptr device) -> bool + { + if (!device) + { + return false; + } + + kstd::println("[OS:DEV] Registering device {}", device->name()); + + auto found = m_devices.find(device->name()); + if (found != m_devices.end()) + { + if (!found->second.expired()) + { + return false; + } + + found->second = device; + return true; + } + + return m_devices.emplace(device->name(), device).second; + } + + auto device_registry::remove(device &) -> bool + { + kstd::println("[OS:DEV] TODO: implement device deregistration"); + return false; + } + + auto device_registry::find(std::string_view name) const -> kstd::shared_ptr + { + auto found = m_devices.find(kstd::string{name}); + if (found == m_devices.end()) + { + return nullptr; + } + + return found->second.lock(); + } + + auto device_registry::all() const -> kstd::vector> + { + auto result = kstd::vector>{}; + + for (auto const & [name, weak_device] : m_devices) + { + if (auto device = weak_device.lock()) + { + result.push_back(std::move(device)); + } + } + + return result; + } +} // namespace kapi::devices + +namespace kapi::test_support::devices +{ + auto deinit_device_registry() -> void + { + kapi::devices::instance.reset(); + } +} // namespace kapi::test_support::devices \ No newline at end of file diff --git a/kernel/kapi/devices/driver.tests.cpp b/kernel/kapi/devices/driver.tests.cpp index abce92d2..53c569dd 100644 --- a/kernel/kapi/devices/driver.tests.cpp +++ b/kernel/kapi/devices/driver.tests.cpp @@ -213,14 +213,14 @@ SCENARIO("a bound controller driver can attach a further, independently-typed bu THEN("the controller device bound the controller driver") { - auto controller = kapi::devices::find_device("stacking_test_controller"); + auto controller = kapi::devices::device_registry::get().find("stacking_test_controller"); REQUIRE(controller != nullptr); REQUIRE(controller->state() == kapi::devices::state::bound); } THEN("the leaf device the controller driver attached is reachable and bound to the leaf driver") { - auto leaf = kapi::devices::find_device("stacking_test_leaf"); + auto leaf = kapi::devices::device_registry::get().find("stacking_test_leaf"); REQUIRE(leaf != nullptr); REQUIRE(leaf->state() == kapi::devices::state::bound); REQUIRE(leaf->bound_driver() != nullptr); diff --git a/kernel/kapi/devices/driver_registry.cpp b/kernel/kapi/devices/driver_registry.cpp index 67da9877..5784694a 100644 --- a/kernel/kapi/devices/driver_registry.cpp +++ b/kernel/kapi/devices/driver_registry.cpp @@ -3,8 +3,8 @@ #include #include #include +#include #include -#include #include #include @@ -57,7 +57,7 @@ namespace kapi::devices { m_drivers.emplace_back(std::move(driver)); - for (auto const & device : kapi::devices::all()) + for (auto const & device : kapi::devices::device_registry::get().all()) { if (device->state() != state::bound) { diff --git a/kernel/kapi/devices/driver_registry.tests.cpp b/kernel/kapi/devices/driver_registry.tests.cpp index 52f320f4..bf87fb47 100644 --- a/kernel/kapi/devices/driver_registry.tests.cpp +++ b/kernel/kapi/devices/driver_registry.tests.cpp @@ -131,7 +131,7 @@ SCENARIO("Driver registry binds devices and drivers regardless of arrival order" THEN("the device binds") { - auto dev = kapi::devices::find_device("driver_registry_test_device_1"); + auto dev = kapi::devices::device_registry::get().find("driver_registry_test_device_1"); REQUIRE(dev); REQUIRE(dev->state() == kapi::devices::state::bound); } @@ -144,7 +144,7 @@ SCENARIO("Driver registry binds devices and drivers regardless of arrival order" THEN("the device binds") { - auto dev = kapi::devices::find_device("driver_registry_test_device_2"); + auto dev = kapi::devices::device_registry::get().find("driver_registry_test_device_2"); REQUIRE(dev); REQUIRE(dev->state() == kapi::devices::state::bound); } @@ -169,7 +169,7 @@ SCENARIO("driver_registry picks the highest-priority match", "[devices][driver_r THEN("it binds to the higher-priority driver") { - auto dev = kapi::devices::find_device("driver_registry_priority_device"); + auto dev = kapi::devices::device_registry::get().find("driver_registry_priority_device"); REQUIRE(dev != nullptr); REQUIRE(dev->bound_driver() == high_priority.get()); } @@ -194,7 +194,7 @@ SCENARIO("driver_registry breaks ties by registration order", "[devices][driver_ THEN("the first-registered driver wins the tie") { - auto dev = kapi::devices::find_device("driver_registry_tie_device"); + auto dev = kapi::devices::device_registry::get().find("driver_registry_tie_device"); REQUIRE(dev != nullptr); REQUIRE(dev->bound_driver() == registered_first.get()); } -- cgit v1.2.3