• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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;
current(void)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  */
sem_set_invalid(struct semaphore * sem)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  */
sem_is_valid(struct semaphore * sem)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