kernel: use the AMPR filter for APR completion events

This commit is contained in:
Çağatay Güçlü
2026-10-04 20:34:28 +04:00
committed by nmzik
parent fdac55a5ef
commit deb45a8bb2
4 changed files with 46 additions and 4 deletions
+2 -2
View File
@@ -564,7 +564,7 @@ int KYTY_SYSV_ABI KernelAddAmprEvent(KernelEqueue eq, int id, void* udata) {
if (eq != KERNEL_EQUEUE_INVALID) { if (eq != KERNEL_EQUEUE_INVALID) {
KernelEqueueEvent event {}; KernelEqueueEvent event {};
event.event.ident = static_cast<uintptr_t>(id); event.event.ident = static_cast<uintptr_t>(id);
event.event.filter = KERNEL_EVFILT_USER; event.event.filter = KERNEL_EVFILT_AMPR;
event.event.flags = EV_ADD | EV_CLEAR; event.event.flags = EV_ADD | EV_CLEAR;
event.event.fflags = 0; event.event.fflags = 0;
event.event.data = 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<uint64_t>(eq), id); LOGF("\t AMPR event delete: eq = 0x%016" PRIx64 ", id = %d\n", static_cast<uint64_t>(eq), id);
if (eq != KERNEL_EQUEUE_INVALID) { if (eq != KERNEL_EQUEUE_INVALID) {
(void)KernelDeleteEvent(eq, static_cast<uintptr_t>(id), KERNEL_EVFILT_USER); (void)KernelDeleteEvent(eq, static_cast<uintptr_t>(id), KERNEL_EVFILT_AMPR);
} }
return OK; return OK;
+1
View File
@@ -18,6 +18,7 @@ constexpr int16_t KERNEL_EVFILT_FILE = -4;
constexpr int16_t KERNEL_EVFILT_GRAPHICS = -14; constexpr int16_t KERNEL_EVFILT_GRAPHICS = -14;
constexpr int16_t KERNEL_EVFILT_VIDEO_OUT = -13; constexpr int16_t KERNEL_EVFILT_VIDEO_OUT = -13;
constexpr int16_t KERNEL_EVFILT_HRTIMER = -15; constexpr int16_t KERNEL_EVFILT_HRTIMER = -15;
constexpr int16_t KERNEL_EVFILT_AMPR = -25;
class KernelEqueuePrivate; class KernelEqueuePrivate;
struct KernelEqueueEvent; struct KernelEqueueEvent;
+3 -2
View File
@@ -1193,8 +1193,9 @@ static int ExecuteCommand(const CommandBufferState::Command& entry) {
std::get_if<CommandBufferState::KernelEventCommand>(&entry.data)) { std::get_if<CommandBufferState::KernelEventCommand>(&entry.data)) {
const auto& command = *payload; const auto& command = *payload;
const auto eq = static_cast<LibKernel::EventQueue::KernelEqueue>(command.eq); const auto eq = static_cast<LibKernel::EventQueue::KernelEqueue>(command.eq);
auto result = LibKernel::EventQueue::KernelTriggerUserEvent( auto result = LibKernel::EventQueue::KernelTriggerEvent(
eq, command.id, reinterpret_cast<void*>(command.data)); eq, static_cast<uintptr_t>(command.id), LibKernel::EventQueue::KERNEL_EVFILT_AMPR,
reinterpret_cast<void*>(command.data));
if (result != OK) { if (result != OK) {
LOGF("\tAPR submit event failed: eq=0x%016" PRIx64 ", id=%" PRId32 LOGF("\tAPR submit event failed: eq=0x%016" PRIx64 ", id=%" PRId32
", result=0x%08" PRIx32 "\n", ", result=0x%08" PRIx32 "\n",
+40
View File
@@ -10,6 +10,7 @@
#include "common/threads.h" #include "common/threads.h"
#include "common/stringUtils.h" #include "common/stringUtils.h"
#include "graphics/presentation/window/windowInternal.h" #include "graphics/presentation/window/windowInternal.h"
#include "kernel/eventQueue.h"
#include "kernel/fileSystem.h" #include "kernel/fileSystem.h"
#include "libs/errno.h" #include "libs/errno.h"
#include "libs/network.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 WriteAddress = int (KYTY_SYSV_ABI *)(void *, volatile uint64_t *, uint64_t);
using ReadFile = int (KYTY_SYSV_ABI *)(void *, uint64_t, uint64_t, uint32_t, using ReadFile = int (KYTY_SYSV_ABI *)(void *, uint64_t, uint64_t, uint32_t,
void *, uint64_t, uint64_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; }; struct Result { int32_t result; uint32_t error_offset; };
using SubmitApr = int (KYTY_SYSV_ABI *)(void *, uint32_t, Result *, uint32_t *); 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 *); 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<WaitAddress>(find("DLfoNxTFNVk")); const auto wait_address = reinterpret_cast<WaitAddress>(find("DLfoNxTFNVk"));
const auto write_address = reinterpret_cast<WriteAddress>(find("sJXyWHjP-F8")); const auto write_address = reinterpret_cast<WriteAddress>(find("sJXyWHjP-F8"));
const auto read_file = reinterpret_cast<ReadFile>(find("mQ16-QdKv7k")); const auto read_file = reinterpret_cast<ReadFile>(find("mQ16-QdKv7k"));
const auto write_event = reinterpret_cast<WriteKernelEvent>(find("H896Pt-yB4I"));
const auto submit_apr = reinterpret_cast<SubmitApr>(find("ASoW5WE-UPo")); const auto submit_apr = reinterpret_cast<SubmitApr>(find("ASoW5WE-UPo"));
const auto submit_amm = reinterpret_cast<SubmitAmm>(find("NnKhlMJtIsI")); const auto submit_amm = reinterpret_cast<SubmitAmm>(find("NnKhlMJtIsI"));
const auto wait_apr = reinterpret_cast<WaitSubmission>(find("rqwFKI4PAiM")); const auto wait_apr = reinterpret_cast<WaitSubmission>(find("rqwFKI4PAiM"));
@@ -723,6 +727,42 @@ void CheckAmprOrdering(Loader::SymbolDatabase &symbols, uint32_t file_id) {
"submission wait observes the completed result"); "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, &ampr_user_data) == OK &&
EventQueue::KernelAddUserEventEdge(queue, 42) == OK,
"AMPR and user events can share an identifier");
std::array<char, 3> output {};
Result event_result {1234, 5678};
uint32_t event_submission = 0;
auto *reader = buffers[0].header.data();
Check(read_file(reader, reinterpret_cast<uint64_t>(&buffers[0].header[3]),
reinterpret_cast<uint64_t>(&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<EventQueue::KernelEvent, 2> 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 == &ampr_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); reset(0);
uint64_t cpu_fence = 0, amm_done = 0, lower_done = 0; uint64_t cpu_fence = 0, amm_done = 0, lower_done = 0;
std::array<uint32_t, 2> ids {}; std::array<uint32_t, 2> ids {};