#include "thread.h" #include "alloc.h" #include "assert.h" #include "interrupts.h" #include "list.h" #include "memory.h" #include "process.h" #include "string.h" #include "thread.h" struct tcb *create_thread(struct pcb *process, void (*entry)(void)) { struct tcb *new_tcb = vmalloc(sizeof(struct tcb)); if (!new_tcb) return NULL; new_tcb->tid = process->tid++; new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL); if (!new_tcb->esp0) { vfree(new_tcb); return NULL; } uint32_t *stack = (uint32_t *)((uint8_t *)new_tcb->esp0 + STACK_SIZE); uint32_t *esp = stack; // testing out some stuff *(--stack) = 0x202; // EFLAGS *(--stack) = 0x08; // CS = kernel code segment *(--stack) = (uint32_t)entry; // Error code and interrupt number (skipped by add $8, %esp) *(--stack) = 0; // err_code *(--stack) = 0; // int_no // General purpose registers (for popa) *(--stack) = 0; // EAX *(--stack) = 0; // ECX *(--stack) = 0; // EDX *(--stack) = 0; // EBX *(--stack) = (uint32_t)esp; // ESP (original - points to exit_process) *(--stack) = 0; // EBP *(--stack) = 0; // ESI *(--stack) = 0; // EDI *(--stack) = 0x10; // kernel DS new_tcb->esp = stack; new_tcb->process = process; new_tcb->state = NEW; struct list *new_node = vmalloc(sizeof(struct list)); if (!new_node) { free_pages(new_tcb->esp0, STACK_SIZE); vfree(new_tcb); return NULL; } new_node->content = new_tcb; new_node->next = NULL; if (process->thread_list == NULL) { process->thread_list = new_node; } else { struct list *it = process->thread_list; while (it->next) it = it->next; it->next = new_node; } return new_tcb; } void delete_thread(struct tcb *thread) { vfree(thread->esp0); struct list *it = thread->process->thread_list; assert(it); while (it->next && it->next->content != thread) it = it->next; struct list *to_free = it; it->next = it->next->next; vfree(to_free); vfree(thread); }