From b29f9d471bade1cf6d5e0994af7ccf722ac65ef0 Mon Sep 17 00:00:00 2001 From: Raul E Rangel Date: Mon, 12 Jul 2021 13:49:59 -0600 Subject: [PATCH] lib/thread: Add mutex We need a way to protect shared resources. Since we are using cooperative multitasking the mutex implementation is pretty trivial. BUG=b:179699789 TEST=Verify thread lock and unlock. Signed-off-by: Raul E Rangel Change-Id: Ife1ac95ec064ebcdd00fcaacec37a06ac52885ff Reviewed-on: https://review.coreboot.org/c/coreboot/+/56230 Reviewed-by: Karthik Ramasubramanian Reviewed-by: Furquan Shaikh Reviewed-by: Julius Werner Tested-by: build bot (Jenkins) --- src/include/thread.h | 11 +++++++++++ src/lib/thread.c | 20 ++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/include/thread.h b/src/include/thread.h index 293a666dbd..4bc04db00a 100644 --- a/src/include/thread.h +++ b/src/include/thread.h @@ -6,6 +6,10 @@ #include #include +struct thread_mutex { + bool locked; +}; + #if ENV_RAMSTAGE && CONFIG(COOP_MULTITASKING) struct thread { @@ -53,6 +57,9 @@ int thread_yield_microseconds(unsigned int microsecs); void thread_coop_enable(void); void thread_coop_disable(void); +void thread_mutex_lock(struct thread_mutex *mutex); +void thread_mutex_unlock(struct thread_mutex *mutex); + static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci) { ci->thread = NULL; @@ -85,6 +92,10 @@ static inline void thread_coop_enable(void) {} static inline void thread_coop_disable(void) {} struct cpu_info; static inline void thread_init_cpu_info_non_bsp(struct cpu_info *ci) { } + +static inline void thread_mutex_lock(struct thread_mutex *mutex) {} + +static inline void thread_mutex_unlock(struct thread_mutex *mutex) {} #endif #endif /* THREAD_H_ */ diff --git a/src/lib/thread.c b/src/lib/thread.c index 47a23acd96..e62c5d7239 100644 --- a/src/lib/thread.c +++ b/src/lib/thread.c @@ -1,5 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ +#include #include #include #include @@ -377,3 +378,22 @@ void thread_coop_disable(void) current->can_yield--; } + +void thread_mutex_lock(struct thread_mutex *mutex) +{ + struct stopwatch sw; + + stopwatch_init(&sw); + + while (mutex->locked) + assert(thread_yield() == 0); + mutex->locked = true; + + printk(BIOS_SPEW, "took %lu us to acquire mutex\n", stopwatch_duration_usecs(&sw)); +} + +void thread_mutex_unlock(struct thread_mutex *mutex) +{ + assert(mutex->locked); + mutex->locked = 0; +}