117 lines
2.6 KiB
C
117 lines
2.6 KiB
C
#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 */
|