Поддержка многопоточности

This commit is contained in:
Aren Elchinyan 2024-01-21 21:40:21 +03:00
parent 90cf91ee31
commit c4b8ec6787
4 changed files with 39 additions and 33 deletions

View File

@ -12,14 +12,14 @@
#include <stdint.h> #include <stdint.h>
#define STACK_SIZE 8192 // 1MB #define STACK_SIZE 8192 // 8 килобайт на стек
typedef struct task { typedef struct task {
uint64_t rax, rbx, rcx, rdx; uint64_t rax, rbx, rcx, rdx;
uint64_t rsi, rdi, rsp, rbp; uint64_t rsi, rdi, rsp, rbp;
uint64_t cr3;
uint64_t id; uint64_t id;
uint64_t ret;
void *stack; void *stack;
struct task *last; struct task *last;
@ -56,6 +56,7 @@ typedef void (*int_entry_t)(struct frame *state);
void arch_init( ); void arch_init( );
void task_init( ); void task_init( );
void task_switch(struct frame *state); void task_switch(struct frame *state);
uint64_t task_new_thread(void (*func)(void *));
void cpu_init( ); void cpu_init( );
void gdt_init( ); void gdt_init( );
void pic_init( ); void pic_init( );

View File

@ -7,6 +7,7 @@
*/ */
#include <arch.h> #include <arch.h>
#include <fb.h>
#include <log.h> #include <log.h>
#include <mem.h> #include <mem.h>
@ -14,7 +15,7 @@ static volatile uint64_t next_thread_id = 0;
static task_t *last_task = NULL; static task_t *last_task = NULL;
static task_t *kernel_task = NULL; static task_t *kernel_task = NULL;
task_t *current_task = NULL; task_t *current_task = NULL;
uint32_t *test_buf = NULL;
extern uint64_t full_init; extern uint64_t full_init;
void task_switch_asm(task_t *, task_t *); void task_switch_asm(task_t *, task_t *);
@ -22,41 +23,39 @@ void task_switch_asm(task_t *, task_t *);
void task_switch(struct frame *state) { void task_switch(struct frame *state) {
UNUSED(state); UNUSED(state);
// LOG("Смена потоков\n");
asm volatile("cli"); asm volatile("cli");
task_t *next = current_task->next; task_t *next = current_task->next;
task_t *last = current_task; task_t *last = current_task;
current_task = next; current_task = next;
// LOG("Смена потоков 2\n"); // LOG("Смена потоков %u->%u\n", last->id, next->id);
outb(0x20, 0x20);
task_switch_asm(last, next); task_switch_asm(last, next);
asm volatile("sti");
} }
uint64_t task_new_thread(void (*func)(void *), void *arg) { uint64_t task_new_thread(void (*func)(void *)) {
asm volatile("cli");
LOG("Выделение потока\n"); LOG("Выделение потока\n");
uint64_t cr3;
asm volatile("mov %%cr3, %0" : "=r"(cr3));
uint64_t cr3;
uint64_t *stack = mem_alloc(STACK_SIZE); uint64_t *stack = mem_alloc(STACK_SIZE);
task_t *new_task = mem_alloc(sizeof(task_t)); task_t *new_task = mem_alloc(sizeof(task_t));
asm volatile("mov %%cr3, %0" : "=r"(cr3));
tool_memset(stack, 0, STACK_SIZE); tool_memset(stack, 0, STACK_SIZE);
tool_memset(new_task, 0, sizeof(task_t)); tool_memset(new_task, 0, sizeof(task_t));
uint64_t *stack_top = (uint64_t *)((uint64_t)stack + STACK_SIZE);
*(--stack_top) = (uint64_t)arg;
*(--stack_top) = (uint64_t)func;
new_task->rsp = (uint64_t)new_task->stack + STACK_SIZE - sizeof(uint64_t) * 2;
new_task->stack = stack; new_task->stack = stack;
uint64_t stack_top = STACK_SIZE;
stack[--stack_top] = (uint64_t)stack;
stack[--stack_top] = (uint64_t)func;
stack[--stack_top] = (uint64_t)0;
new_task->rsp = (uint64_t)new_task->stack + sizeof(uint64_t) * stack_top;
new_task->id = next_thread_id++; new_task->id = next_thread_id++;
new_task->cr3 = cr3;
new_task->last = current_task; new_task->last = current_task;
new_task->next = current_task->next; new_task->next = current_task->next;
@ -65,14 +64,11 @@ uint64_t task_new_thread(void (*func)(void *), void *arg) {
LOG("Создан новый поток с ID: %u\n", new_task->id); LOG("Создан новый поток с ID: %u\n", new_task->id);
if (full_init) {
asm volatile("sti"); // Включаем прерывания
}
return new_task->id; return new_task->id;
} }
void dummy(uint64_t n) { void dummy( ) {
LOG("\t\tПривет! Я поток: %u\n", current_task->id);
for (;;) { asm volatile("hlt"); } for (;;) { asm volatile("hlt"); }
} }
@ -91,6 +87,7 @@ void task_init( ) {
kernel_task->id = next_thread_id++; kernel_task->id = next_thread_id++;
kernel_task->rsp = rsp; kernel_task->rsp = rsp;
kernel_task->cr3 = cr3;
current_task = kernel_task; current_task = kernel_task;
@ -99,7 +96,10 @@ void task_init( ) {
last_task = kernel_task; last_task = kernel_task;
// task_new_thread(dummy, 2 + 2); task_new_thread(dummy);
task_new_thread(dummy);
test_buf = mem_alloc(8 * 8 * sizeof(uint32_t));
LOG("Потоки инициализированы\n"); LOG("Потоки инициализированы\n");
} }

View File

@ -9,10 +9,11 @@ task_switch_asm:
movq %rdi, 40(%rdi) movq %rdi, 40(%rdi)
movq %rsp, 48(%rdi) movq %rsp, 48(%rdi)
movq %rbp, 56(%rdi) movq %rbp, 56(%rdi)
movq %cr3, %rax
movq %rax, 64(%rdi) movq %rax, 64(%rdi)
movq 64(%rsi), %rax movq 64(%rsi), %rax
movq %rax, 64(%rdi) movq %rax, %cr3
movq 56(%rsi), %rbp movq 56(%rsi), %rbp
movq 48(%rsi), %rsp movq 48(%rsi), %rsp
movq 40(%rsi), %rdi movq 40(%rsi), %rdi
@ -22,5 +23,5 @@ task_switch_asm:
movq (%rsi), %rax movq (%rsi), %rax
movq 32(%rsi), %rsi movq 32(%rsi), %rsi
popfq popfq
sti
retq retq

View File

@ -17,6 +17,11 @@
uint64_t full_init = 0; uint64_t full_init = 0;
void finally( ) {
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
for (;;) { asm volatile("hlt"); }
}
// Точка входа // Точка входа
void _start( ) { void _start( ) {
asm volatile("cli"); asm volatile("cli");
@ -33,17 +38,16 @@ void _start( ) {
LOG("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__); LOG("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
task_init( );
pit_init( );
mod_init( ); mod_init( );
pit_init( );
task_init( );
LOG("Готово! Для выхода из симуляции удерживайте: ESCAPE\n"); task_new_thread(finally);
full_init = 1; full_init = 1;
asm volatile("sti"); asm volatile("sti");
mod_after_init( ); // mod_after_init( );
for (;;) { asm volatile("hlt"); } for (;;) { asm volatile("hlt"); }
} }