165 lines
4.1 KiB
C
165 lines
4.1 KiB
C
#ifndef _KERNEL_TASKING_THREAD_H
|
|
#define _KERNEL_TASKING_THREAD_H
|
|
|
|
#include <fs/vfs.h>
|
|
#include <libkern/lock.h>
|
|
#include <libkern/types.h>
|
|
#include <platform/generic/fpu/fpu.h>
|
|
#include <platform/generic/tasking/context.h>
|
|
#include <platform/generic/tasking/trapframe.h>
|
|
#include <tasking/signal.h>
|
|
#include <time/time_manager.h>
|
|
|
|
enum THREAD_STATUS {
|
|
THREAD_STATUS_INVALID = 0,
|
|
THREAD_STATUS_ALLOCATED,
|
|
THREAD_STATUS_RUNNING,
|
|
THREAD_STATUS_STOPPED,
|
|
THREAD_STATUS_BLOCKED,
|
|
THREAD_STATUS_DYING,
|
|
};
|
|
|
|
struct thread;
|
|
struct blocker {
|
|
int reason;
|
|
bool (*should_unblock)(struct thread* thread);
|
|
bool should_unblock_for_signal;
|
|
};
|
|
typedef struct blocker blocker_t;
|
|
|
|
enum BLOCKER_REASON {
|
|
BLOCKER_INVALID,
|
|
BLOCKER_JOIN,
|
|
BLOCKER_READ,
|
|
BLOCKER_WRITE,
|
|
BLOCKER_SLEEP,
|
|
BLOCKER_SELECT,
|
|
BLOCKER_DUMPING,
|
|
BLOCKER_STOP, // Just waiting for signal which will continue the thread.
|
|
};
|
|
|
|
struct blocker_join {
|
|
struct thread* joinee;
|
|
int join_pid;
|
|
};
|
|
typedef struct blocker_join blocker_join_t;
|
|
|
|
struct blocker_rw {
|
|
file_descriptor_t* fd;
|
|
};
|
|
typedef struct blocker_rw blocker_rw_t;
|
|
|
|
struct blocker_sleep {
|
|
timespec_t until;
|
|
};
|
|
typedef struct blocker_sleep blocker_sleep_t;
|
|
|
|
struct blocker_select {
|
|
int nfds;
|
|
fd_set_t readfds;
|
|
fd_set_t writefds;
|
|
fd_set_t exceptfds;
|
|
|
|
bool is_until_time_set;
|
|
timespec_t until;
|
|
};
|
|
typedef struct blocker_select blocker_select_t;
|
|
|
|
struct proc;
|
|
struct thread {
|
|
struct proc* process;
|
|
pid_t tid;
|
|
uint32_t status;
|
|
|
|
/* Kernel data */
|
|
kmemzone_t kstack;
|
|
context_t* context; // context of kernel's registers
|
|
trapframe_t* tf;
|
|
#ifdef FPU_ENABLED
|
|
fpu_state_t* fpu_state;
|
|
#endif
|
|
|
|
/* Scheduler data */
|
|
struct thread* sched_prev;
|
|
struct thread* sched_next;
|
|
int last_cpu;
|
|
time_t ticks_until_preemption;
|
|
time_t start_time_in_ticks; // Time when the task was put to run.
|
|
|
|
/* Blocker data */
|
|
blocker_t blocker;
|
|
union {
|
|
blocker_join_t join;
|
|
blocker_rw_t rw;
|
|
blocker_sleep_t sleep;
|
|
blocker_select_t select;
|
|
} blocker_data;
|
|
|
|
/* Stat data */
|
|
time_t stat_total_running_ticks;
|
|
|
|
uint32_t signals_mask;
|
|
uint32_t pending_signals_mask;
|
|
void* signal_handlers[SIGNALS_CNT];
|
|
};
|
|
typedef struct thread thread_t;
|
|
|
|
#define THREADS_PER_NODE (128)
|
|
struct thread_list_node {
|
|
thread_t thread_storage[THREADS_PER_NODE];
|
|
struct thread_list_node* next;
|
|
int empty_spots;
|
|
};
|
|
typedef struct thread_list_node thread_list_node_t;
|
|
|
|
struct thread_list {
|
|
struct thread_list_node* head;
|
|
struct thread_list_node* next_empty_node;
|
|
int next_empty_index;
|
|
spinlock_t lock;
|
|
struct thread_list_node* tail;
|
|
};
|
|
typedef struct thread_list thread_list_t;
|
|
|
|
/**
|
|
* THREAD FUNCTIONS
|
|
*/
|
|
|
|
int thread_setup_main(struct proc* p, thread_t* thread);
|
|
int thread_setup(struct proc* p, thread_t* thread);
|
|
int thread_setup_kstack(thread_t* thread);
|
|
int thread_copy_of(thread_t* thread, thread_t* from_thread);
|
|
|
|
int thread_fill_up_stack(thread_t* thread, int argc, char** argv, int envc, char** envp);
|
|
|
|
int thread_kstack_free(thread_t* thread);
|
|
int thread_free(thread_t* thread);
|
|
int thread_die(thread_t* thread);
|
|
int thread_zombie(thread_t* thread);
|
|
int thread_stop(thread_t* thread);
|
|
int thread_stop_and_resched(thread_t* thread);
|
|
int thread_continue(thread_t* thread);
|
|
|
|
static ALWAYS_INLINE int thread_is_freed(thread_t* thread) { return (thread->status == THREAD_STATUS_INVALID); }
|
|
static ALWAYS_INLINE int thread_is_alive(thread_t* thread) { return !thread_is_freed(thread); }
|
|
|
|
/**
|
|
* BLOCKER FUNCTIONS
|
|
*/
|
|
|
|
int thread_init_blocker(thread_t* thread, const struct blocker* blocker);
|
|
|
|
int init_join_blocker(thread_t* thread, int wait_for_pid);
|
|
int init_read_blocker(thread_t* thread, file_descriptor_t* bfd);
|
|
int init_write_blocker(thread_t* thread, file_descriptor_t* bfd);
|
|
int init_sleep_blocker(thread_t* thread, timespec_t ts);
|
|
int init_select_blocker(thread_t* thread, int nfds, fd_set_t* readfds, fd_set_t* writefds, fd_set_t* exceptfds, timeval_t* timeout);
|
|
|
|
/**
|
|
* DEBUG FUNCTIONS
|
|
*/
|
|
|
|
int thread_dump_frame(thread_t* thread);
|
|
int thread_print_backtrace();
|
|
|
|
#endif /* _KERNEL_TASKING_THREAD_H */ |