Создание тестового менеджера потоков

This commit is contained in:
Aren Elchinyan 2024-01-02 16:32:32 +03:00
parent b9d186cc2f
commit 224256a8ac
5 changed files with 144 additions and 28 deletions

View File

@ -12,6 +12,14 @@
#include <stdint.h>
#define STACK_SIZE 8192 // 1MB
typedef struct task {
uint64_t id;
struct frame *state;
struct task *next;
} __attribute__((packed)) task_t;
struct frame {
uint64_t rbp;
uint64_t rbx;
@ -40,6 +48,8 @@ struct frame {
typedef void (*int_entry_t)(struct frame *state);
void arch_init( );
void task_init( );
void task_switch(struct frame *state);
void cpu_init( );
void gdt_init( );
void pic_init( );
@ -74,4 +84,14 @@ static inline void io_wait( ) {
outb(0x80, 0);
}
static inline void print_stack_trace( ) {
uint64_t *rsp;
asm volatile("movq %%rsp, %0;" : "=g"(rsp));
while (rsp) {
// fb_printf("%x\n", *rsp);
rsp = (uint64_t *)(*rsp);
}
}
#endif // arch.h

View File

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

View File

@ -12,23 +12,7 @@
#include <stdint.h>
#include <tool.h>
static volatile uint64_t count = 0;
static volatile uint64_t test_color = 0x00D000;
extern uint32_t width;
static void isr_local( ) {
if (test_color >= 0xFFFFFF) { test_color = 0x00D000; }
uint32_t last = fb_get_text_color( );
fb_set_text_color(test_color);
fb_printf_at(SCREEN_WIDTH - 6 * 7, 0, "БМПОС");
fb_set_text_color(last);
count++;
test_color += 0x010101;
}
extern void task_switch(struct frame *state);
void pit_set_interval(int hz) {
int divisor = 1193180 / hz; // Вычисляем делитель
@ -38,7 +22,6 @@ void pit_set_interval(int hz) {
}
void pit_init( ) {
idt_set_int(32, isr_local);
idt_set_int(32, task_switch);
pit_set_interval(1);
fb_printf_at(SCREEN_WIDTH - 6 * 7, 0, "БМПОС");
}

View File

@ -16,7 +16,15 @@
#include <version.h>
char (*getc)( );
extern task_t* current_task;
// Пример функции, которую будем выполнять в разных потоках
static void test_task(void* arg) {
fb_printf("\n\t\t[%u]\n", current_task->id);
for (;;) {}
}
char* msg = "123!!!!";
// Точка входа
void _start( ) {
asm volatile("cli");
@ -33,13 +41,14 @@ void _start( ) {
fb_printf("\t\t\t\t *** Дата сборки: %s %s ***\n", __DATE__, __TIME__);
fb_set_text_color(0x00D000);
task_init( );
pit_init( );
mod_init( );
// mod_init( );
fb_set_text_color(0x00FF00);
fb_printf("Готово! Для выхода из симуляции удерживайте: ESCAPE\n");
module_info_t *mod = mod_find("[KEYBOARD]");
module_info_t* mod = mod_find("[KEYBOARD]");
if (mod == NULL) {
fb_set_text_color(0xFF0000);
@ -52,6 +61,16 @@ void _start( ) {
fb_set_text_color(0x00D000);
// Создаем новый поток и передаем ему аргумент
fb_printf("\tСоздаем новый поток и передаем ему аргумент\n");
task_t* thread1 = task_new_thread(&test_task, &msg);
// Создаем новый поток и передаем ему аргумент
fb_printf("\tСоздаем новый поток и передаем ему аргумент\n");
task_t* thread2 = task_new_thread(test_task, &msg);
// Переключаем контекст на первый поток
// task_switch(thread1->state);
asm volatile("sti");
for (;;) {

View File

@ -6,12 +6,106 @@
*
*/
void task_init( ) {}
#include <arch.h>
#include <fb.h>
#include <mem.h>
void task_new_thread( ) {
return;
static volatile uint64_t pid = 0;
static task_t *kernel_task = NULL;
task_t *current_task = NULL;
void task_switch(struct frame *state) {
// Смена потоков
task_t *prev_task = current_task;
if (current_task == NULL) { return; }
LOG("Смена потоков %u -> ", current_task->id);
current_task = current_task->next;
if (current_task == NULL) {
// LOG("current_task == NULL\n");
// LOG("current_task = kernel_task\n");
current_task = kernel_task;
}
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");
}
void task_delete_thread( ) {
return;
task_t *task_new_thread(void (*func)(void *), void *arg) {
LOG("Выделение потока\n");
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));
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;
if (kernel_task == NULL) {
LOG("Ядро ID: %u\n", new_task->id);
kernel_task = new_task;
current_task = new_task;
}
if (current_task != new_task) {
LOG("Прошлый ID: %u\n", current_task->id);
current_task->next = new_task;
}
LOG("Создан новый поток с ID: %u\n", new_task->id);
return new_task;
}
void task_init( ) {
idt_set_int(32, task_switch);
LOG("Потоки инициализированы\n");
}