From d7049b57d59bf2036f8a09b03f0a06deb2c660f5 Mon Sep 17 00:00:00 2001 From: Peter Bigot Date: Tue, 16 Mar 2021 10:50:49 -0500 Subject: [PATCH] samples: microbit: pong: update work API usage Use the reschedule solution as there may be cases where a newer deadline should supersede an older one. The implementation has no locking and so has data races between the handler and external events. Emit a console diagnostic in one case where the race can be detected. Signed-off-by: Peter Bigot --- samples/boards/bbc_microbit/pong/src/main.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/samples/boards/bbc_microbit/pong/src/main.c b/samples/boards/bbc_microbit/pong/src/main.c index 58d797f0531b..87af15347367 100644 --- a/samples/boards/bbc_microbit/pong/src/main.c +++ b/samples/boards/bbc_microbit/pong/src/main.c @@ -90,7 +90,7 @@ static bool remote_lost; static bool started; static int64_t ended; -static struct k_delayed_work refresh; +static struct k_work_delayable refresh; /* Semaphore to indicate that there was an update to the display */ static K_SEM_DEFINE(disp_update, 0, 1); @@ -262,7 +262,7 @@ static void check_start(void) started = true; remote_lost = false; - k_delayed_work_submit(&refresh, K_NO_WAIT); + k_work_reschedule(&refresh, K_NO_WAIT); } static void game_ended(bool won) @@ -297,7 +297,7 @@ static void game_ended(bool won) printk("You lost!\n"); } - k_delayed_work_submit(&refresh, K_MSEC(RESTART_THRESHOLD)); + k_work_reschedule(&refresh, K_MSEC(RESTART_THRESHOLD)); } static void game_stack_dump(const struct k_thread *thread, void *user_data) @@ -376,7 +376,7 @@ static void game_refresh(struct k_work *work) sound_set(SOUND_PADDLE); } - k_delayed_work_submit(&refresh, GAME_REFRESH); + k_work_reschedule(&refresh, GAME_REFRESH); k_sem_give(&disp_update); } @@ -389,7 +389,7 @@ void pong_ball_received(int8_t x_pos, int8_t y_pos, int8_t x_vel, int8_t y_vel) ball_vel.x = x_vel; ball_vel.y = y_vel; - k_delayed_work_submit(&refresh, K_NO_WAIT); + k_work_reschedule(&refresh, K_NO_WAIT); } static void button_pressed(const struct device *dev, struct gpio_callback *cb, @@ -411,7 +411,12 @@ static void button_pressed(const struct device *dev, struct gpio_callback *cb, } if (ended && (k_uptime_get() - ended) > RESTART_THRESHOLD) { - k_delayed_work_cancel(&refresh); + int busy = k_work_cancel_delayable(&refresh); + + if (busy != 0) { + printk("WARNING: Data-race (work and event)\n"); + } + game_init(state == SINGLE || remote_lost); k_sem_give(&disp_update); return; @@ -473,7 +478,7 @@ void pong_conn_ready(bool initiator) void pong_remote_disconnected(void) { state = INIT; - k_delayed_work_submit(&refresh, K_SECONDS(1)); + k_work_reschedule(&refresh, K_SECONDS(1)); } void pong_remote_lost(void) @@ -513,7 +518,7 @@ void main(void) configure_buttons(); - k_delayed_work_init(&refresh, game_refresh); + k_work_init_delayable(&refresh, game_refresh); pwm = device_get_binding(DT_LABEL(DT_INST(0, nordic_nrf_sw_pwm)));