core: refactor fork function
This commit is contained in:
@ -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(¤t_pcb->children, new_node);
|
lst_add_back(¤t_pcb->children, new_node);
|
||||||
|
|
||||||
if (deep_copy(new_pcb) < 0)
|
if (deep_copy(new_pcb) < 0) {
|
||||||
goto error;
|
remove_process(new_pcb);
|
||||||
struct list *e;
|
return -1;
|
||||||
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;
|
return current_pcb == new_pcb ? 0 : new_pcb->pid;
|
||||||
error:
|
|
||||||
remove_process(new_pcb);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user