9 #include "sys/scheduler.h"
10 #include "lib/string.h"
24 extern uint32_t init_esp;
26 bool scheduler_working =
true;
28 extern physical_addr_t kernel_page_directory;
35 __asm__
volatile(
"mov %%esp, %0" :
"=a"(esp));
38 __asm__
volatile (
"cli");
44 kernel_proc = (process_t*)kcalloc(
sizeof(process_t), 1);
74 __asm__
volatile (
"sti");
82 void scheduler_mode(
bool on) {
83 scheduler_working = on;
86 size_t create_process(
void* entry_point,
char name[256],
bool suspend,
bool is_kernel) {
87 scheduler_working =
false;
88 __asm__
volatile(
"cli");
90 process_t* proc = (process_t*)kcalloc(1,
sizeof(process_t));
93 proc->list_item.list =
nullptr;
94 proc->threads_count = 0;
97 proc->suspend = suspend;
103 qemu_log(
"PID: %d, DIR: %x; Threads: %d; Suspend: %d", proc->pid, proc->page_dir, proc->threads_count, proc->suspend);
107 void* virt = clone_kernel_page_directory(proc->page_tables_virts);
108 uint32_t phys = virt2phys(get_kernel_page_directory(), (virtual_addr_t) virt);
110 proc->page_dir = phys;
112 qemu_log(
"FINISHED!");
114 __asm__
volatile(
"sti");
115 scheduler_working =
true;
148 bool kernel,
bool suspend) {
149 void* stack =
nullptr;
153 thread_t* tmp_thread = (thread_t*) kcalloc(
sizeof(thread_t), 1);
156 memset(tmp_thread, 0,
sizeof(thread_t));
160 tmp_thread->list_item.list =
nullptr;
161 tmp_thread->process = proc;
162 tmp_thread->stack_size = stack_size;
163 tmp_thread->suspend = suspend;
164 tmp_thread->entry_point = (uint32_t) entry_point;
167 stack = (
void*) kcalloc(stack_size, 1);
169 tmp_thread->stack = stack;
170 tmp_thread->esp = (uint32_t) stack + stack_size - (7 * 4);
171 tmp_thread->stack_top = (uint32_t) stack + stack_size;
177 proc->threads_count++;
182 uint32_t* esp = (uint32_t*) ((
char*)stack + stack_size);
185 __asm__
volatile (
"pushf; pop %0":
"=r"(eflags));
189 esp[-1] = (uint32_t) blyat_fire;
190 esp[-2] = (uint32_t) entry_point;
200 thread_t* thread_create(process_t* proc,
void* entry_point,
size_t stack_size,
201 bool kernel,
bool suspend){
203 __asm__
volatile (
"cli");
209 __asm__
volatile (
"sti");
211 qemu_ok(
"CREATED THREAD");
223 thread->suspend = suspend;
233 __asm__
volatile (
"cli");
244 thread->state = DEAD;
247 __asm__
volatile (
"mov %0, %%ecx"::
"a"(&task_switch_v2_wrapper));
250 __asm__
volatile (
"sti");
253 __asm__
volatile (
"call *%ecx");
266 thread_t* next_thread = (thread_t *)
current_thread->list_item.next;
268 while(next_thread->state == PAUSED || next_thread->state == DEAD) {
269 thread_t* next_thread_soon = (thread_t *)next_thread->list_item.next;
271 if(next_thread->state == DEAD) {
272 qemu_log(
"QUICK NOTICE: WE ARE IN PROCESS NR. #%u",
current_proc->pid);
274 process_t* process = next_thread->process;
275 qemu_log(
"REMOVING DEAD THREAD: #%u", next_thread->id);
277 list_remove(&next_thread->list_item);
279 qemu_log(
"REMOVED FROM LIST");
281 kfree(next_thread->stack);
284 qemu_log(
"FREED MEMORY");
286 process->threads_count--;
288 qemu_log(
"MODIFIED PROCESS");
291 if(process->threads_count == 0 && is_krnl_process) {
293 qemu_log(
"PROCESS #%d `%s` DOES NOT HAVE ANY THREADS", process->pid, process->name);
297 for(
size_t pt = 0; pt < 1024; pt++) {
298 size_t page_table = process->page_tables_virts[pt];
302 qemu_note(
"[%d] FREE PAGE TABLE AT: %x", pt, page_table);
303 kfree((
void *) page_table);
308 qemu_log(
"FREED PAGE TABLES");
310 kfree((
void *) process->page_dir_virt);
312 qemu_log(
"FREED SPACE FOR TABLES");
314 list_remove(&process->list_item);
316 qemu_log(
"REMOVED PROCESS FROM LIST");
320 qemu_log(
"FREED PROCESS LIST ITEM");
324 next_thread = next_thread_soon;
void * memset(void *ptr, char value, size_t num)
Заполнение массива указанными символами
int strcpy(char *dest, const char *src)
Копирование строк
volatile process_t * get_current_proc(void)
Получить текущий обработчик процесса
void thread_exit(thread_t *thread)
Завершить текущий поток
list_t process_list
Список процессов
list_t thread_list
Список потоков
thread_t * _thread_create_unwrapped(process_t *proc, void *entry_point, size_t stack_size, bool kernel, bool suspend)
Создание потока
void init_task_manager(void)
Инициализация менеджера задач
thread_t * kernel_thread
Обработчик основного потока ядра
process_t * kernel_proc
Обработчик процесса ядра
void thread_suspend(thread_t *thread, bool suspend)
Остановить поток
uint32_t next_pid
Следующий ID задачи (PID)
bool multi_task
Готова ли система к многозадачности
thread_t * current_thread
Текущий поток
process_t * current_proc
Текущий процесс
uint32_t next_thread_id
Следующий ID потока
bool is_multitask(void)
Получение состояния о мультипотоке