core: refactor fork function
This commit is contained in:
@ -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;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user