From 1631f286c9820bf4ac7ec3b6ad1bae93127de5ff Mon Sep 17 00:00:00 2001 From: Alan Jian Date: Fri, 14 Oct 2022 10:44:53 +0800 Subject: [PATCH] Eliminate memory allocations in the system call `setup_queue` Because the emulator lacks an address translation mechanism and is unable to allocate variables within the process's memory space, This commit grants the user the ability to create queues by passing an additional parameter to the system call that specifies the base address of queues. --- docs/syscall.md | 6 +++--- src/syscall_sdl.c | 23 +++++------------------ 2 files changed, 8 insertions(+), 21 deletions(-) diff --git a/docs/syscall.md b/docs/syscall.md index 0c33d7a5..6e5472a9 100644 --- a/docs/syscall.md +++ b/docs/syscall.md @@ -31,9 +31,9 @@ If a window does not already exist, one will be created with the specified `widt **system call number**: `0xC0DE` -**synopsis**: `void *setup_queue(int capacity, unsigned int* event_count)` +**synopsis**: `void *setup_queue(void *base, int capacity, unsigned int *event_count)` -Allocate a continuous memory chunk that has the requested capacity and two closely packed queues, the event queue and the submission queue. The base address of the event queue is located in the returned address, and the submission queue is immediately after the event queue's last element, which is the event queue's base address plus the size of each event element times the given capacity. The capacity must be a power of 2; if it is not, it will be rounded up to the next highest power of 2. It is crucial to initialize the event counter variable before supplying its address to this system call because it serves as an interaction to the user that an event has been added to the event queue. +The user must pass a continuous memory chunk that contains two tightly packed queues, the event queue and the submission queue. And the submission queue is immediately following the last element of the event queue, which is the event queue's base address plus the size of each event element multiplied by the given capacity. If the capacity is not a power of two, it will be treated as the rounded value of the next highest power of two. Additionally, because the event counter variable serves as a notifier to the user that an event has been added to the event queue, it is critical to initialize it before passing its address to this system call. #### Events @@ -55,4 +55,4 @@ To inform the emulator that a batch of submissions should be processed, the appl The submission entry is structured similarly to an event entry, with a 32-bit type field and an associated dynamic-sized value buffer whose width depends on the type of submission. -* `RELATIVE_MODE_SUBMISSION`: Enable or disable the mouse relative mode. If the mouse relative mode is enabled, the mouse cursor is wrapped within the window border, it's associated with an 8-bit wide boolean value that indicates whether the relative mouse mode should be enbled. \ No newline at end of file +* `RELATIVE_MODE_SUBMISSION`: Enable or disable the mouse relative mode. If the mouse relative mode is enabled, the mouse cursor is wrapped within the window border, it's associated with an 8-bit wide boolean value that indicates whether the relative mouse mode should be enbled. diff --git a/src/syscall_sdl.c b/src/syscall_sdl.c index 631cdb91..f49fcb05 100644 --- a/src/syscall_sdl.c +++ b/src/syscall_sdl.c @@ -234,27 +234,14 @@ void syscall_draw_frame(struct riscv_t *rv) void syscall_setup_queue(struct riscv_t *rv) { - /* setup_queue(capacity, event_count) */ - queues_capacity = rv_get_reg(rv, rv_reg_a0); - event_count = rv_get_reg(rv, rv_reg_a1); + /* setup_queue(base, capacity, event_count) */ + void *base = (void *) (uintptr_t) rv_get_reg(rv, rv_reg_a0); + queues_capacity = rv_get_reg(rv, rv_reg_a1); + event_count = rv_get_reg(rv, rv_reg_a2); - queues_capacity = round_pow2(queues_capacity); - if (queues_capacity == 0) { - rv_set_reg(rv, rv_reg_a0, 0); - return; - } - - /* FIXME: Allocate a memory chunk in the emulator's address space so that - * the user can access it */ - void *base = malloc(sizeof(event_t) * queues_capacity + - sizeof(submission_t) * queues_capacity); event_queue.base = base; submission_queue.base = base + sizeof(event_t) * queues_capacity; - - rv_set_reg( - rv, rv_reg_a0, - (uint32_t) (uintptr_t) base); /* eliminate the "cast from pointer to - integer of different size" warning*/ + queues_capacity = round_pow2(queues_capacity); } void syscall_submit_queue(struct riscv_t *rv)