2023-10-21 21:23:51 +03:00
|
|
|
|
/**
|
|
|
|
|
* task.c
|
|
|
|
|
* Управление потоками
|
|
|
|
|
*
|
|
|
|
|
* Данный файл содержит функции для создания и удаления потоков.
|
|
|
|
|
*
|
|
|
|
|
*/
|
2023-10-21 20:27:23 +03:00
|
|
|
|
|
2024-01-02 16:32:32 +03:00
|
|
|
|
#include <arch.h>
|
2024-01-13 00:00:11 +03:00
|
|
|
|
#include <log.h>
|
2024-01-02 16:32:32 +03:00
|
|
|
|
#include <mem.h>
|
2023-10-23 09:16:16 +03:00
|
|
|
|
|
2024-01-10 19:29:17 +03:00
|
|
|
|
static volatile uint64_t next_thread_id = 0;
|
|
|
|
|
static task_t *last_task = NULL;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
static task_t *kernel_task = NULL;
|
|
|
|
|
task_t *current_task = NULL;
|
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
extern uint64_t full_init;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
void task_switch_asm(task_t *, task_t *);
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
void task_switch(struct frame *state) {
|
|
|
|
|
UNUSED(state);
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-21 19:25:04 +03:00
|
|
|
|
// LOG("Смена потоков\n");
|
2024-01-20 19:04:26 +03:00
|
|
|
|
asm volatile("cli");
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
task_t *next = current_task->next;
|
|
|
|
|
task_t *last = current_task;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
current_task = next;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-21 19:25:04 +03:00
|
|
|
|
// LOG("Смена потоков 2\n");
|
2024-01-20 19:04:26 +03:00
|
|
|
|
task_switch_asm(last, next);
|
|
|
|
|
asm volatile("sti");
|
2024-01-02 16:32:32 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
uint64_t task_new_thread(void (*func)(void *), void *arg) {
|
2024-01-10 19:29:17 +03:00
|
|
|
|
asm volatile("cli");
|
|
|
|
|
|
2024-01-02 16:32:32 +03:00
|
|
|
|
LOG("Выделение потока\n");
|
2024-01-20 19:04:26 +03:00
|
|
|
|
uint64_t cr3;
|
|
|
|
|
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
uint64_t *stack = mem_alloc(STACK_SIZE);
|
2024-01-02 16:32:32 +03:00
|
|
|
|
task_t *new_task = mem_alloc(sizeof(task_t));
|
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
tool_memset(stack, 0, STACK_SIZE);
|
2024-01-10 19:29:17 +03:00
|
|
|
|
tool_memset(new_task, 0, sizeof(task_t));
|
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
uint64_t *stack_top = (uint64_t *)((uint64_t)stack + STACK_SIZE);
|
2024-01-10 19:29:17 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
*(--stack_top) = (uint64_t)arg;
|
|
|
|
|
*(--stack_top) = (uint64_t)func;
|
2024-01-10 19:29:17 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
new_task->rsp = (uint64_t)new_task->stack + STACK_SIZE - sizeof(uint64_t) * 2;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-10 19:29:17 +03:00
|
|
|
|
new_task->stack = stack;
|
2024-01-20 19:04:26 +03:00
|
|
|
|
new_task->id = next_thread_id++;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
new_task->last = current_task;
|
|
|
|
|
new_task->next = current_task->next;
|
|
|
|
|
current_task->next->last = new_task;
|
|
|
|
|
current_task->next = new_task;
|
2024-01-02 16:32:32 +03:00
|
|
|
|
|
|
|
|
|
LOG("Создан новый поток с ID: %u\n", new_task->id);
|
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
if (full_init) {
|
|
|
|
|
asm volatile("sti"); // Включаем прерывания
|
|
|
|
|
}
|
2023-10-21 20:27:23 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
return new_task->id;
|
|
|
|
|
}
|
2024-01-14 15:28:12 +03:00
|
|
|
|
|
2024-01-20 19:04:26 +03:00
|
|
|
|
void dummy(uint64_t n) {
|
2024-01-21 19:25:04 +03:00
|
|
|
|
for (;;) { asm volatile("hlt"); }
|
2024-01-13 00:00:11 +03:00
|
|
|
|
}
|
|
|
|
|
|
2024-01-02 16:32:32 +03:00
|
|
|
|
void task_init( ) {
|
2024-01-20 19:04:26 +03:00
|
|
|
|
asm volatile("cli");
|
|
|
|
|
idt_set_int(32, task_switch);
|
2024-01-14 15:28:12 +03:00
|
|
|
|
|
2024-01-10 19:29:17 +03:00
|
|
|
|
uint64_t rsp;
|
|
|
|
|
uint64_t cr3;
|
|
|
|
|
|
|
|
|
|
asm volatile("mov %%rsp, %0" : "=r"(rsp));
|
|
|
|
|
asm volatile("mov %%cr3, %0" : "=r"(cr3));
|
|
|
|
|
|
|
|
|
|
kernel_task = mem_alloc(sizeof(task_t));
|
|
|
|
|
tool_memset(kernel_task, 0, sizeof(task_t));
|
2024-01-20 19:04:26 +03:00
|
|
|
|
|
2024-01-10 19:29:17 +03:00
|
|
|
|
kernel_task->id = next_thread_id++;
|
|
|
|
|
kernel_task->rsp = rsp;
|
|
|
|
|
|
|
|
|
|
current_task = kernel_task;
|
2024-01-20 19:04:26 +03:00
|
|
|
|
|
|
|
|
|
current_task->last = current_task;
|
|
|
|
|
current_task->next = current_task;
|
|
|
|
|
|
2024-01-10 19:29:17 +03:00
|
|
|
|
last_task = kernel_task;
|
|
|
|
|
|
2024-01-21 19:25:04 +03:00
|
|
|
|
// task_new_thread(dummy, 2 + 2);
|
2024-01-20 19:04:26 +03:00
|
|
|
|
|
2024-01-02 16:32:32 +03:00
|
|
|
|
LOG("Потоки инициализированы\n");
|
|
|
|
|
}
|