core: refactor fork function

This commit is contained in:
0x35c
2025-11-30 14:30:04 +01:00
parent 896a0a04f9
commit 274113a401

View File

@ -4,21 +4,6 @@
#include "string.h" #include "string.h"
#include "thread.h" #include "thread.h"
static struct tcb *thread_clone(struct tcb *thread)
{
struct tcb *new_tcb = umalloc(sizeof(struct tcb));
if (!new_tcb)
return NULL;
new_tcb->tid = thread->tid;
new_tcb->esp0 = kalloc_pages(STACK_SIZE);
if (!new_tcb->esp0) {
delete_thread(new_tcb);
return NULL;
}
memcpy(new_tcb->esp0, thread->esp0, STACK_SIZE);
return new_tcb;
}
static void free_pts(void) static void free_pts(void)
{ {
for (size_t i = USER_PT_END / 2; PD[i]; i++) { for (size_t i = USER_PT_END / 2; PD[i]; i++) {
@ -49,6 +34,32 @@ static int copy_pt(uint32_t *pt_src, uint32_t *pt_dest, size_t pd_index)
return 0; return 0;
} }
static int copy_thread_list(struct pcb *new_pcb)
{
struct list *e;
struct list *prev = NULL;
for (struct list *it = current_pcb->thread_list; it; it = it->next) {
e = kmalloc(sizeof(struct list));
if (!e)
return -1;
if (prev)
prev->next = e;
else
new_pcb->thread_list = e;
struct tcb *new_content = kmalloc(sizeof(struct tcb));
if (!new_content) {
kfree(e);
return -1;
}
memcpy(new_content, it->content, sizeof(struct tcb));
new_content->process = new_pcb;
e->next = NULL;
e->content = new_content;
prev = e;
}
return 0;
}
static int deep_copy(struct pcb *new_pcb) static int deep_copy(struct pcb *new_pcb)
{ {
if (PD[USER_PT_END / 2]) if (PD[USER_PT_END / 2])
@ -69,6 +80,8 @@ static int deep_copy(struct pcb *new_pcb)
new_pcb->heap[i] = (uint32_t)new_pt | INIT_FLAGS; new_pcb->heap[i] = (uint32_t)new_pt | INIT_FLAGS;
} }
bzero(PD + USER_PT_END / 2, i * sizeof(uint32_t)); bzero(PD + USER_PT_END / 2, i * sizeof(uint32_t));
if (copy_thread_list(new_pcb) < 0)
return -1;
return 0; return 0;
} }
@ -85,32 +98,10 @@ pid_t fork(void)
new_pcb->daddy = current_pcb; new_pcb->daddy = current_pcb;
lst_add_back(&current_pcb->children, new_node); lst_add_back(&current_pcb->children, new_node);
if (deep_copy(new_pcb) < 0) if (deep_copy(new_pcb) < 0) {
goto error;
struct list *e;
struct list *prev = NULL;
for (struct list *it = current_pcb->thread_list; it; it = it->next) {
e = kmalloc(sizeof(struct list));
if (!e)
goto error;
if (prev)
prev->next = e;
else
new_pcb->thread_list = e;
struct tcb *new_content = kmalloc(sizeof(struct tcb));
if (!new_content) {
kfree(e);
goto error;
}
memcpy(new_content, it->content, sizeof(struct tcb));
new_content->process = new_pcb;
e->next = NULL;
e->content = new_content;
prev = e;
}
return current_pcb == new_pcb ? 0 : new_pcb->pid;
error:
remove_process(new_pcb); remove_process(new_pcb);
return -1; return -1;
} }
return current_pcb == new_pcb ? 0 : new_pcb->pid;
}