예제 #1
0
int
sys_fork(struct trapframe* tf, pid_t* retval)
{
    DEBUG(DB_EXEC,"sys_fork(): entering\n");
    KASSERT(curproc != NULL);
    KASSERT(sizeof(struct trapframe)==(37*4));

    char* child_name = kmalloc(sizeof(char)* NAME_MAX);
    strcpy(child_name, curproc->p_name);
    strcat(child_name, "_c");

    // create PCB for child
    struct proc* child_proc = NULL;
    proc_fork(&child_proc);
    if (child_proc == NULL)
    {
        return ENOMEM;
    }
    strcpy(child_proc->p_name, child_name);
    
    KASSERT(child_proc->p_pid > 0);

    // copy address space and registers from this process to child
    struct addrspace* child_as = kmalloc(sizeof(struct addrspace));
    if (child_as == NULL)
    {
        kfree(child_name);
        proc_destroy(child_proc);
        return ENOMEM;
    }

    struct trapframe* child_tf = kmalloc(sizeof(struct trapframe));
    if (child_tf == NULL)
    {
        kfree(child_name);
        as_destroy(child_as);
        proc_destroy(child_proc);
        return ENOMEM;
    }

    DEBUG(DB_EXEC,"sys_fork(): copying address space...\n");
    // copy the address space just created into the child process's
    // PCB structure
    int result = as_copy(curproc->p_addrspace, &child_as);
    if (result)
    {
        kfree(child_name);
        as_destroy(child_as);
        proc_destroy(child_proc);
        return result;
    }
    child_proc->p_addrspace = child_as;

    DEBUG(DB_EXEC,"sys_fork(): copying trapframe space...\n");
    // copy this process's trapframe to the child process
    memcpy(child_tf, tf, sizeof(struct trapframe));

    
    DEBUG(DB_EXEC, "sys_fork(): copying filetable...\n");
    filetable_copy(curproc->p_filetable,&child_proc->p_filetable);

    DEBUG(DB_EXEC,"sys_fork(): assigning child process's parent as this process...\n");
    // assign child processes parent as this process
    child_proc->p_parent = curproc;

    DEBUG(DB_EXEC,"sys_fork(): adding child to children procarray...\n");
    result = procarray_add(&curproc->p_children, child_proc, NULL);
    if (result)
    {
        DEBUG(DB_EXEC, "sys_fork(): failed to add child process to proc_table...\n");
    }

    DEBUG(DB_EXEC,"sys_fork(): allocating data...\n");
    void **data = kmalloc(2*sizeof(void*));
    data[0] = (void*)child_tf;
    data[1] = (void*)child_as;

    result = thread_fork(child_name, child_proc, &enter_forked_process, data, 0);
    if (result)
    {
        kfree(child_name);
        kfree(child_tf);
        as_destroy(child_as);
        proc_destroy(child_proc);
        return ENOMEM;
    }

    *retval = child_proc->p_pid;
    DEBUG(DB_EXEC, "sys_fork(): thread_fork returned: curproc=%u, child_proc=%u\n",curproc->p_pid,child_proc->p_pid);
    return 0;
}
예제 #2
0
pid_t sys_fork(struct trapframe *tf) {


	if(procarray_num(procarr) == PID_MAX - PID_MIN) {
		errno = EMPROC;
		return 0;
	}

	struct proc *newproc = kmalloc(sizeof(*newproc));

	// normal field
	newproc->p_name = kstrdup(curthread->t_proc->p_name);  // name
	newproc->p_cwd = curproc->p_cwd; // vnode
	
	// synch field
	spinlock_init(&newproc->p_lock);
	newproc->p_cv = cv_create("proc cv");
	newproc->p_lk = lock_create("proc lock");
	newproc->open_num = 0;

	// files field
	newproc->fd_table = kmalloc(sizeof(struct fd *) * MAX_fd_table);
	for(unsigned i = 0 ; i < MAX_fd_table ; i++) {
		newproc->fd_table[i] = curproc->fd_table[i];
	}

	// pid creation
	for(pid_t curid = PID_MIN ; curid <= PID_MAX ; curid++) { // loop through available pid range.
		if(find_proc(curid) == NULL) { // first available pid found.
			newproc->p_pid = curid; // set pid.
			break; // break loop.
		}
	}

	threadarray_init(&newproc->p_threads);
	spinlock_init(&newproc->p_lock);

	// copy threads
	// struct threadarray oldthreads = curproc->p_threads;
	pid_t result;

	procarray_add(procarr,newproc,NULL);

	struct exitc *c = kmalloc(sizeof(struct exitc));
	c->exitcode = -1;
	c->pid = newproc->p_pid;
	exitcarray_add(codes,c,NULL);

	// fork thread
	// struct thread *t = threadarray_get(&oldthreads,0);

	// copy trapframe to heap.
	struct trapframe *ctf = kmalloc(sizeof(struct trapframe));
	ctf->tf_vaddr = tf->tf_vaddr;
	ctf->tf_status = tf->tf_status;
	ctf->tf_cause = tf->tf_cause;
	ctf->tf_lo = tf->tf_lo;
	ctf->tf_hi = tf->tf_hi;
	ctf->tf_ra = tf->tf_ra;
	ctf->tf_at = tf->tf_at;
	ctf->tf_v0 = tf->tf_v0;
	ctf->tf_v1 = tf->tf_v1;
	ctf->tf_a0 = tf->tf_a0;
	ctf->tf_a1 = tf->tf_a1;
	ctf->tf_a2 = tf->tf_a2;
	ctf->tf_a3 = tf->tf_a3;
	ctf->tf_t0 = tf->tf_t0;
	ctf->tf_t1 = tf->tf_t1;
	ctf->tf_t2 = tf->tf_t2;
	ctf->tf_t3 = tf->tf_t3;
	ctf->tf_t4 = tf->tf_t4;
	ctf->tf_t5 = tf->tf_t5;
	ctf->tf_t6 = tf->tf_t6;
	ctf->tf_t7 = tf->tf_t7;
	ctf->tf_s0 = tf->tf_s0;
	ctf->tf_s1 = tf->tf_s1;
	ctf->tf_s2 = tf->tf_s2;
	ctf->tf_s3 = tf->tf_s3;
	ctf->tf_s4 = tf->tf_s4;
	ctf->tf_s5 = tf->tf_s5;
	ctf->tf_s6 = tf->tf_s6;
	ctf->tf_s7 = tf->tf_s7;
	ctf->tf_t8 = tf->tf_t8;
	ctf->tf_t9 = tf->tf_t9;
	ctf->tf_k0 = tf->tf_k0;
	ctf->tf_k1 = tf->tf_k1;
	ctf->tf_gp = tf->tf_gp;
	ctf->tf_sp = tf->tf_sp;
	ctf->tf_s8 = tf->tf_s8;
	ctf->tf_epc = tf->tf_epc;

	//int spl = splhigh();
	result = thread_fork(curthread->t_proc->p_name,
			newproc,	
			enter_forked_process, ctf, (unsigned long)curproc->p_addrspace
			);

	// parent return.
	//splx(spl);

	return newproc->p_pid;
}