|
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.
|