blob: 8ec4a26749144d19d2a37ea5ffc6da4fb852afcc [file] [log] [blame]
Greg Hartman76d05dc2016-11-23 15:51:27 -08001#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 */