mirror of
https://github.com/0Nera/BMOSP.git
synced 2024-11-23 00:51:54 +03:00
Исправлен механизм смены потоков
This commit is contained in:
parent
224256a8ac
commit
9c11be08c9
@ -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 {
|
||||
|
@ -1,3 +1,3 @@
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_BUILD 905
|
||||
#define VERSION_BUILD 915
|
||||
|
@ -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);
|
||||
|
106
kernel/task.c
106
kernel/task.c
@ -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
0
modules/imfs/build.sh
Normal file → Executable file
0
modules/tga/build.sh
Normal file → Executable file
0
modules/tga/build.sh
Normal file → Executable file
Loading…
Reference in New Issue
Block a user