void enter_process(void *tf,unsigned long addr) { struct trapframe *childframe,child_tf; struct addrspace *childspace; if(tf!=NULL) { tf = (struct trapframe *) tf; childframe = tf; //copy the trapframe info now into the child_tf // child_tf = *childframe; memcpy(&child_tf,tf,sizeof(struct trapframe)); child_tf.tf_a3=0; child_tf.tf_v0=0; child_tf.tf_epc +=4; pid_t parentid = (pid_t)addr; if(process_array[curthread->t_pid]->parent_id!=parentid) process_array[curthread->t_pid]->parent_id=parentid; if(!(curthread->t_addrspace==NULL)) { childspace = curthread->t_addrspace; as_activate(childspace); } mips_usermode(&child_tf); } }
void md_forkentry(struct trapframe *tf,unsigned long addrspace_copy) { /* * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ //(void)tf; //kprintf("\n md_forkentry"); tf->tf_v0=0; tf->tf_a3=0; curthread->t_vmspace=(struct addrspace*)addrspace_copy; if(curthread->t_vmspace!=NULL){ as_activate(curthread->t_vmspace); } //copy modified trap frame from kernel heap to stack struct trapframe tf_temp=*tf;//=kmalloc(sizeof(struct trapframe)); tf_temp.tf_v0=tf->tf_v0; tf_temp.tf_a0=tf->tf_a0; tf_temp.tf_a1=tf->tf_a1; tf_temp.tf_a2=tf->tf_a2; tf_temp.tf_a3=tf->tf_a3; tf->tf_epc+=4; mips_usermode(&tf_temp); }
void md_forkentry(struct trapframe *tf, unsigned int vmspace) { struct trapframe child_kstack; /* copy trapframe of parent to chile procss*/ memcpy(&child_kstack, tf, sizeof(struct trapframe)); /* release trapframe when allocated at function process*/ kfree(tf); /* activate addrspace*/ as_activate((struct addrspace *)vmspace); /* increment pc*/ child_kstack.tf_epc += 4; child_kstack.tf_v0 = 0; child_kstack.tf_a3 = 0; /* release lock so that other process can execute process_fork*/ // lock_release(forklock); /* execute chile process*/ mips_usermode(&child_kstack); }
/* This is the entry point of the forked child process */ int md_forkentry(void* tf, unsigned long vmspace) { // int spl = splhigh(); //kprintf(" process %d is in enter md_forkentry\n",curthread->pID); struct trapframe child_tf; struct trapframe *tf_parent = (struct trapframe*) tf; assert(tf_parent != NULL); // memcpy(child_tf, tf, sizeof(struct trapframe)); tf_parent->tf_epc += 4; //we set the return value to be 0. tf_parent->tf_v0 = 0; tf_parent->tf_a3 = 0; // Load Address Space of Child and Activate it. curthread->t_vmspace = (struct addrspace*)vmspace; assert(curthread->t_vmspace != NULL); as_activate(curthread->t_vmspace); child_tf = *tf_parent; mips_usermode(&child_tf); // we should never reach here panic("switching to user mode returned\n"); return 0; }
void md_forkentry(struct trapframe *tf, unsigned long child_addr) { /* this function is basically for the child thread, remember the threadfor in sys_fork, it calls the md_forkentry and passed in new TF and addressspace and the child_thread. */ //kprintf("just enter forkentry\n"); struct trapframe* modifiy_tf; struct trapframe dumbvalue; struct addrspace* new_addr = (struct addrspace*) child_addr; modifiy_tf= kmalloc(sizeof(struct trapframe)); //kprintf("just enter memcpy modified tf and tf\n"); memcpy(modifiy_tf, tf, sizeof(struct trapframe)); //kprintf("just after memcpy modified tf and tf\n"); //*modifiy_tf = *tf; modifiy_tf->tf_v0 = 0; modifiy_tf->tf_a3 = 0; modifiy_tf->tf_epc +=4; curthread->t_vmspace = new_addr; //activie the addressspace //kprintf("activate thread -- pid: %d\n", curthread->t_pid); as_activate(curthread->t_vmspace); //memcpy(dumbvalue, tf, sizeof(struct trapframe)); //kprintf("just enter dumbvalue =*tf\n"); dumbvalue = *modifiy_tf; //kprintf("just leave dumbvalue =*tf\n"); mips_usermode(&dumbvalue); }
void forkentry(void *tf, unsigned long child_addrs ) { (void)child_addrs; int *temp; struct trapframe my_tf; int s = splhigh(); if((curthread->errflag)==1){ splx(s); sysexit(temp,tf); }else{ //DEBUG(1,"forkentry %d\n",curthread->ppid); memcpy(&my_tf, tf, sizeof(struct trapframe)); my_tf.tf_a3 = 0; my_tf.tf_epc +=4; my_tf.tf_v0 = 0; splx(s); kfree(tf); mips_usermode(&my_tf); } }
void md_forkentry(void * data1, unsigned long unused) { //(void)unused; struct fork_info * info = data1; struct addrspace * new_as; struct trapframe new_tf; /* copy address space */ if (as_copy(info->parent->t_vmspace, &new_as)) { info->child_pid = ENOMEM; // Means no memory for process V(info->sem); // child is done, parent should resume. thread_exit(); } curthread->t_vmspace = new_as; as_activate(new_as); /* copy trap frame */ memcpy(&new_tf, info->tf, sizeof(struct trapframe)); /* change tf's registers to return values for syscall */ new_tf.tf_v0 = 0; new_tf.tf_a3 = 0; new_tf.tf_epc += 4; /* create process and get the pid */ struct thread *new_process = kmalloc(sizeof(struct thread)); new_process->parent_pid = curthread->t_pid; proc_table++; new_process->t_pid = create_tpid(); proc_table++; V(info->sem); mips_usermode(&new_tf); /* mips_usermode does not return */ }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(struct trapframe *tf) { KASSERT(tf); struct trapframe newtf=*tf; kfree(tf); newtf.tf_v0=0; newtf.tf_a0=0; newtf.tf_epc += 4; mips_usermode(&newtf); (void)tf; }
/* * md_usermode: go to user mode after loading an executable. * * Works by creating an ersatz trapframe and jumping into the middle * of the exception return code. */ void md_usermode(int argc, userptr_t argv, vaddr_t stack, vaddr_t entry) { struct trapframe tf; bzero(&tf, sizeof(tf)); tf.tf_status = CST_IRQMASK | CST_IEp | CST_KUp; tf.tf_epc = entry; tf.tf_a0 = argc; tf.tf_a1 = (vaddr_t)argv; tf.tf_sp = stack; mips_usermode(&tf); }
/* * Enter user mode for a newly forked process. * * Succeed and return 0 into userspace. */ void enter_forked_process(struct trapframe *tf) { tf->tf_v0 = 0; tf->tf_a3 = 0; /* * Advance the PC. */ tf->tf_epc += 4; mips_usermode(tf); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(struct trapframe *tf) { #if OPT_A2 struct trapframe temptrap; memcpy(&temptrap, (void *)tf, sizeof(struct trapframe)); kfree(tf); temptrap.tf_v0 = 0; temptrap.tf_a3 = 0; temptrap.tf_epc += 4; mips_usermode(&temptrap); #else (void)tf; #endif /* OPT_A2 */ }
//void entry_point(void* data1, unsigned long data2) void enter_forked_process(void* data1, unsigned long data2) { //(void)tf; //kprintf("hi1"); struct trapframe tf = (*(struct trapframe*) data1); //struct trapframe new_tf; //memcpy(&new_tf,tf, sizeof(struct trapframe)); //new_tf = *tf; //(void) data2; tf.tf_a3 = 0; tf.tf_v0 = data2; tf.tf_epc += 4; //as_activate(); mips_usermode(&tf); //Enter user mode for newly forked process //kprintf("hi2"); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(struct trapframe *tf) { //kprintf("enter_forked_process \n"); #if OPT_A2 struct trapframe thisTF = *tf; //create tf on stack thisTF.tf_v0 =0; //child returns with 0 thisTF.tf_a3 =0; //error coding thisTF.tf_epc +=4; //counter as_activate(); mips_usermode(&thisTF); panic("Should not return from mips usermode\n"); #else (void)tf; #endif }
void child_process_entry(void *data1, unsigned long data2) { struct trapframe *tf = (struct trapframe *)data1 ; curthread->t_addrspace = (struct addrspace *)data2 ; as_activate(curthread->t_addrspace) ; struct trapframe usertf ; usertf = *tf; //memcpy(&usertf,tf ,sizeof(struct trapframe )); usertf.tf_v0 = 0 ; usertf.tf_a3 = 0 ; usertf.tf_epc += 4 ; kfree(tf) ; mips_usermode(&usertf) ; }
void child_fork_entry(void *data1, unsigned long data2) { struct trapframe *ctf = (struct trapframe *)data1; struct addrspace *caddr = (struct addrspace *)data2; ctf->tf_a3= 0; ctf->tf_v0= 0; ctf->tf_epc = ctf->tf_epc+4; curthread->t_addrspace = caddr; as_activate(curthread->t_addrspace); struct trapframe tf; memcpy(&tf,ctf,sizeof(struct trapframe)); mips_usermode(&tf); //KASSERT(SAME_STACK(cpustacks[curcpu->c_number]-1, (vaddr_t)tf_copy)); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(struct trapframe *tf) { #if OPT_A2 struct trapframe forkTf = *tf; forkTf.tf_a3 = 0; //signal no error forkTf.tf_v0 = 0; forkTf.tf_epc += 4; //advance the PC, to avoid the syscall again as_activate(); mips_usermode(&forkTf); panic("can't come here"); #else (void)tf; #endif //OPT_A2 }
void enter_forked_process(void *data1, unsigned long data2){ struct trapframe *childtf = ((void **)data1)[0]; struct addrspace *childas = ((void **)data1)[1]; // using local variable to put tf on stack struct trapframe local = *childtf; // switch to childas curproc_setas(childas); as_activate(); // set register local.tf_epc += 4; local.tf_v0 = 0; local.tf_a3 = 0; (void)data2; mips_usermode(&local); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(void* ptr, unsigned long args) { //panic("test"); //while(1) {} struct trapframe childtf; bzero(&childtf, sizeof(childtf)); childtf = *(struct trapframe *) ptr; childtf.tf_v0 = 0; childtf.tf_a3 = 0; childtf.tf_epc += 4; kfree(ptr); // load and activate the address space struct addrspace* as = (struct addrspace *) args; proc_setas(as); as_activate(); mips_usermode(&childtf); }
void child_forkentry(void *data1, unsigned long data2){ struct trapframe st_trapframe; struct trapframe* childtf = (struct trapframe*) data1; struct addrspace* childaddr = (struct addrspace*) data2; childtf->tf_v0 = 0; childtf->tf_a3 = 0; childtf->tf_epc += 4; memcpy(&st_trapframe, childtf, sizeof(struct trapframe)); kfree(childtf); childtf = NULL; curproc->p_addrspace = childaddr; as_activate(); mips_usermode(&st_trapframe); };
void md_forkentry(struct fork_data *fd, unsigned long un) { (void) un; struct trapframe local_tf; local_tf = *(fd->tf); curthread->t_vmspace = fd->addr; as_activate(curthread->t_vmspace); kfree(fd->tf); kfree(fd); local_tf.tf_epc += 4; local_tf.tf_a3 = 0; local_tf.tf_v0 = 0; mips_usermode(&local_tf); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(void *tf, unsigned long arg) { #if OPT_A2 (void) arg; as_activate(); //activate the address space struct trapframe stacktf; stacktf = *(struct trapframe *) tf; //copy the trapframe stacktf.tf_v0 = 0; stacktf.tf_a3 = 0; stacktf.tf_epc = stacktf.tf_epc + 4; kfree(tf); mips_usermode(&stacktf); return; #else (void)tf; (void)arg; #endif }
void md_forkentry(struct trapframe *tf,unsigned long as_data) { struct trapframe tf_local; struct trapframe *newtf; struct addrspace *newas = (struct addrspace*) as_data; tf_local = *tf; newtf = &tf_local; newtf->tf_v0 = 0; newtf->tf_a3 = 0; newtf->tf_epc += 4; kfree(tf); curthread->t_vmspace = newas; as_activate(curthread->t_vmspace); mips_usermode(&tf_local); }
void md_forkentry(struct trapframe *tf) { /* * This function is used to copy the trap frame of the parent process into * the the child's and return the child process to user mode */ //int spl; // disable interrupts //spl = splhigh(); //new trap frame for the child struct trapframe newtf; // copy the trap frame memcpy (&newtf, tf, sizeof(struct trapframe)); //newtf = *tf; newtf.tf_v0 = 0; // return value of the child process should be 0 newtf.tf_epc += 4; // advance the PC to avoid redo of the syscall newtf.tf_a3 = 0; // indicate that there are no errors curthread->t_vmspace = (struct addrspace*)tf->tf_a0; //memcpy (curthread->t_vmspace, (struct addrspace*) tf->tf_a0, sizeof(struct addrspace*)); //kprintf ("BEOFRE"); //struct addrspace *temp = (struct addrspace*) tf->tf_a0; //int test = as_copy(curthread->t_vmspace, &temp); //kprintf ("as_copy: %d\n", test); //kprintf ("TESTING HERE"); as_activate(curthread->t_vmspace); kfree (tf); V(curthread->t_sem_fork); //kprintf ("md_forkentry childpid: %d\n", curthread->t_pid); // re-enable interrupts //splx(spl); // Warp to user mode mips_usermode(&newtf); }
/* * Enter user mode for a newly forked process. * * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ void enter_forked_process(void *data1, unsigned long unused) { struct trapframe local_tf; (void)unused; /* Copy the trapframe passed in onto the current thread's stack */ local_tf = *(struct trapframe *)data1; /* And free the kernel memory from the trapframe passed in */ kfree(data1); /* * Advance the program counter, to avoid restarting * the syscall over and over again in the child. */ local_tf.tf_epc += 4; local_tf.tf_a3 = 0; /* Success if the child gets here */ local_tf.tf_v0 = 0; /* return 0 to the child */ mips_usermode(&local_tf); }
static void md_forkentry(struct trapframe *tf, unsigned long vmspace) { // disable interrupt struct addrspace *t_vmspace = (struct addrspace*)vmspace; splhigh(); if (t_vmspace == NULL) { thread_exit(); } assert(curthread->t_vmspace == NULL); curthread->t_vmspace = t_vmspace; // copy the trapframe to our own stack and free it struct trapframe mytf; memmove(&mytf, tf, sizeof(mytf)); kfree(tf); // set the return value to 0 mytf.tf_v0 = 0; mytf.tf_a3 = 0; // next instruction mytf.tf_epc += 4; /* Activate it. */ // as_hold(curthread->t_vmspace); as_activate(curthread->t_vmspace); // kprintf("sw to user mode.\n"); // switch to usermode mips_usermode(&mytf); // should not come here assert(0); }
void md_forkentry(struct trapframe *tf) { /* * This function is provided as a reminder. You need to write * both it and the code that calls it. * * Thus, you can trash it and do things another way if you prefer. */ int s; s = splhigh(); DEBUG(DB_SYSCALL,"forking thread"); //(void)tf; // tf->tf_v0 = 0; //set return value to 0 for child process tf->tf_epc += 4; //advance pc to avoid restarting syscall tf->tf_a3 = 0; //a3 set to 0 to indicate success splx(s); mips_usermode(tf); }
void entrypoint(void* data1, unsigned long data2) { struct trapframe *tf, tfnew; struct addrspace * addr; tf = (struct trapframe *) data1; addr = (struct addrspace *) data2; tf->tf_a3 = 0; tf->tf_v0 = 0; tf->tf_epc += 4; //kprintf(" LMAO "); curproc->p_addrspace = addr; //kprintf(" rekt "); //memcpy(tfnew, tf, sizeof(struct trapframe)); as_activate(); //kprintf(" nips "); tfnew = *tf; //kprintf(" nips "); mips_usermode(&tfnew); //kprintf(" SWAG "); }
// The parent copies the appropriate data from itself to its child in this function void start_child(void * data1, unsigned long unused) { (void)unused; struct fork_info * info = data1; struct addrspace * new_as; struct trapframe new_tf; /* copy address space */ if (as_copy(info->parent->t_vmspace, &new_as)) { info->child_pid = ENOMEM; // Means no memory for process V(info->sem); // child is done, parent should resume. thread_exit(); } curthread->t_vmspace = new_as; as_activate(new_as); /* copy trap frame to new curkstack */ memcpy(&new_tf, info->tf, sizeof(struct trapframe)); /* change tf's registers to return values for syscall */ new_tf.tf_v0 = 0; new_tf.tf_a3 = 0; new_tf.tf_epc += 4; /* create process and get the pid */ struct process *new_process = proctable_add_child_process(curthread->t_process); if (new_process == NULL) { info->child_pid = EAGAIN; // Means no more processes available in process table V(info->sem); // child is done, parent should resume. thread_exit(); } info->child_pid = new_process->pid; new_process->parent = info->parent->t_process; // Attach new process to our thread curthread->t_process = new_process; // Initalize new file table int result = fdtable_create(); if (result) { // Error occured info->child_pid = result; result = proctable_remove_process(new_process->pid); // We're already exiting, so if there's an error with the line above, then it doesn't matter that much V(info->sem); // child is done, parent should resume. thread_exit(); } struct process * parent_process = info->parent->t_process; lock_acquire(parent_process->t_fdtable_lock); // Copy file table // This requires the filetable to be locked and the refcounts of each file to be increased. int i; for (i = 0; i < OPEN_MAX ; i++) { new_process->t_fdtable->entries[i] = parent_process->t_fdtable->entries[i]; if (new_process->t_fdtable->entries[i] != NULL) new_process->t_fdtable->entries[i]->refcount++; // Increases the number of references to a file } lock_release(parent_process->t_fdtable_lock); // child is done, parent should resume. V(info->sem); mips_usermode(&new_tf); /* mips_usermode does not return */ panic("start_child returned\n"); }