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 17 struct semaphore; 18 19 struct thread_list { 20 struct thread_list *next, *prev; 21 }; 22 23 /* 24 * Stack frame used by __switch_to, see thread_asm.S 25 */ 26 struct thread_stack { 27 int errno; 28 uint16_t rmsp, rmss; 29 uint32_t edi, esi, ebp, ebx; 30 void (*eip)(void); 31 }; 32 33 struct 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 44 struct 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 55 extern void (*sched_hook_func)(void); 56 57 void __thread_process_timeouts(void); 58 void __schedule(void); 59 void __switch_to(struct thread *); 60 void thread_yield(void); 61 62 extern struct thread *__current; 63 static inline struct thread *current(void) 64 { 65 return __current; 66 } 67 68 struct 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 82 mstime_t sem_down(struct semaphore *, mstime_t); 83 void sem_up(struct semaphore *); 84 void 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 */ 94 static 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 */ 103 static inline bool sem_is_valid(struct semaphore *sem) 104 { 105 return ((!!sem) && (!!sem->list.next)); 106 } 107 108 struct thread *start_thread(const char *name, size_t stack_size, int prio, 109 void (*start_func)(void *), void *func_arg); 110 void __exit_thread(void); 111 void kill_thread(struct thread *); 112 113 void start_idle_thread(void); 114 void test_thread(void); 115 116 #endif /* _THREAD_H */ 117