diff options
| author | Felix Morgner <felix.morgner@ost.ch> | 2026-07-24 17:50:16 +0200 |
|---|---|---|
| committer | Felix Morgner <felix.morgner@ost.ch> | 2026-07-24 17:50:16 +0200 |
| commit | e99eb52d9923606dd325862a5f2e649eee0b2d3e (patch) | |
| tree | e3a15138bfec8a630d02f0f858bb9f000c6da3f8 /kernel/kapi/devices | |
| parent | aa25bfac399e32efda039eb833b2c4d74f1edba0 (diff) | |
| download | kernel-e99eb52d9923606dd325862a5f2e649eee0b2d3e.tar.xz kernel-e99eb52d9923606dd325862a5f2e649eee0b2d3e.zip | |
kapi: formally extract device registry
Diffstat (limited to 'kernel/kapi/devices')
| -rw-r--r-- | kernel/kapi/devices/bus.cpp | 2 | ||||
| -rw-r--r-- | kernel/kapi/devices/device_registry.cpp | 106 | ||||
| -rw-r--r-- | kernel/kapi/devices/driver.tests.cpp | 4 | ||||
| -rw-r--r-- | kernel/kapi/devices/driver_registry.cpp | 4 | ||||
| -rw-r--r-- | kernel/kapi/devices/driver_registry.tests.cpp | 8 |
5 files changed, 115 insertions, 9 deletions
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<bus>(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 <kapi/devices/device_registry.hpp> + +#include <kapi/devices/device.hpp> +#include <kapi/system.hpp> + +#include <kstd/memory.hpp> +#include <kstd/print.hpp> +#include <kstd/string.hpp> +#include <kstd/vector.hpp> + +#include <optional> +#include <string_view> +#include <utility> + +namespace kapi::devices +{ + + namespace + { + auto constinit instance = std::optional<device_registry>{}; + } + + 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> 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<device> + { + 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<kstd::shared_ptr<device>> + { + auto result = kstd::vector<kstd::shared_ptr<device>>{}; + + 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 <kapi/devices/bus.hpp> #include <kapi/devices/bus_protocol.hpp> #include <kapi/devices/device.hpp> +#include <kapi/devices/device_registry.hpp> #include <kapi/devices/driver.hpp> -#include <kapi/devices/manager.hpp> #include <kapi/system.hpp> #include <kapi/test_support/devices.hpp> @@ -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()); } |
