1#ifndef _THREAD_H 2#define _THREAD_H 3 4#include <stddef.h> 5#include <inttypes.h> 6#include <limits.h> 7#include <stdbool.h> 8#include <timer.h> 9#include <sys/cpu.h> 10 11/* The idle thread runs at this priority */ 12#define IDLE_THREAD_PRIORITY INT_MAX 13 14/* This priority should normally be used for hardware-polling threads */ 15#define POLL_THREAD_PRIORITY (INT_MAX-1) 16 17struct semaphore; 18 19struct thread_list { 20 struct thread_list *next, *prev; 21}; 22 23/* 24 * Stack frame used by __switch_to, see thread_asm.S 25 */ 26struct thread_stack { 27 int errno; 28 uint16_t rmsp, rmss; 29 uint32_t edi, esi, ebp, ebx; 30 void (*eip)(void); 31}; 32 33struct thread_block { 34 struct thread_list list; 35 struct thread *thread; 36 struct semaphore *semaphore; 37 mstime_t block_time; 38 mstime_t timeout; 39 bool timed_out; 40}; 41 42#define THREAD_MAGIC 0x3568eb7d 43 44struct thread { 45 struct thread_stack *esp; /* Must be first; stack pointer */ 46 unsigned int thread_magic; 47 const char *name; /* Name (for debugging) */ 48 struct thread_list list; 49 struct thread_block *blocked; 50 void *stack, *rmstack; /* Stacks, iff allocated by malloc/lmalloc */ 51 void *pvt; /* For the benefit of lwIP */ 52 int prio; 53}; 54 55extern void (*sched_hook_func)(void); 56 57void __thread_process_timeouts(void); 58void __schedule(void); 59void __switch_to(struct thread *); 60void thread_yield(void); 61 62extern struct thread *__current; 63static inline struct thread *current(void) 64{ 65 return __current; 66} 67 68struct semaphore { 69 int count; 70 struct thread_list list; 71}; 72 73#define DECLARE_INIT_SEMAPHORE(sem, cnt) \ 74 struct semaphore sem = { \ 75 .count = (cnt), \ 76 .list = { \ 77 .next = &sem.list, \ 78 .prev = &sem.list \ 79 } \ 80 } 81 82mstime_t sem_down(struct semaphore *, mstime_t); 83void sem_up(struct semaphore *); 84void sem_init(struct semaphore *, int); 85 86/* 87 * This marks a semaphore object as unusable; it will remain unusable 88 * until sem_init() is called on it again. This DOES NOT clear the 89 * list of blocked processes on this semaphore! 90 * 91 * It is also possible to mark the semaphore invalid by zeroing its 92 * memory structure. 93 */ 94static inline void sem_set_invalid(struct semaphore *sem) 95{ 96 if (!!sem) 97 sem->list.next = NULL; 98} 99 100/* 101 * Ask if a semaphore object has been initialized. 102 */ 103static inline bool sem_is_valid(struct semaphore *sem) 104{ 105 return ((!!sem) && (!!sem->list.next)); 106} 107 108struct thread *start_thread(const char *name, size_t stack_size, int prio, 109 void (*start_func)(void *), void *func_arg); 110void __exit_thread(void); 111void kill_thread(struct thread *); 112 113void start_idle_thread(void); 114void test_thread(void); 115 116#endif /* _THREAD_H */ 117