From deb45a8bb2dca771427c3a6243de2d09c414f92d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=87a=C4=9Fatay=20G=C3=BC=C3=A7l=C3=BC?= <33038942+defektu@users.noreply.github.com> Date: Sun, 4 Oct 2026 20:34:28 +0400 Subject: [PATCH] kernel: use the AMPR filter for APR completion events --- src/kernel/eventQueue.cpp | 4 ++-- src/kernel/eventQueue.h | 1 + src/libs/libAmpr.cpp | 5 +++-- tests/KernelFileSystemTests.cpp | 40 +++++++++++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 4 deletions(-) diff --git a/src/kernel/eventQueue.cpp b/src/kernel/eventQueue.cpp index 010a1f07..afb84722 100644 --- a/src/kernel/eventQueue.cpp +++ b/src/kernel/eventQueue.cpp @@ -564,7 +564,7 @@ int KYTY_SYSV_ABI KernelAddAmprEvent(KernelEqueue eq, int id, void* udata) { if (eq != KERNEL_EQUEUE_INVALID) { KernelEqueueEvent event {}; event.event.ident = static_cast(id); - event.event.filter = KERNEL_EVFILT_USER; + event.event.filter = KERNEL_EVFILT_AMPR; event.event.flags = EV_ADD | EV_CLEAR; event.event.fflags = 0; event.event.data = 0; @@ -592,7 +592,7 @@ int KYTY_SYSV_ABI KernelDeleteAmprEvent(KernelEqueue eq, int id) { LOGF("\t AMPR event delete: eq = 0x%016" PRIx64 ", id = %d\n", static_cast(eq), id); if (eq != KERNEL_EQUEUE_INVALID) { - (void)KernelDeleteEvent(eq, static_cast(id), KERNEL_EVFILT_USER); + (void)KernelDeleteEvent(eq, static_cast(id), KERNEL_EVFILT_AMPR); } return OK; diff --git a/src/kernel/eventQueue.h b/src/kernel/eventQueue.h index ca724cd7..911d6ea0 100644 --- a/src/kernel/eventQueue.h +++ b/src/kernel/eventQueue.h @@ -18,6 +18,7 @@ constexpr int16_t KERNEL_EVFILT_FILE = -4; constexpr int16_t KERNEL_EVFILT_GRAPHICS = -14; constexpr int16_t KERNEL_EVFILT_VIDEO_OUT = -13; constexpr int16_t KERNEL_EVFILT_HRTIMER = -15; +constexpr int16_t KERNEL_EVFILT_AMPR = -25; class KernelEqueuePrivate; struct KernelEqueueEvent; diff --git a/src/libs/libAmpr.cpp b/src/libs/libAmpr.cpp index 2412cfce..dfdc1730 100644 --- a/src/libs/libAmpr.cpp +++ b/src/libs/libAmpr.cpp @@ -1193,8 +1193,9 @@ static int ExecuteCommand(const CommandBufferState::Command& entry) { std::get_if(&entry.data)) { const auto& command = *payload; const auto eq = static_cast(command.eq); - auto result = LibKernel::EventQueue::KernelTriggerUserEvent( - eq, command.id, reinterpret_cast(command.data)); + auto result = LibKernel::EventQueue::KernelTriggerEvent( + eq, static_cast(command.id), LibKernel::EventQueue::KERNEL_EVFILT_AMPR, + reinterpret_cast(command.data)); if (result != OK) { LOGF("\tAPR submit event failed: eq=0x%016" PRIx64 ", id=%" PRId32 ", result=0x%08" PRIx32 "\n", diff --git a/tests/KernelFileSystemTests.cpp b/tests/KernelFileSystemTests.cpp index 201c3996..83ceadec 100644 --- a/tests/KernelFileSystemTests.cpp +++ b/tests/KernelFileSystemTests.cpp @@ -10,6 +10,7 @@ #include "common/threads.h" #include "common/stringUtils.h" #include "graphics/presentation/window/windowInternal.h" +#include "kernel/eventQueue.h" #include "kernel/fileSystem.h" #include "libs/errno.h" #include "libs/network.h" @@ -640,6 +641,8 @@ void CheckAmprOrdering(Loader::SymbolDatabase &symbols, uint32_t file_id) { using WriteAddress = int (KYTY_SYSV_ABI *)(void *, volatile uint64_t *, uint64_t); using ReadFile = int (KYTY_SYSV_ABI *)(void *, uint64_t, uint64_t, uint32_t, void *, uint64_t, uint64_t); + using WriteKernelEvent = int (KYTY_SYSV_ABI *)(void *, uint64_t, uint64_t, uint64_t, + uint64_t, uint64_t); struct Result { int32_t result; uint32_t error_offset; }; using SubmitApr = int (KYTY_SYSV_ABI *)(void *, uint32_t, Result *, uint32_t *); using SubmitAmm = int (KYTY_SYSV_ABI *)(void *, uint32_t, uint32_t, uint32_t *); @@ -653,6 +656,7 @@ void CheckAmprOrdering(Loader::SymbolDatabase &symbols, uint32_t file_id) { const auto wait_address = reinterpret_cast(find("DLfoNxTFNVk")); const auto write_address = reinterpret_cast(find("sJXyWHjP-F8")); const auto read_file = reinterpret_cast(find("mQ16-QdKv7k")); + const auto write_event = reinterpret_cast(find("H896Pt-yB4I")); const auto submit_apr = reinterpret_cast(find("ASoW5WE-UPo")); const auto submit_amm = reinterpret_cast(find("NnKhlMJtIsI")); const auto wait_apr = reinterpret_cast(find("rqwFKI4PAiM")); @@ -723,6 +727,42 @@ void CheckAmprOrdering(Loader::SymbolDatabase &symbols, uint32_t file_id) { "submission wait observes the completed result"); } } + reset(1); + namespace EventQueue = Libs::LibKernel::EventQueue; + EventQueue::KernelEqueue queue = EventQueue::KERNEL_EQUEUE_INVALID; + uint64_t ampr_user_data = 1, user_data = 2; + Check(EventQueue::KernelCreateEqueue(&queue, "apr-completion") == OK && + EventQueue::KernelAddAmprEvent(queue, 42, &r_user_data) == OK && + EventQueue::KernelAddUserEventEdge(queue, 42) == OK, + "AMPR and user events can share an identifier"); + std::array output {}; + Result event_result {1234, 5678}; + uint32_t event_submission = 0; + auto *reader = buffers[0].header.data(); + Check(read_file(reader, reinterpret_cast(&buffers[0].header[3]), + reinterpret_cast(&buffers[0].header[4]), file_id, + output.data(), output.size(), 0) == OK && + write_event(reader, queue, 42, 0x123456789abc, 0, 0) == OK && + submit_apr(reader, 3, &event_result, &event_submission) == OK && + wait_apr(event_submission) == OK && event_result.result == OK, + "APR read submits its completion event"); + std::array events {}; + int event_count = 0; + const Libs::LibKernel::KernelUseconds poll = 0; + Check(EventQueue::KernelWaitEqueue(queue, events.data(), 2, &event_count, &poll) == OK && + event_count == 1 && events[0].ident == 42 && events[0].filter == -25 && + events[0].data == 0x123456789abc && events[0].udata == &r_user_data && + std::memcmp(output.data(), "APR", 3) == 0, + "APR completion reports the AMPR filter, payload and registration user data"); + Check(EventQueue::KernelDeleteAmprEvent(queue, 42) == OK && + EventQueue::KernelTriggerEvent(queue, 42, -25, nullptr) == + Libs::LibKernel::KERNEL_ERROR_ENOENT && + EventQueue::KernelTriggerUserEvent(queue, 42, &user_data) == OK && + EventQueue::KernelWaitEqueue(queue, events.data(), 2, &event_count, &poll) == OK && + event_count == 1 && events[0].filter == EventQueue::KERNEL_EVFILT_USER && + events[0].udata == &user_data, + "deleting AMPR leaves the user event with the same identifier intact"); + Check(EventQueue::KernelDeleteEqueue(queue) == OK, "delete APR completion queue"); reset(0); uint64_t cpu_fence = 0, amm_done = 0, lower_done = 0; std::array ids {};