From 4b28e4626e744ac9b779a680f8e9647014956dda Mon Sep 17 00:00:00 2001 From: Felix Morgner Date: Sun, 26 Jul 2026 21:46:37 +0200 Subject: kapi/devices: implement locking discipline --- kernel/kapi/devices/bus.stress.cpp | 76 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 76 insertions(+) create mode 100644 kernel/kapi/devices/bus.stress.cpp (limited to 'kernel/kapi/devices/bus.stress.cpp') diff --git a/kernel/kapi/devices/bus.stress.cpp b/kernel/kapi/devices/bus.stress.cpp new file mode 100644 index 00000000..226b0296 --- /dev/null +++ b/kernel/kapi/devices/bus.stress.cpp @@ -0,0 +1,76 @@ +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +namespace +{ + + struct test_device final : kapi::devices::device + { + using kapi::devices::device::device; + }; + +} // namespace + +constexpr auto thread_count = 32; +constexpr auto devices_per_thread = 200; + +SCENARIO("Concurrent attach/detach/lookup on a bus is race-free") +{ + GIVEN("A bus shared by several threads") + { + auto shared_bus = kstd::make_shared("stress_test_bus"); + kapi::devices::get_root_bus()->add_child(shared_bus); + + WHEN("each thread repeatedly attaches, detaches, and looks up devices concurrently with the others") + { + auto threads = std::vector{}; + threads.reserve(thread_count); + + auto failure_count = std::atomic{0}; + + for (auto thread_index = 0uz; thread_index < thread_count; ++thread_index) + { + threads.emplace_back([&shared_bus, &failure_count, thread_index] { + for (auto i = 0uz; i < devices_per_thread; ++i) + { + auto name = kstd::format("stress_test_device_{}_{}", thread_index, i); + auto device = kstd::make_shared(name); + + shared_bus->add_child(device); + + std::ignore = kapi::devices::device_registry::get().find(name); + std::ignore = kapi::devices::device_registry::get().all(); + std::ignore = shared_bus->children().size(); + + if (!shared_bus->remove_child(*device)) + { + ++failure_count; + }; + } + }); + } + + threads.clear(); + + THEN("every attach was matched by a successful removal") + { + REQUIRE(failure_count == 0); + } + + THEN("the bus has no children") + { + REQUIRE(shared_bus->children().empty()); + } + } + } +} \ No newline at end of file -- cgit v1.2.3