Skip to content

Eliminate memory allocations in the system call setup_queue #68

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Oct 14, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions docs/syscall.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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.
* `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.
23 changes: 5 additions & 18 deletions src/syscall_sdl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down