From: falcovorbis <fal...@us...> - 2024-04-21 08:04:05
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "A pseudo Operating System for the Dreamcast.". The branch, master has been updated via f7a14e260dc6dfa55eec1f417b2c661101732773 (commit) via 5145efaaf5f6b816a0bb2bb69a81405b4ecdc5d2 (commit) from c1410a93e38ab6f80efcb9400b47c8451d490d13 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit f7a14e260dc6dfa55eec1f417b2c661101732773 Author: Paul Cercueil <pa...@cr...> Date: Sun Apr 21 10:03:27 2024 +0200 maple: Fix race between IRQ and threads (#517) The IRQ handler and threads would read-modify-write the state->queue_len field as if races didn't exist. Address this issue by using atomics instead. Note that the code in the IRQ handler is using atomic routines as well just to be future-proof, as it may very well be called from a threaded interrupt handler in the future. This has the added benefit that it also tells GCC that the 'queue_len' may be updated outside the visible scope, and therefore its value may change at any moment. This fixes the code not working properly when building with LTO. Signed-off-by: Paul Cercueil <pa...@cr...> ----------------------------------------------------------------------- Summary of changes: .gitignore | 2 ++ kernel/arch/dreamcast/hardware/maple/keyboard.c | 8 ++++---- kernel/arch/dreamcast/include/dc/maple/keyboard.h | 4 +++- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index bfc7f1f1..9d351605 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,8 @@ examples/dreamcast/kgl/basic/vq/fruit.vq examples/dreamcast/conio/adventure/data.c examples/dreamcast/conio/adventure/datagen examples/dreamcast/png/romdisk_boot.img +examples/dreamcast/pvr/bumpmap/romdisk/bricks.kmg +examples/dreamcast/pvr/bumpmap/romdisk/bumpmap.raw examples/dreamcast/pvr/modifier_volume_tex/romdisk/fruit.kmg examples/dreamcast/pvr/texture_render/texture_render.bin utils/dc-chain/logs diff --git a/kernel/arch/dreamcast/hardware/maple/keyboard.c b/kernel/arch/dreamcast/hardware/maple/keyboard.c index cc5dbe4f..9137ecc8 100644 --- a/kernel/arch/dreamcast/hardware/maple/keyboard.c +++ b/kernel/arch/dreamcast/hardware/maple/keyboard.c @@ -410,10 +410,10 @@ static int kbd_enqueue(kbd_state_t *state, uint8 keycode, int mods) { return 0; /* Queue the key up on the device-specific queue. */ - if(state->queue_len < KBD_QUEUE_SIZE) { + if(atomic_load(&state->queue_len) < KBD_QUEUE_SIZE) { state->key_queue[state->queue_head] = keycode | (mods << 8); state->queue_head = (state->queue_head + 1) & (KBD_QUEUE_SIZE - 1); - ++state->queue_len; + atomic_fetch_add(&state->queue_len, 1); } /* If queueing is turned off, don't bother with the global queue. */ @@ -463,12 +463,12 @@ int kbd_queue_pop(maple_device_t *dev, int xlat) { uint32 rv, mods; uint8 ascii; - if(!state->queue_len) + if(!atomic_load(&state->queue_len)) return -1; rv = state->key_queue[state->queue_tail]; state->queue_tail = (state->queue_tail + 1) & (KBD_QUEUE_SIZE - 1); - --state->queue_len; + atomic_fetch_sub(&state->queue_len, 1); if(!xlat) return (int)rv; diff --git a/kernel/arch/dreamcast/include/dc/maple/keyboard.h b/kernel/arch/dreamcast/include/dc/maple/keyboard.h index 51be9173..56d1567e 100644 --- a/kernel/arch/dreamcast/include/dc/maple/keyboard.h +++ b/kernel/arch/dreamcast/include/dc/maple/keyboard.h @@ -28,6 +28,8 @@ __BEGIN_DECLS #include <arch/types.h> #include <dc/maple.h> +#include <stdatomic.h> + /** \defgroup kbd Keyboard \brief Driver for the Dreamcast's Keyboard Input Device \ingroup peripherals @@ -297,7 +299,7 @@ typedef struct kbd_state { uint32 key_queue[KBD_QUEUE_SIZE]; int queue_tail; /**< \brief Key queue tail. */ int queue_head; /**< \brief Key queue head. */ - int queue_len; /**< \brief Current length of queue. */ + atomic_int queue_len; /**< \brief Current length of queue. */ uint8 kbd_repeat_key; /**< \brief Key that is repeating. */ uint64 kbd_repeat_timer; /**< \brief Time that the next repeat will trigger. */ hooks/post-receive -- A pseudo Operating System for the Dreamcast. |