Rename struct Thread; Completely split task memspace and shceduling

This commit is contained in:
TXuian
2024-05-18 21:37:30 +08:00
parent 0b858de120
commit 736ba18769
36 changed files with 636 additions and 260 deletions
@@ -1,6 +1,5 @@
SRC_FILES := syscall.c \
sys_spawn.c \
sys_exec.c \
sys_yield.c \
sys_register_as_server.c \
sys_connect_session.c \
@@ -38,7 +38,7 @@ Modification:
/// @param cur_task
/// @param session
/// @return
int sys_close_session(struct TaskMicroDescriptor* cur_task, struct Session* session)
int sys_close_session(struct Thread* cur_task, struct Session* session)
{
assert(cur_task != NULL);
/* check if session is available */
@@ -35,7 +35,7 @@ Modification:
#include "syscall.h"
#include "task.h"
struct session_backend* create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session)
struct session_backend* create_session_inner(struct Thread* client, struct Thread* server, int capacity, struct Session* user_session)
{
// create share pages
assert(server != NULL && client != NULL);
@@ -61,7 +61,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session)
return -1;
}
struct TaskMicroDescriptor* client = cur_cpu()->task;
struct Thread* client = cur_cpu()->task;
/// get server
struct TraceTag server_identifier_owner;
if (!AchieveResourceTag(&server_identifier_owner, RequireRootTag(), "softkernel/server-identifier")) {
@@ -75,7 +75,7 @@ int sys_connect_session(char* path, int capacity, struct Session* user_session)
return -1;
}
struct TaskMicroDescriptor* server = AchieveResource(&server_tag);
struct Thread* server = AchieveResource(&server_tag);
assert(server != NULL);
if (create_session_inner(client, server, capacity, user_session) == NULL) {
return -1;
@@ -66,7 +66,7 @@ Modification:
/// @param path path to elf file
/// @param argv arguments giving to main
/// @return
int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv)
int task_exec(struct Thread* task, char* img_start, char* name, char** argv)
{
/* load img to task */
if (img_start == NULL) {
@@ -163,8 +163,8 @@ int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, cha
// init task trapframe, which stores in svc stack
// do not go tp error_exec once we change trapframe!
assert(copied_len == (argc + 1) * sizeof(uintptr_t));
arch_trapframe_set_sp_pc(task->main_thread.trapframe, user_vspace_sp, elf.entry);
arch_set_main_params(task->main_thread.trapframe, argc, user_vspace_sp);
arch_trapframe_set_sp_pc(task->thread_context.trapframe, user_vspace_sp, elf.entry);
arch_set_main_params(task->thread_context.trapframe, argc, user_vspace_sp);
// save program name
char* last = NULL;
@@ -202,7 +202,7 @@ int sys_exec(char* img_start, char* name, char** argv)
}
struct MmuCommonDone* p_mmu_driver = AchieveResource(&mmu_driver_tag);
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
struct Thread* current_task = cur_cpu()->task;
int ret = task_exec(current_task, img_start, name, argv);
if (ret >= 0) {
p_mmu_driver->LoadPgdir((uintptr_t)V2P(current_task->pgdir.pd_addr));
@@ -36,7 +36,7 @@ Modification:
#include "syscall.h"
#include "task.h"
int sys_exit(struct TaskMicroDescriptor* ptask)
int sys_exit(struct Thread* ptask)
{
assert(ptask != NULL);
ptask->dead = true;
@@ -31,14 +31,14 @@ Modification:
#include "task.h"
extern int sys_exit(struct TaskMicroDescriptor* task);
extern int sys_exit(struct Thread* task);
int sys_kill(int id)
{
struct TaskMicroDescriptor* task = NULL;
struct Thread* task = NULL;
// check if task is a running one
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_running_list_head, node)
{
if (task->pid == id) {
if (task->tid == id) {
sys_exit(task);
return 0;
}
@@ -47,7 +47,7 @@ int sys_kill(int id)
// check if task is a blocking one
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_blocked_list_head, node)
{
if (task->pid == id) {
if (task->tid == id) {
sys_exit(task);
return 0;
}
@@ -57,7 +57,7 @@ int sys_kill(int id)
for (int prio = 0; prio < TASK_MAX_PRIORITY; prio++) {
DOUBLE_LIST_FOR_EACH_ENTRY(task, &xizi_task_manager.task_list_head[prio], node)
{
if (task->pid == id) {
if (task->tid == id) {
sys_exit(task);
return 0;
}
@@ -30,15 +30,15 @@ Modification:
#include <stdint.h>
#include "assert.h"
#include "multicores.h"
#include "kalloc.h"
#include "multicores.h"
#include "share_page.h"
#include "syscall.h"
#include "task.h"
int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev)
{
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
struct Thread* cur_task = cur_cpu()->task;
assert(cur_task != NULL);
int true_len = ALIGNUP(len, PAGE_SIZE);
@@ -64,6 +64,6 @@ int sys_mmap(uintptr_t vaddr, uintptr_t paddr, int len, int is_dev)
}
}
cur_task->mem_size += true_len;
cur_task->memspace->mem_size += true_len;
return vaddr + true_len;
}
@@ -44,7 +44,7 @@ static inline bool is_msg_needed(struct IpcMsg* msg)
int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
{
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
struct Thread* cur_task = cur_cpu()->task;
if (cur_task == NULL) {
ERROR("%s by killed task\n");
return -1;
@@ -66,7 +66,7 @@ int sys_poll_session(struct Session* userland_session_arr, int arr_capacity)
// update session_backend
// if current session is handled
if (server_session->head != userland_session_arr[i].head) {
struct TaskMicroDescriptor* client = SERVER_SESSION_BACKEND(server_session)->client;
struct Thread* client = SERVER_SESSION_BACKEND(server_session)->client;
if (client->state == BLOCKED) {
xizi_task_manager.task_unblock(client);
} else {
@@ -39,7 +39,7 @@ Modification:
int sys_register_as_server(char* name)
{
struct TaskMicroDescriptor* server = cur_cpu()->task;
struct Thread* server = cur_cpu()->task;
struct TraceTag server_identifier_set_tag;
if (!AchieveResourceTag(&server_identifier_set_tag, RequireRootTag(), "softkernel/server-identifier")) {
panic("Server identifier not initialized.\b");
@@ -34,15 +34,15 @@ Modification:
#include "actracer.h"
#include "assert.h"
#include "ipc.h"
#include "kalloc.h"
#include "memspace.h"
#include "multicores.h"
#include "share_page.h"
#include "syscall.h"
#include "task.h"
static struct TaskMicroDescriptor* kernel_irq_proxy;
static struct Thread* kernel_irq_proxy;
static struct {
struct TaskMicroDescriptor* handle_task;
struct Thread* handle_task;
struct Session session;
struct session_backend* p_kernel_session;
int opcode;
@@ -56,7 +56,7 @@ static void send_irq_to_user(int irq_num)
len += sizeof(struct IpcArgInfo);
/* get message space and add session tail */
void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->pgdir, (uintptr_t)session->buf));
void* session_kern_vaddr = P2V(xizi_pager.address_translate(&kernel_irq_proxy->memspace->pgdir, (uintptr_t)session->buf));
struct IpcMsg* buf = session_kern_vaddr + session->tail;
/* check if server session is full */
@@ -98,7 +98,7 @@ int user_irq_handler(int irq, void* tf, void* arg)
return 0;
}
extern struct session_backend* create_session_inner(struct TaskMicroDescriptor* client, struct TaskMicroDescriptor* server, int capacity, struct Session* user_session);
extern struct session_backend* create_session_inner(struct Thread* client, struct Thread* server, int capacity, struct Session* user_session);
/// @warning no tested.
static struct XiziTrapDriver* p_intr_driver = NULL;
@@ -116,10 +116,16 @@ int sys_register_irq(int irq_num, int irq_opcode)
// init kerenl sender proxy
if (kernel_irq_proxy == NULL) {
kernel_irq_proxy = xizi_task_manager.new_task_cb();
/// @todo handle corner cases
struct MemSpace* pmemspace = alloc_memspace();
if (pmemspace == NULL) {
return -1;
}
xizi_pager.new_pgdir(&pmemspace->pgdir);
memcpy(pmemspace->pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE);
kernel_irq_proxy = xizi_task_manager.new_task_cb(pmemspace);
kernel_irq_proxy->state = NEVER_RUN;
xizi_pager.new_pgdir(&kernel_irq_proxy->pgdir);
memcpy(kernel_irq_proxy->pgdir.pd_addr, kern_pgdir.pd_addr, TOPLEVLE_PAGEDIR_SIZE);
}
// bind irq to session
@@ -127,7 +133,7 @@ int sys_register_irq(int irq_num, int irq_opcode)
ERROR("irq %d is occupied.\n", irq_num);
return -1;
}
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
struct Thread* cur_task = cur_cpu()->task;
irq_forward_table[irq_num].handle_task = cur_task;
irq_forward_table[irq_num].opcode = irq_opcode;
irq_forward_table[irq_num].p_kernel_session = create_session_inner(kernel_irq_proxy, cur_task, PAGE_SIZE, &irq_forward_table[irq_num].session);
@@ -137,7 +143,7 @@ int sys_register_irq(int irq_num, int irq_opcode)
return 0;
}
int sys_unbind_irq(struct TaskMicroDescriptor* task, int irq_num)
int sys_unbind_irq(struct Thread* task, int irq_num)
{
if (irq_forward_table[irq_num].handle_task != task) {
return -1;
@@ -147,7 +153,7 @@ int sys_unbind_irq(struct TaskMicroDescriptor* task, int irq_num)
return 0;
}
int sys_unbind_irq_all(struct TaskMicroDescriptor* task)
int sys_unbind_irq_all(struct Thread* task)
{
for (int idx = 0; idx < NR_IRQS; idx++) {
if (irq_forward_table[idx].handle_task == task) {
@@ -29,26 +29,64 @@ Modification:
*************************************************/
#include "actracer.h"
#include "assert.h"
#include "memspace.h"
#include "share_page.h"
#include "syscall.h"
#include "task.h"
extern int task_exec(struct TaskMicroDescriptor* task, char* img_start, char* name, char** argv);
extern int task_exec(struct Thread* task, char* img_start, char* name, char** argv);
int sys_spawn(char* img_start, char* name, char** argv)
{
// alloc a new pcb
struct TaskMicroDescriptor* new_task_cb = xizi_task_manager.new_task_cb();
if (UNLIKELY(!new_task_cb)) {
ERROR("Unable to new task control block.\n");
// alloc a new memspace
struct MemSpace* pmemspace = alloc_memspace();
if (pmemspace == NULL) {
return -1;
}
// init trapframe
arch_init_trapframe(new_task_cb->main_thread.trapframe, 0, 0);
if (UNLIKELY(task_exec(new_task_cb, img_start, name, argv)) < 0) {
// load memspace
uintptr_t* entry = load_memspace(pmemspace, img_start);
if (NULL == entry) {
ERROR("Loading memspace from %016x failed.\n", img_start);
free_memspace(pmemspace);
return -1;
}
// alloc a new pcb
struct Thread* new_task_cb = xizi_task_manager.new_task_cb(pmemspace);
if (UNLIKELY(!new_task_cb)) {
ERROR("Unable to new task control block.\n");
free_memspace(pmemspace);
return -1;
}
assert(!IS_DOUBLE_LIST_EMPTY(&pmemspace->thread_list_guard));
// init params
struct ThreadStackPointer loaded_sp = load_user_stack(pmemspace, argv);
if (loaded_sp.stack_idx == -1) {
ERROR("Uable to load params to memspace.\n");
/* memspace is freed alone with free_pcb() */
xizi_task_manager.free_pcb(new_task_cb);
return -1;
}
// init pcb
// init trapframe
new_task_cb->thread_context.user_stack_idx = loaded_sp.stack_idx;
new_task_cb->thread_context.uspace_stack_addr = USER_MEM_TOP - ((loaded_sp.stack_idx + 1) * USER_STACK_SIZE);
new_task_cb->thread_context.ustack_kvaddr = loaded_sp.user_stack_vaddr;
arch_init_trapframe(new_task_cb->thread_context.trapframe, 0, 0);
arch_trapframe_set_sp_pc(new_task_cb->thread_context.trapframe, loaded_sp.user_sp, (uintptr_t)entry);
arch_set_main_params(new_task_cb->thread_context.trapframe, loaded_sp.argc, loaded_sp.user_sp);
// init thread name
char* last = NULL;
for (last = name; *name; name++) {
if (*name == '/') {
last = name + 1;
}
}
strncpy(new_task_cb->name, last, sizeof(new_task_cb->name));
// init pcb schedule attributes
xizi_task_manager.task_set_default_schedule_attr(new_task_cb);
return 0;
@@ -41,11 +41,11 @@ Modification:
extern uint8_t _binary_fs_img_start[], _binary_fs_img_end[];
#define SHOWINFO_BORDER_LINE() LOG_PRINTF("******************************************************\n");
#define SHOWTASK_TASK_BASE_INFO(task) LOG_PRINTF(" %-6d %-16s %-4d 0x%x(%-d)\n", task->pid, task->name, task->priority, task->mem_size >> 10, task->mem_size >> 10)
#define SHOWTASK_TASK_BASE_INFO(task) LOG_PRINTF(" %-6d %-16s %-4d 0x%x(%-d)\n", task->tid, task->name, task->priority, task->memspace->mem_size >> 10, task->memspace->mem_size >> 10)
void show_tasks(void)
{
struct TaskMicroDescriptor* task = NULL;
struct Thread* task = NULL;
SHOWINFO_BORDER_LINE();
for (int i = 0; i < NR_CPU; i++) {
LOG_PRINTF("CPU %-2d: %s\n", i, (global_cpus[i].task == NULL ? "NULL" : global_cpus[i].task->name));
@@ -128,7 +128,7 @@ void show_cpu(void)
int cpu_id = 0;
struct TaskMicroDescriptor* current_task = cur_cpu()->task;
struct Thread* current_task = cur_cpu()->task;
assert(current_task != NULL);
LOG_PRINTF(" ID COMMAND USED_TICKS FREE_TICKS \n");
@@ -144,7 +144,7 @@ int sys_state(sys_state_option option, sys_state_info* info)
info->memblock_info.memblock_start = (uintptr_t)V2P(_binary_fs_img_start);
info->memblock_info.memblock_end = (uintptr_t)V2P(_binary_fs_img_end);
} else if (option == SYS_STATE_GET_HEAP_BASE) {
return cur_cpu()->task->heap_base;
return cur_cpu()->task->memspace->heap_base;
} else if (option == SYS_STATE_SET_TASK_PRIORITY) {
xizi_task_manager.set_cur_task_priority(info->priority);
} else if (option == SYS_STATE_SHOW_TASKS) {
@@ -35,7 +35,7 @@ Modification:
int sys_yield(task_yield_reason reason)
{
struct TaskMicroDescriptor* cur_task = cur_cpu()->task;
struct Thread* cur_task = cur_cpu()->task;
xizi_task_manager.task_yield_noschedule(cur_task, false);
// handle ipc block
@@ -63,7 +63,8 @@ int syscall(int sys_num, uintptr_t param1, uintptr_t param2, uintptr_t param3, u
ret = sys_close_session(cur_cpu()->task, (struct Session*)param1);
break;
case SYSCALL_EXEC:
ret = sys_exec((char*)param1, (char*)param2, (char**)param3);
// ret = sys_exec((char*)param1, (char*)param2, (char**)param3);
ret = -1;
break;
case SYSCALL_SYS_STATE:
ret = sys_state(param1, (sys_state_info*)param2);