mirror of https://github.com/0Nera/BMOSP.git
Создание тестового менеджера потоков
This commit is contained in:
parent
b9d186cc2f
commit
224256a8ac
|
@ -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
|
|
@ -1,3 +1,3 @@
|
|||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 1
|
||||
#define VERSION_BUILD 899
|
||||
#define VERSION_BUILD 905
|
||||
|
|
|
@ -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, "БМПОС");
|
||||
}
|
|
@ -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 (;;) {
|
||||
|
|
106
kernel/task.c
106
kernel/task.c
|
@ -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");
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue