mirror of
https://github.com/0Nera/BMOSP.git
synced 2024-11-23 00:51:54 +03:00
Поддержка многопоточности
This commit is contained in:
parent
90cf91ee31
commit
c4b8ec6787
@ -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( );
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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"); }
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user