Squash commits for public release
This commit is contained in:
21
kernel/include/tasking/bits/dump.h
Normal file
21
kernel/include/tasking/bits/dump.h
Normal file
@@ -0,0 +1,21 @@
|
||||
#ifndef _KERNEL_TASKING_BITS_DUMP_H
|
||||
#define _KERNEL_TASKING_BITS_DUMP_H
|
||||
|
||||
#include <libkern/types.h>
|
||||
#include <tasking/proc.h>
|
||||
|
||||
typedef int (*dump_saver_t)(const char*);
|
||||
typedef ssize_t (*sym_resolver_t)(void* symtab, size_t syms_n, uintptr_t tp);
|
||||
|
||||
struct dump_data {
|
||||
proc_t* p;
|
||||
uintptr_t entry_point;
|
||||
void* syms;
|
||||
size_t symsn;
|
||||
char* strs;
|
||||
dump_saver_t writer;
|
||||
sym_resolver_t sym_resolver;
|
||||
};
|
||||
typedef struct dump_data dump_data_t;
|
||||
|
||||
#endif // _KERNEL_TASKING_BITS_DUMP_H
|
||||
29
kernel/include/tasking/bits/sched.h
Normal file
29
kernel/include/tasking/bits/sched.h
Normal file
@@ -0,0 +1,29 @@
|
||||
#ifndef _KERNEL_TASKING_BITS_SCHED_H
|
||||
#define _KERNEL_TASKING_BITS_SCHED_H
|
||||
|
||||
#define MAX_PRIO 0
|
||||
#define MIN_PRIO 11
|
||||
#define IDLE_PRIO (MIN_PRIO + 1)
|
||||
#define PROC_PRIOS_COUNT (MIN_PRIO - MAX_PRIO + 1)
|
||||
#define TOTAL_PRIOS_COUNT (IDLE_PRIO - MAX_PRIO + 1)
|
||||
#define DEFAULT_PRIO 6
|
||||
#define SCHED_INT 10
|
||||
#define LAST_CPU_NOT_SET 0xffff
|
||||
|
||||
struct thread;
|
||||
|
||||
struct runqueue {
|
||||
struct thread* head;
|
||||
struct thread* tail;
|
||||
};
|
||||
typedef struct runqueue runqueue_t;
|
||||
|
||||
struct sched_data {
|
||||
int next_read_prio;
|
||||
runqueue_t* master_buf;
|
||||
runqueue_t* slave_buf;
|
||||
int enqueued_tasks;
|
||||
};
|
||||
typedef struct sched_data sched_data_t;
|
||||
|
||||
#endif // _KERNEL_TASKING_BITS_SCHED_H
|
||||
45
kernel/include/tasking/cpu.h
Normal file
45
kernel/include/tasking/cpu.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef _KERNEL_TASKING_CPU_H
|
||||
#define _KERNEL_TASKING_CPU_H
|
||||
|
||||
#include <platform/generic/cpu.h>
|
||||
#include <platform/generic/fpu/fpu.h>
|
||||
#include <tasking/bits/sched.h>
|
||||
#include <tasking/proc.h>
|
||||
#include <tasking/thread.h>
|
||||
|
||||
#define RUNNING_THREAD (THIS_CPU->running_thread)
|
||||
|
||||
static inline cpu_state_t cpu_enter_kernel_space()
|
||||
{
|
||||
cpu_state_t prev = THIS_CPU->current_state;
|
||||
THIS_CPU->current_state = CPU_IN_KERNEL;
|
||||
return prev;
|
||||
}
|
||||
|
||||
static inline cpu_state_t cpu_get_state()
|
||||
{
|
||||
return THIS_CPU->current_state;
|
||||
}
|
||||
|
||||
static inline void cpu_set_state(cpu_state_t state)
|
||||
{
|
||||
THIS_CPU->current_state = state;
|
||||
}
|
||||
|
||||
static inline void cpu_enter_user_space()
|
||||
{
|
||||
THIS_CPU->current_state = CPU_IN_USERLAND;
|
||||
}
|
||||
|
||||
static inline void cpu_tick()
|
||||
{
|
||||
if (!THIS_CPU->running_thread) {
|
||||
THIS_CPU->stat_system_and_idle_ticks++;
|
||||
} else if (THIS_CPU->running_thread->process->is_kthread) {
|
||||
THIS_CPU->stat_system_and_idle_ticks++;
|
||||
} else {
|
||||
THIS_CPU->stat_user_ticks++;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _KERNEL_TASKING_CPU_H
|
||||
12
kernel/include/tasking/dump.h
Normal file
12
kernel/include/tasking/dump.h
Normal file
@@ -0,0 +1,12 @@
|
||||
#ifndef _KERNEL_TASKING_DUMP_H
|
||||
#define _KERNEL_TASKING_DUMP_H
|
||||
|
||||
#include <platform/generic/tasking/trapframe.h>
|
||||
#include <tasking/proc.h>
|
||||
|
||||
void dump_and_kill(proc_t* p);
|
||||
int dump_prepare_kernel_data();
|
||||
int dump_kernel(const char* err);
|
||||
int dump_kernel_from_tf(const char* err, trapframe_t* tf);
|
||||
|
||||
#endif // _KERNEL_TASKING_DUMP_H
|
||||
270
kernel/include/tasking/elf.h
Normal file
270
kernel/include/tasking/elf.h
Normal file
@@ -0,0 +1,270 @@
|
||||
#ifndef _KERNEL_TASKING_ELF_H
|
||||
#define _KERNEL_TASKING_ELF_H
|
||||
|
||||
#define ELF_CLASS_32 1
|
||||
#define ELF_CLASS_64 2
|
||||
|
||||
#define ELF_DATA2_LSB 1
|
||||
#define ELF_DATA2_MSB 2
|
||||
|
||||
enum E_IDENT_FIELDS {
|
||||
EI_MAG0,
|
||||
EI_MAG1,
|
||||
EI_MAG2,
|
||||
EI_MAG3,
|
||||
EI_CLASS,
|
||||
EI_DATA,
|
||||
EI_VERSION,
|
||||
EI_OSABI,
|
||||
EI_ABIVERSION,
|
||||
};
|
||||
|
||||
enum E_TYPE_FIELDS {
|
||||
ET_NONE,
|
||||
ET_REL,
|
||||
ET_EXEC,
|
||||
ET_DYN,
|
||||
ET_CORE,
|
||||
};
|
||||
|
||||
enum E_MACHINE_FIELDS {
|
||||
EM_NONE = 0x0,
|
||||
EM_386 = 0x03,
|
||||
EM_ARM = 0x28,
|
||||
EM_AMD64 = 0x3e,
|
||||
EM_AARCH64 = 0xB7,
|
||||
EM_RISCV = 0xF3,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[16];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
uint32_t e_entry;
|
||||
uint32_t e_phoff;
|
||||
uint32_t e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} elf_header_32_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t e_ident[16];
|
||||
uint16_t e_type;
|
||||
uint16_t e_machine;
|
||||
uint32_t e_version;
|
||||
uint64_t e_entry;
|
||||
uint64_t e_phoff;
|
||||
uint64_t e_shoff;
|
||||
uint32_t e_flags;
|
||||
uint16_t e_ehsize;
|
||||
uint16_t e_phentsize;
|
||||
uint16_t e_phnum;
|
||||
uint16_t e_shentsize;
|
||||
uint16_t e_shnum;
|
||||
uint16_t e_shstrndx;
|
||||
} elf_header_64_t;
|
||||
|
||||
enum P_TYPE_FIELDS {
|
||||
PT_NULL,
|
||||
PT_LOAD,
|
||||
PT_DYNAMIC,
|
||||
PT_INTERP,
|
||||
PT_NOTE,
|
||||
PT_SHLIB,
|
||||
PT_PHDR,
|
||||
PT_TLS,
|
||||
PT_LOOS = 0x60000000,
|
||||
PT_HIOS = 0x6FFFFFFF,
|
||||
PT_LOPROC = 0x70000000,
|
||||
PT_HIPROC = 0x7FFFFFFF,
|
||||
};
|
||||
|
||||
enum P_FLAGS_FIELDS {
|
||||
PF_X = 0x1,
|
||||
PF_W = 0x2,
|
||||
PF_R = 0x4,
|
||||
PF_MASKPROC = 0xf0000000,
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t p_type;
|
||||
uint32_t p_offset;
|
||||
uint32_t p_vaddr;
|
||||
uint32_t p_paddr;
|
||||
uint32_t p_filesz;
|
||||
uint32_t p_memsz;
|
||||
uint32_t p_flags;
|
||||
uint32_t p_align;
|
||||
} elf_program_header_32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t p_type;
|
||||
uint32_t p_flags;
|
||||
uint64_t p_offset;
|
||||
uint64_t p_vaddr;
|
||||
uint64_t p_paddr;
|
||||
uint64_t p_filesz;
|
||||
uint64_t p_memsz;
|
||||
uint64_t p_align;
|
||||
} elf_program_header_64_t;
|
||||
|
||||
enum SH_TYPE_FIELDS {
|
||||
SHT_NULL,
|
||||
SHT_PROGBITS,
|
||||
SHT_SYMTAB,
|
||||
SHT_STRTAB,
|
||||
SHT_RELA,
|
||||
SHT_HASH,
|
||||
SHT_DYNAMIC,
|
||||
SHT_NOTE,
|
||||
SHT_NOBITS,
|
||||
SHT_REL,
|
||||
SHT_SHLIB,
|
||||
SHT_DYNSYM,
|
||||
SHT_INIT_ARRAY,
|
||||
SHT_FINI_ARRAY,
|
||||
SHT_PREINIT_ARRAY,
|
||||
SHT_GROUP,
|
||||
SHT_SYMTAB_SHNDX,
|
||||
|
||||
SHT_LOOS = 1610612736,
|
||||
SHT_HIOS = 1879048191,
|
||||
SHT_LOPROC = 1879048192,
|
||||
SHT_HIPROC = 2147483647,
|
||||
SHT_LOUSER = 2147483648,
|
||||
SHT_HIUSER = 4294967295,
|
||||
};
|
||||
|
||||
enum SH_FLAGS_FIELDS {
|
||||
SHF_WRITE = 0x1,
|
||||
SHF_ALLOC = 0x2,
|
||||
SHF_EXECINSTR = 0x4,
|
||||
SHF_MERGE = 0x10,
|
||||
SHF_STRINGS = 0x20,
|
||||
|
||||
SHF_INFO_LINK = 0x40,
|
||||
SHF_LINK_ORDER = 0x80,
|
||||
SHF_OS_NONCONFORMING = 0x100,
|
||||
SHF_GROUP = 0x200,
|
||||
SHF_TLS = 0x400,
|
||||
SHF_COMPRESSED = 0x800,
|
||||
SHF_MASKOS = 0x0ff00000,
|
||||
SHF_MASKPROC = 0xf0000000
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint32_t sh_flags;
|
||||
uint32_t sh_addr;
|
||||
uint32_t sh_offset;
|
||||
uint32_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint32_t sh_addralign;
|
||||
uint32_t sh_entsize;
|
||||
} elf_section_header_32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t sh_name;
|
||||
uint32_t sh_type;
|
||||
uint64_t sh_flags;
|
||||
uint64_t sh_addr;
|
||||
uint64_t sh_offset;
|
||||
uint64_t sh_size;
|
||||
uint32_t sh_link;
|
||||
uint32_t sh_info;
|
||||
uint64_t sh_addralign;
|
||||
uint64_t sh_entsize;
|
||||
} elf_section_header_64_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t st_name; // name - index into string table
|
||||
uint32_t st_value; // symbol value
|
||||
uint32_t st_size; // symbol size
|
||||
uint8_t st_info; // type and binding
|
||||
uint8_t st_other; // 0 - no defined meaning
|
||||
uint16_t st_shndx; // section header index
|
||||
} elf_sym_32_t;
|
||||
|
||||
typedef struct {
|
||||
uint32_t st_name;
|
||||
uint8_t st_info;
|
||||
uint8_t st_other;
|
||||
uint16_t st_shndx;
|
||||
uint64_t st_value;
|
||||
uint64_t st_size;
|
||||
} elf_sym_64_t;
|
||||
|
||||
enum ST_BINDING_FIELDS {
|
||||
STB_LOCAL = 0,
|
||||
STB_GLOBAL = 1,
|
||||
STB_WEAK = 2,
|
||||
STB_NUM = 3,
|
||||
STB_LOPROC = 13,
|
||||
STB_HIPROC = 15
|
||||
};
|
||||
|
||||
enum ST_TYPE_FIELDS {
|
||||
STT_NOTYPE = 0,
|
||||
STT_OBJECT = 1,
|
||||
STT_FUNC = 2,
|
||||
STT_SECTION = 3,
|
||||
STT_FILE = 4,
|
||||
STT_TLS = 6,
|
||||
STT_LOPROC = 13,
|
||||
STT_HIPROC = 15
|
||||
};
|
||||
|
||||
struct proc;
|
||||
struct file_descriptor;
|
||||
|
||||
#ifdef __i386__
|
||||
#define MACHINE_ARCH EM_386
|
||||
typedef elf_header_32_t elf_header_t;
|
||||
typedef elf_section_header_32_t elf_section_header_t;
|
||||
typedef elf_program_header_32_t elf_program_header_t;
|
||||
typedef elf_sym_32_t elf_sym_t;
|
||||
#define USER_STACK_SIZE (16 << 10) // 16KB
|
||||
#elif __x86_64__
|
||||
#define MACHINE_ARCH EM_AMD64
|
||||
typedef elf_header_64_t elf_header_t;
|
||||
typedef elf_section_header_64_t elf_section_header_t;
|
||||
typedef elf_program_header_64_t elf_program_header_t;
|
||||
typedef elf_sym_64_t elf_sym_t;
|
||||
#define USER_STACK_SIZE (4 << 20) // 4MB
|
||||
#elif __arm__
|
||||
#define MACHINE_ARCH EM_ARM
|
||||
typedef elf_header_32_t elf_header_t;
|
||||
typedef elf_section_header_32_t elf_section_header_t;
|
||||
typedef elf_program_header_32_t elf_program_header_t;
|
||||
typedef elf_sym_32_t elf_sym_t;
|
||||
#define USER_STACK_SIZE (16 << 10) // 16KB
|
||||
#elif __aarch64__
|
||||
#define MACHINE_ARCH EM_AARCH64
|
||||
typedef elf_header_64_t elf_header_t;
|
||||
typedef elf_section_header_64_t elf_section_header_t;
|
||||
typedef elf_program_header_64_t elf_program_header_t;
|
||||
typedef elf_sym_64_t elf_sym_t;
|
||||
#define USER_STACK_SIZE (4 << 20) // 4MB
|
||||
#elif defined(__riscv) && (__riscv_xlen == 64)
|
||||
#define MACHINE_ARCH EM_RISCV
|
||||
typedef elf_header_64_t elf_header_t;
|
||||
typedef elf_section_header_64_t elf_section_header_t;
|
||||
typedef elf_program_header_64_t elf_program_header_t;
|
||||
typedef elf_sym_64_t elf_sym_t;
|
||||
#define USER_STACK_SIZE (4 << 20) // 4MB
|
||||
#endif
|
||||
|
||||
int elf_check_header(elf_header_t* header);
|
||||
int elf_load(struct proc* p, struct file_descriptor* fd);
|
||||
int elf_find_symtab_unchecked(void* mapped_data, void** symtab, size_t* symtab_entries, char** strtab);
|
||||
ssize_t elf_find_function_in_symtab(void* symtab, size_t syms_n, uintptr_t ip);
|
||||
|
||||
#endif // _KERNEL_TASKING_ELF_H
|
||||
112
kernel/include/tasking/proc.h
Normal file
112
kernel/include/tasking/proc.h
Normal file
@@ -0,0 +1,112 @@
|
||||
#ifndef _KERNEL_TASKING_PROC_H
|
||||
#define _KERNEL_TASKING_PROC_H
|
||||
|
||||
#include <algo/dynamic_array.h>
|
||||
#include <fs/vfs.h>
|
||||
#include <io/tty/vconsole.h>
|
||||
#include <libkern/atomic.h>
|
||||
#include <libkern/lock.h>
|
||||
#include <libkern/types.h>
|
||||
#include <mem/kmemzone.h>
|
||||
#include <mem/memzone.h>
|
||||
#include <mem/vm_address_space.h>
|
||||
#include <mem/vmm.h>
|
||||
|
||||
#define MAX_PROCESS_COUNT 1024
|
||||
#define MAX_OPENED_FILES 16
|
||||
|
||||
struct blocker;
|
||||
|
||||
enum PROC_STATUS {
|
||||
PROC_INVALID = 0,
|
||||
PROC_ALIVE,
|
||||
PROC_DEAD,
|
||||
PROC_DYING,
|
||||
PROC_ZOMBIE,
|
||||
};
|
||||
|
||||
struct thread;
|
||||
struct proc {
|
||||
vm_address_space_t* address_space;
|
||||
|
||||
pid_t pid;
|
||||
pid_t ppid;
|
||||
pid_t pgid;
|
||||
uint32_t prio;
|
||||
uint32_t status;
|
||||
struct thread* main_thread;
|
||||
|
||||
spinlock_t lock;
|
||||
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
uid_t euid;
|
||||
gid_t egid;
|
||||
uid_t suid;
|
||||
gid_t sgid;
|
||||
|
||||
file_t* proc_file;
|
||||
path_t cwd;
|
||||
file_descriptor_t* fds;
|
||||
|
||||
int exit_code;
|
||||
|
||||
bool is_kthread;
|
||||
|
||||
// Trace data
|
||||
bool is_tracee;
|
||||
};
|
||||
typedef struct proc proc_t;
|
||||
|
||||
/**
|
||||
* PROC FUNCTIONS
|
||||
*/
|
||||
pid_t proc_alloc_pid();
|
||||
struct thread* thread_by_pid(pid_t pid);
|
||||
|
||||
int proc_init_storage();
|
||||
int proc_setup(proc_t* p);
|
||||
int proc_setup_with_uid(proc_t* p, uid_t uid, gid_t gid);
|
||||
int proc_setup_vconsole(proc_t* p, vconsole_entry_t* vconsole);
|
||||
int proc_fill_up_stack(proc_t* p, int argc, char** argv, char** env);
|
||||
int proc_free(proc_t* p);
|
||||
int proc_free_locked(proc_t* p);
|
||||
|
||||
struct thread* proc_alloc_thread();
|
||||
struct thread* proc_create_thread(proc_t* p);
|
||||
void proc_kill_all_threads(proc_t* p);
|
||||
void proc_kill_all_threads_except(proc_t* p, struct thread* gthread);
|
||||
|
||||
/**
|
||||
* KTHREAD FUNCTIONS
|
||||
*/
|
||||
|
||||
int kthread_setup(proc_t* p);
|
||||
int kthread_setup_regs(proc_t* p, void* entry_point);
|
||||
void kthread_setup_segment_regs(proc_t* p);
|
||||
int kthread_fill_up_stack(struct thread* thread, void* data);
|
||||
|
||||
int proc_load(proc_t* p, struct thread* main_thread, const char* path);
|
||||
int proc_fork_from(proc_t* new_proc, struct thread* from_thread);
|
||||
|
||||
int proc_die(proc_t* p, int exit_code);
|
||||
int proc_block_all_threads(proc_t* p, const struct blocker* blocker);
|
||||
|
||||
/**
|
||||
* PROC FD FUNCTIONS
|
||||
*/
|
||||
|
||||
int proc_chdir(proc_t* p, const char* path);
|
||||
file_descriptor_t* proc_get_free_fd(proc_t* p);
|
||||
file_descriptor_t* proc_get_fd(proc_t* p, size_t index);
|
||||
int proc_get_fd_id(proc_t* proc, file_descriptor_t* fd);
|
||||
int proc_copy_fd(file_descriptor_t* oldfd, file_descriptor_t* newfd);
|
||||
|
||||
/**
|
||||
* PROC HELPER FUNCTIONS
|
||||
*/
|
||||
|
||||
static ALWAYS_INLINE bool proc_is_su(proc_t* p) { return p->euid == 0; }
|
||||
static ALWAYS_INLINE int proc_is_alive(proc_t* p) { return p->status == PROC_ALIVE; }
|
||||
|
||||
#endif // _KERNEL_TASKING_PROC_H
|
||||
30
kernel/include/tasking/sched.h
Normal file
30
kernel/include/tasking/sched.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#ifndef _KERNEL_TASKING_SCHED_H
|
||||
#define _KERNEL_TASKING_SCHED_H
|
||||
|
||||
#include <libkern/types.h>
|
||||
#include <mem/vmm.h>
|
||||
#include <tasking/bits/sched.h>
|
||||
#include <tasking/tasking.h>
|
||||
|
||||
void scheduler_init();
|
||||
void schedule_activate_cpu();
|
||||
void resched_dont_save_context();
|
||||
void resched();
|
||||
void sched();
|
||||
void sched_enqueue(thread_t* thread);
|
||||
void sched_dequeue(thread_t* thread);
|
||||
size_t active_cpu_count();
|
||||
|
||||
static inline void sched_tick()
|
||||
{
|
||||
if (!RUNNING_THREAD) {
|
||||
return;
|
||||
}
|
||||
|
||||
RUNNING_THREAD->ticks_until_preemption--;
|
||||
if (!RUNNING_THREAD->ticks_until_preemption) {
|
||||
resched();
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _KERNEL_TASKING_SCHED_H
|
||||
17
kernel/include/tasking/signal.h
Normal file
17
kernel/include/tasking/signal.h
Normal file
@@ -0,0 +1,17 @@
|
||||
#ifndef _KERNEL_TASKING_SIGNAL_H
|
||||
#define _KERNEL_TASKING_SIGNAL_H
|
||||
|
||||
#include <libkern/bits/signal.h>
|
||||
#include <libkern/types.h>
|
||||
|
||||
#define SIGNALS_CNT 32
|
||||
|
||||
enum SIGNAL_ACTION {
|
||||
SIGNAL_ACTION_ABNORMAL_TERMINATE,
|
||||
SIGNAL_ACTION_TERMINATE,
|
||||
SIGNAL_ACTION_STOP,
|
||||
SIGNAL_ACTION_CONTINUE,
|
||||
SIGNAL_ACTION_IGNORE,
|
||||
};
|
||||
|
||||
#endif // _KERNEL_TASKING_SIGNAL_H
|
||||
76
kernel/include/tasking/tasking.h
Normal file
76
kernel/include/tasking/tasking.h
Normal file
@@ -0,0 +1,76 @@
|
||||
#ifndef _KERNEL_TASKING_TASKING_H
|
||||
#define _KERNEL_TASKING_TASKING_H
|
||||
|
||||
#include <fs/vfs.h>
|
||||
#include <libkern/types.h>
|
||||
#include <mem/kmemzone.h>
|
||||
#include <mem/vmm.h>
|
||||
#include <platform/generic/fpu/fpu.h>
|
||||
#include <platform/generic/tasking/context.h>
|
||||
#include <platform/generic/tasking/trapframe.h>
|
||||
#include <tasking/cpu.h>
|
||||
#include <tasking/proc.h>
|
||||
#include <tasking/thread.h>
|
||||
|
||||
#define MAX_PROCESS_COUNT 1024
|
||||
#define MAX_DYING_PROCESS_COUNT 8
|
||||
#define MAX_OPENED_FILES 16
|
||||
#define SIGNALS_CNT 32
|
||||
|
||||
extern proc_t proc[MAX_PROCESS_COUNT];
|
||||
|
||||
proc_t* tasking_get_proc(pid_t pid);
|
||||
|
||||
/**
|
||||
* CPU FUNCTIONS
|
||||
*/
|
||||
|
||||
void switch_uthreads(thread_t* p);
|
||||
|
||||
/**
|
||||
* TASK LOADING FUNCTIONS
|
||||
*/
|
||||
|
||||
void tasking_start_init_proc();
|
||||
proc_t* tasking_create_kernel_thread(void* entry_point, void* data);
|
||||
proc_t* tasking_run_kernel_thread(void* entry_point, void* data);
|
||||
|
||||
/**
|
||||
* TASKING RELATED FUNCTIONS
|
||||
*/
|
||||
|
||||
void tasking_init();
|
||||
void tasking_kill_dying();
|
||||
bool tasking_should_become_zombie(proc_t* p);
|
||||
void tasking_evict_proc_entry(proc_t* p);
|
||||
void tasking_evict_zombies_waiting_for(proc_t* p);
|
||||
|
||||
pid_t tasking_get_proc_count();
|
||||
|
||||
/**
|
||||
* SYSCALL IMPLEMENTATION
|
||||
*/
|
||||
|
||||
void tasking_fork();
|
||||
int tasking_exec(const char __user* path, const char __user** argv, const char __user** env);
|
||||
void tasking_exit(int exit_code);
|
||||
int tasking_waitpid(int pid, int* status, int options);
|
||||
int tasking_signal(thread_t* thread, int signo);
|
||||
|
||||
/**
|
||||
* SIGNALS
|
||||
*/
|
||||
|
||||
void signal_init();
|
||||
|
||||
int signal_set_handler(thread_t* thread, int signo, uintptr_t handler);
|
||||
int signal_set_allow(thread_t* thread, int signo);
|
||||
int signal_set_private(thread_t* thread, int signo);
|
||||
int signal_set_pending(thread_t* thread, int signo);
|
||||
int signal_rem_pending(thread_t* thread, int signo);
|
||||
|
||||
int signal_restore_thread_after_handling_signal(thread_t* thread);
|
||||
int signal_send(thread_t* thread, int signo);
|
||||
int signal_dispatch_pending(thread_t* thread);
|
||||
|
||||
#endif // _KERNEL_TASKING_TASKING_H
|
||||
165
kernel/include/tasking/thread.h
Normal file
165
kernel/include/tasking/thread.h
Normal file
@@ -0,0 +1,165 @@
|
||||
#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 */
|
||||
Reference in New Issue
Block a user