Home | History | Annotate | Download | only in include
      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