[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Minios-devel] [UNIKRAFT PATCH 8/8] lib/ukschedcoop: Fix race condition when trying to wake up current thread
The previous patch introduced a race condition: if the current thread blocks and yields, and an interrupt is triggered whose handle tries to wake up the current thread then the thread will remain blocked until the next interrupt (potentially forever) because the current thread cannot be added to the ready threads list. The solution is to set a flag on the current thread as soon as the next thread is scheduled. The interrupt will queue the current thread if and only if this flag is set. Signed-off-by: Costin Lupu <costin.lupu@xxxxxxxxx> --- lib/uksched/include/uk/thread.h | 5 +++++ lib/ukschedcoop/schedcoop.c | 7 ++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/uksched/include/uk/thread.h b/lib/uksched/include/uk/thread.h index 71e39225..10fd4a33 100644 --- a/lib/uksched/include/uk/thread.h +++ b/lib/uksched/include/uk/thread.h @@ -96,6 +96,7 @@ struct uk_thread *uk_thread_current(void) #define RUNNABLE_FLAG 0x00000001 #define EXITED_FLAG 0x00000002 +#define QUEUEABLE_FLAG 0x00000004 #define is_runnable(_thread) ((_thread)->flags & RUNNABLE_FLAG) #define set_runnable(_thread) ((_thread)->flags |= RUNNABLE_FLAG) @@ -104,6 +105,10 @@ struct uk_thread *uk_thread_current(void) #define is_exited(_thread) ((_thread)->flags & EXITED_FLAG) #define set_exited(_thread) ((_thread)->flags |= EXITED_FLAG) +#define is_queueable(_thread) ((_thread)->flags & QUEUEABLE_FLAG) +#define set_queueable(_thread) ((_thread)->flags |= QUEUEABLE_FLAG) +#define clear_queueable(_thread) ((_thread)->flags &= ~QUEUEABLE_FLAG) + int uk_thread_init(struct uk_thread *thread, struct ukplat_ctx_callbacks *cbs, struct uk_alloc *allocator, const char *name, void *stack, diff --git a/lib/ukschedcoop/schedcoop.c b/lib/ukschedcoop/schedcoop.c index 90559052..7aa411c7 100644 --- a/lib/ukschedcoop/schedcoop.c +++ b/lib/ukschedcoop/schedcoop.c @@ -109,6 +109,9 @@ static void schedcoop_schedule(struct uk_sched *s) else if (prev->wakeup_time > 0) UK_TAILQ_INSERT_TAIL(&prv->sleeping_threads, prev, thread_list); + else + set_queueable(prev); + clear_queueable(next); ukplat_stack_set_current_thread(next); break; } else if (is_runnable(prev)) { @@ -204,8 +207,10 @@ static void schedcoop_thread_woken(struct uk_sched *s, struct uk_thread *t) if (t->wakeup_time > 0) UK_TAILQ_REMOVE(&prv->sleeping_threads, t, thread_list); - if (t != uk_thread_current()) + if (t != uk_thread_current() || is_queueable(t)) { UK_TAILQ_INSERT_TAIL(&prv->thread_list, t, thread_list); + clear_queueable(t); + } } static void idle_thread_fn(void *unused __unused) -- 2.11.0 _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |