Files
42_KFS/src/multitasking/thread.c
2025-11-12 15:07:36 +01:00

81 lines
2.0 KiB
C

#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);
}