53 lines
1.1 KiB
C
53 lines
1.1 KiB
C
#include "thread.h"
|
|
#include "alloc.h"
|
|
#include "assert.h"
|
|
#include "interrupts.h"
|
|
#include "memory.h"
|
|
#include "string.h"
|
|
#include "thread.h"
|
|
|
|
struct tcb *create_thread(struct pcb *process, void (*routine)(void))
|
|
{
|
|
static uint32_t tid = 1;
|
|
struct tcb *new_tcb = vmalloc(sizeof(struct tcb));
|
|
if (!new_tcb)
|
|
return NULL;
|
|
new_tcb->tid = tid++;
|
|
|
|
new_tcb->esp0 = alloc_pages(STACK_SIZE, NULL);
|
|
if (!new_tcb->esp0) {
|
|
vfree(new_tcb);
|
|
return NULL;
|
|
}
|
|
// set esp to "skip" the 4 GPRs and eip later to be used as the context
|
|
// of the thread
|
|
new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4;
|
|
memcpy(new_tcb->esp + 4, routine, 4);
|
|
new_tcb->process = process;
|
|
new_tcb->next = NULL;
|
|
new_tcb->state = NEW;
|
|
|
|
struct tcb *it = process->thread_list;
|
|
if (it) {
|
|
while (it)
|
|
it = it->next;
|
|
it = new_tcb;
|
|
}
|
|
else {
|
|
process->thread_list = new_tcb;
|
|
}
|
|
|
|
return new_tcb;
|
|
}
|
|
|
|
void delete_thread(struct tcb *thread)
|
|
{
|
|
vfree(thread->esp0);
|
|
struct tcb *it = thread->process->thread_list;
|
|
assert(it);
|
|
while (it->next != thread)
|
|
it = it->next;
|
|
it->next = it->next->next;
|
|
vfree(thread);
|
|
}
|