diff --git a/src/multitasking/fork.c b/src/multitasking/fork.c index f34efe9..bacc061 100644 --- a/src/multitasking/fork.c +++ b/src/multitasking/fork.c @@ -4,21 +4,6 @@ #include "string.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) { 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; } +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) { 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; } bzero(PD + USER_PT_END / 2, i * sizeof(uint32_t)); + if (copy_thread_list(new_pcb) < 0) + return -1; return 0; } @@ -85,32 +98,10 @@ pid_t fork(void) new_pcb->daddy = current_pcb; lst_add_back(¤t_pcb->children, new_node); - 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; + if (deep_copy(new_pcb) < 0) { + remove_process(new_pcb); + return -1; } return current_pcb == new_pcb ? 0 : new_pcb->pid; -error: - remove_process(new_pcb); - return -1; }