#include #include #include #include #include #include #include #include namespace kapi::interrupts { namespace { auto constinit handlers = kstd::flat_map>>>{}; } // namespace auto register_handler(std::uint32_t irq_number, handler & handler, kstd::weak_ptr context) -> void { if (handlers.contains(irq_number)) { auto & handler_list = handlers.at(irq_number); handler_list.push_back(std::pair{&handler, context}); } else { handlers.emplace(irq_number, kstd::vector{ std::pair{&handler, context} }); } } auto unregister_handler(std::uint32_t irq_number, handler & handler) -> void { auto & handler_list = handlers.at(irq_number); auto [first, last] = std::ranges::remove_if(handler_list, [&](auto const & entry) { return entry.first == &handler; }); handler_list.erase(first, last); } auto dispatch(std::uint32_t irq_number) -> status { if (!handlers.contains(irq_number)) { kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); return status::unhandled; } auto & handler_list = handlers.at(irq_number); if (handler_list.empty()) { kstd::println(kstd::print_sink::stderr, "[OS:interrupts] No handler for IRQ{}", irq_number); return status::unhandled; } for (auto const & [handler, context] : handler_list) { if (handler && handler->handle_interrupt(irq_number, context) == status::handled) { return status::handled; } } return status::unhandled; } } // namespace kapi::interrupts