diff options
author | Raul E Rangel <rrangel@chromium.org> | 2021-09-13 14:24:55 -0600 |
---|---|---|
committer | Raul Rangel <rrangel@chromium.org> | 2021-10-05 22:39:16 +0000 |
commit | c842c59b3eb8f9df42779bf9bf8fdd2c4136319c (patch) | |
tree | bb99572c7ee9c1a6af75671add54acad13d89387 | |
parent | b2346a56f135924214761f55e6a3b9ff8056dee7 (diff) |
lib/thread: Switch to using CPU_INFO_V2
CPU_INFO_V2 changes the behavior of cpu_info(). There is now only 1
cpu_info struct per cpu. This means that we no longer need to allocate
it at the top of each threads stack.
We can now in theory remove the CONFIG_STACK_SIZE alignment on the
thread stack sizes. We can also in theory use threads in SMM if you are
feeling venturesome.
BUG=b:194391185, b:179699789
TEST=Perform reboot stress test on guybrush with COOP_MULTITASKING
enabled.
Signed-off-by: Raul E Rangel <rrangel@chromium.org>
Change-Id: I5e04d254a00db43714ec60ebed7c4aa90e23190a
Reviewed-on: https://review.coreboot.org/c/coreboot/+/57628
Tested-by: build bot (Jenkins) <no-reply@coreboot.org>
Reviewed-by: Eric Peers <epeers@google.com>
Reviewed-by: Karthik Ramasubramanian <kramasub@google.com>
-rw-r--r-- | src/Kconfig | 2 | ||||
-rw-r--r-- | src/lib/thread.c | 27 |
2 files changed, 6 insertions, 23 deletions
diff --git a/src/Kconfig b/src/Kconfig index 09bc22dad1..ea05215bdd 100644 --- a/src/Kconfig +++ b/src/Kconfig @@ -677,7 +677,7 @@ config TIMER_QUEUE config COOP_MULTITASKING def_bool n - depends on TIMER_QUEUE && ARCH_X86 + depends on TIMER_QUEUE && ARCH_X86 && CPU_INFO_V2 help Cooperative multitasking allows callbacks to be multiplexed on the main thread of ramstage. With this enabled it allows for multiple diff --git a/src/lib/thread.c b/src/lib/thread.c index 2ff09a50d5..ac8460c964 100644 --- a/src/lib/thread.c +++ b/src/lib/thread.c @@ -36,28 +36,17 @@ static struct thread all_threads[TOTAL_NUM_THREADS]; static struct thread *runnable_threads; static struct thread *free_threads; -static inline struct cpu_info *thread_cpu_info(const struct thread *t) -{ - return (void *)(t->stack_orig); -} - static inline int thread_can_yield(const struct thread *t) { return (t != NULL && t->can_yield > 0); } -/* Assumes current CPU info can switch. */ -static inline struct thread *cpu_info_to_thread(const struct cpu_info *ci) -{ - return ci->thread; -} - static inline struct thread *current_thread(void) { if (!initialized) return NULL; - return cpu_info_to_thread(cpu_info()); + return cpu_info()->thread; } static inline int thread_list_empty(struct thread **list) @@ -94,21 +83,12 @@ static inline struct thread *pop_runnable(void) static inline struct thread *get_free_thread(void) { struct thread *t; - struct cpu_info *ci; - struct cpu_info *new_ci; if (thread_list_empty(&free_threads)) return NULL; t = pop_thread(&free_threads); - ci = cpu_info(); - - /* Initialize the cpu_info structure on the new stack. */ - new_ci = thread_cpu_info(t); - *new_ci = *ci; - new_ci->thread = t; - /* Reset the current stack value to the original. */ t->stack_current = t->stack_orig; @@ -134,6 +114,7 @@ __noreturn static enum cb_err idle_thread(void *unused) static void schedule(struct thread *t) { struct thread *current = current_thread(); + struct cpu_info *ci = cpu_info(); /* If t is NULL need to find new runnable thread. */ if (t == NULL) { @@ -148,6 +129,8 @@ static void schedule(struct thread *t) if (t->handle) t->handle->state = THREAD_STARTED; + ci->thread = t; + switch_to_thread(t->stack_current, ¤t->stack_current); } @@ -279,7 +262,7 @@ static void threads_initialize(void) t->id = 0; t->can_yield = 1; - stack_top = &thread_stacks[CONFIG_STACK_SIZE] - sizeof(struct cpu_info); + stack_top = &thread_stacks[CONFIG_STACK_SIZE]; for (i = 1; i < TOTAL_NUM_THREADS; i++) { t = &all_threads[i]; t->stack_orig = (uintptr_t)stack_top; |