thread.h
1 /* SPDX-License-Identifier: GPL-2.0-only */ 2 #ifndef THREAD_H_ 3 #define THREAD_H_ 4 5 #include <arch/cpu.h> 6 #include <bootstate.h> 7 #include <types.h> 8 9 struct thread_mutex { 10 bool locked; 11 }; 12 13 enum thread_state { 14 THREAD_UNINITIALIZED, 15 THREAD_STARTED, 16 THREAD_DONE, 17 }; 18 19 struct thread_handle { 20 enum thread_state state; 21 /* Only valid when state == THREAD_DONE */ 22 enum cb_err error; 23 }; 24 25 /* Run func(arg) on a new thread. Return 0 on successful start of thread, < 0 26 * when thread could not be started. The thread handle if populated, will 27 * reflect the state and return code of the thread. 28 */ 29 int thread_run(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg); 30 31 /* thread_run_until is the same as thread_run() except that it blocks state 32 * transitions from occurring in the (state, seq) pair of the boot state 33 * machine. */ 34 int thread_run_until(struct thread_handle *handle, enum cb_err (*func)(void *), void *arg, 35 boot_state_t state, boot_state_sequence_t seq); 36 37 /* Waits until the thread has terminated and returns the error code */ 38 enum cb_err thread_join(struct thread_handle *handle); 39 40 #if ENV_SUPPORTS_COOP 41 42 struct thread { 43 int id; 44 uintptr_t stack_current; 45 uintptr_t stack_orig; 46 struct thread *next; 47 enum cb_err (*entry)(void *); 48 void *entry_arg; 49 int can_yield; 50 struct thread_handle *handle; 51 }; 52 53 /* Return 0 on successful yield, < 0 when thread did not yield. */ 54 int thread_yield(void); 55 56 /* Return 0 on successful yield for the given amount of time, < 0 when thread 57 * did not yield. */ 58 int thread_yield_microseconds(unsigned int microsecs); 59 60 /* Allow and prevent thread cooperation on current running thread. By default 61 * all threads are marked to be cooperative. That means a thread can yield 62 * to another thread at a pre-determined switch point. i.e., udelay, 63 * thread_yield, or thread_yield_microseconds. 64 * 65 * These methods should be used to guard critical sections so a dead lock does 66 * not occur. The critical sections can be nested. Just make sure the methods 67 * are used in pairs. 68 */ 69 void thread_coop_enable(void); 70 void thread_coop_disable(void); 71 72 void thread_mutex_lock(struct thread_mutex *mutex); 73 void thread_mutex_unlock(struct thread_mutex *mutex); 74 75 /* Architecture specific thread functions. */ 76 asmlinkage void switch_to_thread(uintptr_t new_stack, uintptr_t *saved_stack); 77 /* Set up the stack frame for a new thread so that a switch_to_thread() call 78 * will enter the thread_entry() function with arg as a parameter. The 79 * saved_stack field in the struct thread needs to be updated accordingly. */ 80 void arch_prepare_thread(struct thread *t, 81 asmlinkage void (*thread_entry)(void *), void *arg); 82 #else 83 static inline int thread_yield(void) 84 { 85 return -1; 86 } 87 static inline int thread_yield_microseconds(unsigned int microsecs) 88 { 89 return -1; 90 } 91 static inline void thread_coop_enable(void) {} 92 static inline void thread_coop_disable(void) {} 93 94 static inline void thread_mutex_lock(struct thread_mutex *mutex) {} 95 96 static inline void thread_mutex_unlock(struct thread_mutex *mutex) {} 97 #endif 98 99 #endif /* THREAD_H_ */