Исправлен механизм смены потоков

This commit is contained in:
Aren 2024-01-10 19:29:17 +03:00
parent 224256a8ac
commit 9c11be08c9
6 changed files with 69 additions and 55 deletions

View File

@ -14,10 +14,16 @@
#define STACK_SIZE 8192 // 1MB
typedef struct task {
uint64_t id;
struct frame *state;
struct task *next;
typedef struct thread {
uint64_t id; // Идентификатор задачи
uint64_t priority; // Приоритет задачи
void *entry_point; // Точка входа в задачу
uint64_t status; // Состояние задачи
void *stack; // Указатель на стек
void *rsp; // Указатель на RSP
uint64_t stack_size; // Размер стека задачи
struct task *next; // Следующий поток
struct task *last; // Предыдущий поток
} __attribute__((packed)) task_t;
struct frame {

View File

@ -1,3 +1,3 @@
#define VERSION_MAJOR 0
#define VERSION_MINOR 1
#define VERSION_BUILD 905
#define VERSION_BUILD 915

View File

@ -101,7 +101,7 @@ void mod_init( ) {
continue;
}
module_info_t (*module_init)(env_t * env) =
module_info_t (*module_init)(env_t *env) =
(module_info_t(*)(env_t * env)) elf_entry((elf64_header_t *)module_ptr->address);
// LOG("\t->Точка входа: 0x%x\n", module_init);

View File

@ -10,18 +10,24 @@
#include <fb.h>
#include <mem.h>
static volatile uint64_t pid = 0;
static volatile uint64_t next_thread_id = 0;
static task_t *last_task = NULL;
static task_t *kernel_task = NULL;
task_t *current_task = NULL;
void task_switch(struct frame *state) {
// Смена потоков
asm volatile("cli");
asm volatile("pushf");
task_t *prev_task = current_task;
if (current_task == NULL) { return; }
if (current_task->next == NULL) { current_task = kernel_task; }
LOG("Смена потоков %u -> ", current_task->id);
asm volatile("mov %%rsp, %0" : "=a"(current_task->rsp));
current_task = current_task->next;
if (current_task == NULL) {
@ -33,61 +39,45 @@ void task_switch(struct frame *state) {
fb_printf("%u\n", current_task->id);
// Сохранение предыдущего состояния
prev_task->state->rip = state->rip;
prev_task->state->rsp = state->rsp;
prev_task->state->rbp = state->rbp;
// Восстановление следующего состояния
// LOG("Смена rsp\n");
state->rsp = current_task->state->rsp;
// LOG("Смена rbp\n");
state->rbp = current_task->state->rbp;
// LOG("Смена rip\n");
state->rip = current_task->state->rip;
// LOG("Конец!\n");
asm volatile("mov %0, %%rsp" ::"a"(current_task->rsp));
asm volatile("popf");
}
task_t *task_new_thread(void (*func)(void *), void *arg) {
uint64_t eflags;
void *stack = NULL;
asm volatile("cli");
LOG("Выделение потока\n");
asm volatile("pushf");
asm volatile("pop %0" : "=r"(eflags));
task_t *new_task = mem_alloc(sizeof(task_t));
LOG("new_task = 0x%x\n", new_task);
new_task->id = ++pid;
// mem_dump_memory( );
LOG("Выделение состояния\n");
new_task->state = mem_alloc(sizeof(struct frame));
tool_memset(new_task, 0, sizeof(task_t));
new_task->id = next_thread_id++;
new_task->stack_size = STACK_SIZE;
new_task->entry_point = func;
new_task->priority = 1;
stack = mem_alloc(STACK_SIZE);
new_task->stack = stack;
new_task->rsp = (uintptr_t)stack + STACK_SIZE - 16;
uintptr_t *rsp = (uintptr_t *)stack;
*(--rsp) = (uintptr_t)func; // Добавляем entry_point на стек
*(--rsp) = eflags | (1 << 9); // Сохраняем флаги на стеке
// Добавляем new_task в цепочку
if (last_task != NULL) { last_task->next = new_task; }
new_task->last = last_task;
new_task->next = NULL;
// Выделяем память под стек
LOG("Выделение стека\n");
void *stack = mem_alloc(STACK_SIZE);
// Устанавливаем значения регистров для нового потока
LOG("Установка регистров\n");
new_task->state->rbp = (uint64_t)stack + STACK_SIZE; // Указываем на вершину стека
new_task->state->rbx = 0;
new_task->state->r15 = 0;
new_task->state->r14 = 0;
new_task->state->r13 = 0;
new_task->state->r12 = 0;
new_task->state->r11 = 0;
new_task->state->r10 = 0;
new_task->state->r9 = 0;
new_task->state->r8 = 0;
new_task->state->rax = 0;
new_task->state->rcx = 0;
new_task->state->rdx = 0;
new_task->state->rsi = 0;
new_task->state->rdi = (uint64_t)arg; // Передаем аргументы в регистр rdi
new_task->state->int_number = 0;
new_task->state->err = 0;
new_task->state->rip = (uint64_t)func; // Устанавливаем адрес функции
new_task->state->cs = 0;
new_task->state->rflags = 0;
new_task->state->rsp = (uint64_t)stack + STACK_SIZE; // Указываем на вершину стека
new_task->state->ss = 0;
last_task = new_task;
if (kernel_task == NULL) {
LOG("Ядро ID: %u\n", new_task->id);
@ -101,11 +91,29 @@ task_t *task_new_thread(void (*func)(void *), void *arg) {
}
LOG("Создан новый поток с ID: %u\n", new_task->id);
asm volatile("sti"); // Включаем прерывания
return new_task;
}
void task_init( ) {
uint64_t rsp;
uint64_t cr3;
asm volatile("mov %%rsp, %0" : "=r"(rsp));
asm volatile("mov %%cr3, %0" : "=r"(cr3));
asm volatile("cli");
kernel_task = mem_alloc(sizeof(task_t));
tool_memset(kernel_task, 0, sizeof(task_t));
kernel_task->id = next_thread_id++;
kernel_task->stack_size = STACK_SIZE;
kernel_task->rsp = rsp;
current_task = kernel_task;
last_task = kernel_task;
idt_set_int(32, task_switch);
LOG("Потоки инициализированы\n");
}

0
modules/imfs/build.sh Normal file → Executable file
View File

0
modules/tga/build.sh Normal file → Executable file
View File