#ifndef _THREAD_H #define _THREAD_H #include <stddef.h> #include <inttypes.h> #include <limits.h> #include <stdbool.h> #include <timer.h> #include <sys/cpu.h> /* The idle thread runs at this priority */ #define IDLE_THREAD_PRIORITY INT_MAX /* This priority should normally be used for hardware-polling threads */ #define POLL_THREAD_PRIORITY (INT_MAX-1) struct semaphore; struct thread_list { struct thread_list *next, *prev; }; /* * Stack frame used by __switch_to, see thread_asm.S */ struct thread_stack { int errno; uint16_t rmsp, rmss; uint32_t edi, esi, ebp, ebx; void (*eip)(void); }; struct thread_block { struct thread_list list; struct thread *thread; struct semaphore *semaphore; mstime_t block_time; mstime_t timeout; bool timed_out; }; #define THREAD_MAGIC 0x3568eb7d struct thread { struct thread_stack *esp; /* Must be first; stack pointer */ unsigned int thread_magic; const char *name; /* Name (for debugging) */ struct thread_list list; struct thread_block *blocked; void *stack, *rmstack; /* Stacks, iff allocated by malloc/lmalloc */ void *pvt; /* For the benefit of lwIP */ int prio; }; extern void (*sched_hook_func)(void); void __thread_process_timeouts(void); void __schedule(void); void __switch_to(struct thread *); void thread_yield(void); extern struct thread *__current; static inline struct thread *current(void) { return __current; } struct semaphore { int count; struct thread_list list; }; #define DECLARE_INIT_SEMAPHORE(sem, cnt) \ struct semaphore sem = { \ .count = (cnt), \ .list = { \ .next = &sem.list, \ .prev = &sem.list \ } \ } mstime_t sem_down(struct semaphore *, mstime_t); void sem_up(struct semaphore *); void sem_init(struct semaphore *, int); /* * This marks a semaphore object as unusable; it will remain unusable * until sem_init() is called on it again. This DOES NOT clear the * list of blocked processes on this semaphore! * * It is also possible to mark the semaphore invalid by zeroing its * memory structure. */ static inline void sem_set_invalid(struct semaphore *sem) { if (!!sem) sem->list.next = NULL; } /* * Ask if a semaphore object has been initialized. */ static inline bool sem_is_valid(struct semaphore *sem) { return ((!!sem) && (!!sem->list.next)); } struct thread *start_thread(const char *name, size_t stack_size, int prio, void (*start_func)(void *), void *func_arg); void __exit_thread(void); void kill_thread(struct thread *); void start_idle_thread(void); void test_thread(void); #endif /* _THREAD_H */