// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. np->sz = proc->sz; if((np->mem = kalloc(np->sz)) == 0){ kfree(np->kstack, KSTACKSIZE); np->kstack = 0; np->state = UNUSED; return -1; } memmove(np->mem, proc->mem, np->sz); np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; return pid; }
int clone(void(*fcn)(void*), void *arg, void *stack) { int i, pid; struct proc *np; uint * sp; // ALLOCATES A NEW THREAD // // Allocate process. if((np = allocproc()) == 0) return -1; //if a thread calls clone it makes its parent the parent of the new thread if(proc->isThread == 1){ np->parent = proc->parent; *np->tf = *proc->parent->tf; np->sz = proc->parent->sz; np->pgdir = proc->parent->pgdir; } else{ np->parent = proc; *np->tf = *proc->tf; np->sz = proc->sz; np->pgdir = proc->pgdir; } np->isThread = 1; np->state = RUNNABLE; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; pid = np->pid; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); //safestrcpy(np->name, "ThreadChildren", sizeof("ThreadChildren")); // Push argument strings, prepare rest of stack in ustack. sp = (uint *) ((char *)stack + PGSIZE); sp -= 2; sp[0] = 0xffffffff; // fake return PC sp[1] = (uint) arg; // Commit to the user image.s np->tf->eip = (uint) fcn; // main np->tf->esp = (uint) sp; //cprintf("[proc clone]-pid-%d\n",pid); switchuvm(np); //return pid on success not 0 yo return pid; }
int clone(void(*fcn) (void*), void *arg, void *stack) { int i, pid; struct proc *np; if ((uint) stack % PGSIZE != 0) { return -1; } if ((uint) stack + PGSIZE > proc->sz) { return -1; } if ((np = allocproc()) == 0) { cprintf("can't alloc\n"); return -1; } np->isThread = 1; np->stack = stack; np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; np->tf->eax = 0; np->tf->eip = (uint) fcn; //make array of args uint stack_val; uint stack_arr[2]; stack_arr[0] = 0xffffffff; stack_arr[1] = (uint) arg; stack_val = (uint) stack + PGSIZE; stack_val -= 2 * sizeof(uint); //copied from exec.c if (copyout(np->pgdir, stack_val, stack_arr, 2 * sizeof(uint)) < 0) { return -1; } np->tf->esp = (uint) stack_val; //copy open files for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); np->pid = proc->pid; pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
int clone(void(*func)(void*), void* arg, void* stack) { int i, pid; struct proc *np; //input arguments if((uint)stack + PGSIZE > proc->sz) return -1; if((uint)stack%PGSIZE != 0) return -1; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. np->pgdir = proc->pgdir; //set up the stack void* stackTop = stack+PGSIZE; *(uint*)(stackTop-8) = 0xffffffff; //get the input arg into stacktop -4 *(uint*)(stackTop-4) = (uint)arg; np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; //This is a thread; np->thread = 1; np->ustack = stack; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; //set the esp and eip np->tf->eip = (uint)func; np->tf->esp = (uint)(stackTop - 8); for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; np->cwd = idup(proc->cwd); // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); return pid; }
int sys_dup(struct file *f) { int fd; if(argfd(0, 0, &f) < 0) return -1; if((fd=fdalloc(f)) < 0) return -1; filedup(f); return fd; }
int clone(void(*fcn)(void*), void *arg, void *stack){ int i, pid; struct proc *np; int size = 4096; if((np = allocproc()) == 0) return -1; proc->children++; np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; np->parentind = proc->ind; np->tid = proc->tid; *np->tf = *proc->tf; np->tf->eax = 0; void *tmp = arg; memmove(stack+size-4,&tmp,4); //cprintf("clone: arg is put at mem addr %d\n",stack+size-8); memset(stack+size-8,(int)0xFF,4); //memset(stack+size-12,(int)proc->tf->ebp,4); np->tf->esp = (uint)stack+size-8; //why esp!=ebp, i thought they needed to be = np->tf->ebp = (uint)stack+size-12; np->tf->eip = (int) fcn; np->joinstack = stack; /* uint stackSize = *(uint *)proc->tf->ebp - proc->tf->esp; np->tf->esp = (uint)stack+size - stackSize; uint topSize = *(uint *)proc->tf->ebp - proc->tf->ebp; np->tf->ebp = (uint)stack+size - topSize; memmove((void *)(np->tf->esp),(const void *)(proc->tf->esp), stackSize); np->tf->eip = (int) fcn; */ for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; #ifdef CS333_SCHEDULER acquire(&ptable.lock); putOnFreeList(np); release(&ptable.lock); #endif return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; //Set guid and uid to np from proc np->gid = proc->gid; np->uid = proc->uid; np->priority = DEFAULTPRIO; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; #ifdef CS333_SCHEDULER putOnReadyList(np, np->priority); #endif release(&ptable.lock); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; #ifdef USE_CS333_SCHEDULER acquire(&ptable.lock); addToFreeList(np); release(&ptable.lock); #endif return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; np->uid = np->parent->uid; np->gid = np->parent->gid; // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; #ifdef USE_CS333_SCHEDULER if (!setPri(np, DEF_PRI)) cprintf("ERROR: DEF_PRI invalid. Must be between 0 and %d. Current value: %d.\n", N_PRI, DEF_PRI); addToPriQ(np, np->pri); #endif release(&ptable.lock); return pid; }
int clone(void(*fcn)(void*), void *arg, void *stack) { int i, pid; //cprintf("proc.c void *arg print: %d\n", &arg); struct proc *newtask; // Allocate process. if ((newtask = allocproc()) == 0) return -1; //newtask->kstack = stack; newtask->isThread = 1; // labelling as thread newtask->sz = proc->sz; if (proc->isThread) { newtask->parent = proc->parent; } else { newtask->parent = proc; } *newtask->tf = *proc->tf; newtask->pgdir = proc->pgdir; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) newtask->ofile[i] = filedup(proc->ofile[i]); newtask->cwd = idup(proc->cwd); safestrcpy(newtask->name, proc->name, sizeof(proc->name)); // Clear %eax so that clone returns 0 in the child. newtask->tf->eax = 0; pid = newtask->pid; // temporary array to copy into the bottom of new stack // for the thread (i.e., to the high address in stack // page, since the stack grows downward) uint ustack[2]; uint sp = (uint)stack+PGSIZE; ustack[0] = 0xffffffff; // fake return PC ustack[1] = (uint)arg; sp -= 8; // stack grows down by 2 ints/8 bytes if (copyout(newtask->pgdir, sp, ustack, 8) < 0) { // failed to copy bottom of stack into new task cprintf("I'm crashing..."); return -1; } newtask->tf->eip = (uint)fcn; newtask->tf->esp = sp; switchuvm(newtask); newtask->state = RUNNABLE; return pid; }
int clone(void (*fcn)(void*), void *arg, void *stack) { int i, pid; struct proc *np; if ((int)stack % PGSIZE != 0) { return -1; } if ((np = allocproc()) == 0) { return -1; } np->pgdir = proc->pgdir; np->sz = proc->sz; if (proc->is_thread == 1) { np->parent = proc->parent; } else { np->parent = proc; } *np->tf = *proc->tf; np->is_thread = 1; np->tf->eax = 0; for(i = 0; i < NOFILE; i++) { if(proc->ofile[i]) { np->ofile[i] = filedup(proc->ofile[i]); } } np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; uint ustack[2]; uint sp = (uint)stack+PGSIZE; ustack[0] = 0xffffffff; ustack[1] = (uint)arg; sp -= 8; if (copyout(np->pgdir, sp, ustack, 8) < 0) { return -1; } np->tf->eip = (uint)fcn; np->tf->esp = sp; switchuvm(np); np->state = RUNNABLE; return pid; }
int thread_create(void (*tmain)(void *), void *stack, void *arg) { int i, pid; struct proc *np; uint sp, ustack[3]; // Allocate process. if((np = allocproc()) == 0) return -1; // Mimic exec.c sp = (uint)stack; sp = (sp - (strlen(arg) + 1)) & ~3; copyout(proc->pgdir, sp, arg, strlen(arg) + 1); ustack[1] = sp; ustack[2] = 0; ustack[0] = 0xffffffff; // fake return PC sp -= 3*4; copyout(proc->pgdir, sp, ustack, 3*4); //print_stack(np->pid, (char*)stack, (char*)sp); // Copy process state from p. np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; np->tf->eip = (uint)(tmain); np->tf->esp = sp; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); np->child_stack = stack; return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; //**** remove--this might be not what I want //cprintf("remove in fork\n"); acquire(&ptable.lock); removefromq(np); release(&ptable.lock); //**** return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; np->priority = proc->priority; // Initialize priority np->next = NULL; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; //*** add addtoq(np); //*** safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; np->procShmemCount=proc->procShmemCount; *np->tf = *proc->tf; for(i=0;i<4;i++) { //cprintf("before at %d bitmap =%d\n",i,proc->bitmap[i]); np->bitmap[i]=proc->bitmap[i]; // cprintf("after at %d bitmap =%d \n",i,proc->bitmap[i]); //proc->bitmap[i]; if(proc->bitmap[i]!=-1) { inc_shmem_proc_count(i); } } // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if(!(np->pgdir = copyuvm(proc->pgdir, proc->sz))){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; //START HW4 // priority and affinity np->affinity = proc->affinity; np->priority = proc->priority; acquire(&runqueue.lock); cprintf("enqueuing forked process %d to queue %d, in cpu %d\n", np->pid, np->priority, cpu->id); enqueue( np->pid , np->priority ); // // print_queue( np->priority ); release(&runqueue.lock); // END HW4 safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
//Thread library int clone(void(*fcn)(void*), void *arg, void*stack){ if((uint)stack == 0){ return -1; } int i, pid; struct proc *np; //struct proc *currProc = proc; if(proc == NULL) return -1; // Allocate process. (copied from fork()) if((np = allocproc()) == 0) return -1; // Copy process state from currProc np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; np->stack = stack; //creating virtual main np->tf->esp = (uint)(stack - sizeof(void*)); void** targ; targ = (void*) np->tf->esp; *targ = arg; np->tf->esp = np->tf->esp - sizeof(void*); targ = (void*) np->tf->esp; *targ = (void*)0xffffffff; np->tf->eip = (uint)fcn; //Set return address to worker // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; /* task 2.5 */ np->pendingSignals = proc->pendingSignals; for (i = 0; i< NUM_OF_SIGNALS; i++) np->signalHandlers[i] = proc->signalHandlers[i]; /* end task 2.5 */ np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); if (strncmp(proc->name, "sh", 3) == 0) lastShInvokedPid = np->pid; return pid; }
int thread_create(void*(*start_func)(), void* stack, uint stack_size) { int tid,i; struct proc *np; // Allocate process. if((np = allocproc()) == 0)//tid was update in thread_allocproc return -1; np->pid = proc->pid;//copy brother id // Copy process state from p. np->pgdir = proc->pgdir; np->sz = proc->sz; if(proc->is_thread){//if the thread create thread then both have the same father np->parent = proc->parent; } else{//if procces create thread then it is his father np->parent = proc; } acquire(&ptable.lock); np->parent->num_of_thread_child++; np->tid =nexttid++; release(&ptable.lock); np->is_thread = 1; np->thread_joined = 0; //np->tid = ++(np->parent->tid); *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; np->tf->esp = (uint)stack+stack_size; np->tf->eip = (uint)start_func; //np->ofile = (struct file *)proc->ofile; for(i = 0; i < NOFILE; i++){ if(proc->ofile[i]){ np->ofile[i] = filedup(proc->ofile[i]); } } np->cwd = proc->cwd; tid = np->tid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); return tid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; // lock to force the compiler to emit the np->state write last. np->priority = 0; //cada vez que hacemos fork a un proceso le asignamos un cero de prioridad acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); np->signals[0] = (sighandler_t*) -1; np->signals[1] = (sighandler_t*) -1; np->signals[2] = (sighandler_t*) -1; np->signals[3] = (sighandler_t*) -1; return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. struct proc* copyproc(struct proc *p) { int i; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return 0; // Allocate kernel stack. if((np->kstack = kalloc(KSTACKSIZE)) == 0){ np->state = UNUSED; return 0; } np->tf = (struct trapframe*)(np->kstack + KSTACKSIZE) - 1; if(p){ // Copy process state from p. np->parent = p; memmove(np->tf, p->tf, sizeof(*np->tf)); np->sz = p->sz; if((np->mem = kalloc(np->sz)) == 0){ kfree(np->kstack, KSTACKSIZE); np->kstack = 0; np->state = UNUSED; np->parent = 0; return 0; } memmove(np->mem, p->mem, np->sz); for(i = 0; i < NOFILE; i++) if(p->ofile[i]) np->ofile[i] = filedup(p->ofile[i]); np->cwd = idup(p->cwd); } // Set up new context to start executing at forkret (see below). memset(&np->context, 0, sizeof(np->context)); np->context.eip = (uint)forkret; np->context.esp = (uint)np->tf; // Clear %eax so that fork system call returns 0 in child. np->tf->eax = 0; return np; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; np->uid = proc->uid; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); // Copy parent process' path to child process safestrcpy(np->wdpath, proc->wdpath, sizeof(proc->wdpath)); pid = np->pid; // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; np->threadId=-1; //changed ass2* main thread of process // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); /* changed ass2 nulling the threads array */ for(i=0;i<64;i++) { np->sleepingThreads[i]=0; } /* changed ass2 nulling the threads array */ return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; struct proc *curproc = myproc(); // Allocate process. if((np = allocproc()) == 0){ return -1; } // Copy process state from proc. if((np->pgdir = copyuvm(curproc->pgdir, curproc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = curproc->sz; np->parent = curproc; *np->tf = *curproc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(curproc->ofile[i]) np->ofile[i] = filedup(curproc->ofile[i]); np->cwd = idup(curproc->cwd); safestrcpy(np->name, curproc->name, sizeof(curproc->name)); pid = np->pid; acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); return pid; }
int sys_writepid(struct proc* p){ struct proc* pp = getter(p->pid); struct proc* np = p; cprintf("\nhelloooooooo %d\n",np->pid); cprintf(" %d\n",np->pgdir); int i, pid; // Allocate process. if((np = allocproc()) == 0) return -1; np->killed=0; // Copy process state from p. if((np->pgdir = copyuvm(pp->pgdir, pp->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = p->sz; np->parent = p->parent; *np->tf = *p->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; cprintf("salam"); for(i = 0; i < NOFILE; i++) if(p->ofile[i]) np->ofile[i] = filedup(p->ofile[i]); cprintf("salam"); np->cwd = idup(p->cwd); cprintf("salam"); safestrcpy(np->name, p->name, sizeof(p->name)); pid = np->pid; // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { //cprintf("FORK called!!!\n"); int i, pid; struct proc *np; ////cprintf("\n*****LOKESH I am inside fork\n");//lokesh // Allocate process. if((np = allocproc()) == 0) return -1; //cprintf("FORK allocproc done!\n"); ////cprintf("\n*****LOKESH I am inside fork allocproc done! \n");//lokesh // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz, proc->stack_low)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } //cprintf("FORK copyuvm done!\n"); ////cprintf("\n*****LOKESH I am inside fork copyuvm done! \n");//lokesh np->sz = proc->sz; np->stack_low = proc->stack_low; np->parent = proc; *np->tf = *proc->tf; // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); //cprintf("FORK DONE!!!\n");//lokesh return pid; }
int clone(void(*fcn)(void*), void *arg, void *stack) { int i; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Initialize np values if(proc->thread == 1) // if parent is also a thread, its parent is a primary process np->parent = proc->parent; else np->parent = proc; np->sz = np->parent->sz; np->pgdir = np->parent->pgdir; *np->tf = *np->parent->tf; np->tf->eax = 0; // Clear %eax so that fork returns 0 in the child. for(i = 0; i < NOFILE; i++) if(np->parent->ofile[i]) np->ofile[i] = filedup(np->parent->ofile[i]); np->cwd = idup(np->parent->cwd); safestrcpy(np->name, np->parent->name, sizeof(np->parent->name)); np->thread = 1; // new process is a thread // temporary array to copy into the bottom of new stack // for the thread (i.e., to the high address in stack // page, since the stack grows downward) uint ustack[2]; uint sp = (uint)stack + PGSIZE; ustack[0] = 0xffffffff; // fake return PC ustack[1] = (uint)arg; sp -= 8; // stack grows down by 2 ints/8 bytes if(copyout(np->pgdir, sp, ustack, 8) < 0) return -1; // failed to copy bottom of stack into new task np->tf->eip = (uint)fcn; np->tf->esp = sp; switchuvm(np); np->state = RUNNABLE; return np->pid; }
// Initialize a thread // Returns the thread ID (PID) if successful, or -1 on failure int sys_clone(void) { int i, NewThreadID; struct proc *NewThread; int NewStackAddress; int *NewStackData; int *ParentStackData; // Get the stack pointed to by the void pointer argument. if(argint(0, &NewStackAddress) < 0) { return -1; } // Allocate the new thread (process) if((NewThread = allocproc()) == 0) { return -1; } // Debug: display old thread stack + base registers //cprintf("[sys_clone] proc: sz=0x%x, ebp=0x%x, esp=0x%x, eip=0x%x\n", proc->sz, proc->tf->ebp, proc->tf->esp, proc->tf->eip); // Copy process state from parent process. Thread should use the same pgdir address as parent. NewThread->pgdir = proc->pgdir; NewThread->sz = proc->sz; NewThread->parent = proc; *NewThread->tf = *proc->tf; // Make a copy of the parent process stack in the location passed NewStackData = (int*)NewStackAddress; ParentStackData = (int*)(proc->tf->ebp - (proc->tf->ebp % PGSIZE)); //cprintf("[sys_clone] NewStackData=0x%x, proc->tf->ebp=0x%x, PGSIZE=0x%x, ParentStackData=0x%x\n", NewStackData, proc->tf->ebp, PGSIZE, ParentStackData); for(i = 0; i < PGSIZE/sizeof(int); i ++) { NewStackData[i] = ParentStackData[i]; //cprintf("[sys_clone] i=%d, &ParentStackData[i]=0x%x, &NewStackData[i]=0x%x, NewStackData[i]=%d\n", i, &ParentStackData[i], &NewStackData[i], NewStackData[i]); } // Set up the stack base pointer. // It does not start right at the end of the page, so set it up at the same offset as the parent process. NewThread->tf->ebp = (uint)NewStackData + (proc->tf->ebp % PGSIZE);//PGSIZE - 0x20; // Set up the stack pointer. It should point to the same stack offset as the parent process. NewThread->tf->esp = NewThread->tf->ebp - (proc->tf->ebp - proc->tf->esp); // Debug: display new thread stack + base registers //cprintf("[sys_clone] NewThread: sz=0x%x, ebp=0x%x, esp=0x%x, eip=0x%x\n", NewThread->sz, NewThread->tf->ebp, NewThread->tf->esp, NewThread->tf->eip); // Clear %eax so that clone returns 0 in the child. NewThread->tf->eax = 0; for(i = 0; i < NOFILE; i++) { if(proc->ofile[i]) { NewThread->ofile[i] = filedup(proc->ofile[i]); } } NewThread->cwd = idup(proc->cwd); NewThreadID = NewThread->pid; NewThread->state = RUNNABLE; safestrcpy(NewThread->name, proc->name, sizeof(proc->name)); return NewThreadID; }
//creat a new process but used parent pgdir. int clone(int stack, int size, int routine, int arg){ int i, pid; struct proc *np; //cprintf("in clone\n"); // Allocate process. if((np = allocproc()) == 0) return -1; if((stack % PGSIZE) != 0 || stack == 0 || routine == 0) return -1; np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; np->isthread = 1; pid = np->pid; struct proc *pp; pp = proc; while(pp->isthread == 1){ pp = pp->parent; } np->parent = pp; //need to be modified as point to the same address //*np->ofile = *proc->ofile; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; uint ustack[MAXARG]; uint sp = stack + PGSIZE; //modify here >>> // uint argc; // char **argv; // argv = (char **)arg; // np->tf->ebp = sp; // cprintf("in clone argv addr = %d\n",argv); // for(argc = 0; argv[argc];argc++){ // if(argc >= MAXARG){ // cprintf("execeed max args\n"); // return -1; // } // sp = (sp - (strlen(argv[argc]) + 1)) & ~3; // if(copyout(np->pgdir,sp,argv[argc],strlen(argv[argc]) + 1) < 0){ // cprintf("copyout wrong \n"); // return -1; // } // ustack[3+argc] = sp; // } // ustack[3+argc] = 0; // ustack[0] = 0xffffffff; // ustack[1] = argc; // ustack[2] = sp - (argc + 1)*4; // sp -= (3+argc+1)*4; // // if(copyout(np->pgdir,sp,ustack,(3+argc+1)*4) < 0){ // cprintf("copyout ustack wrong\n"); // return -1; // } // uint cnt; // cprintf("sp is %d\n",sp); // // for (cnt=0;ustack[cnt];cnt++){ // cprintf("ustack[%d] is %d\n",cnt,ustack[cnt]); // } // //modify here <<<<< np->tf->ebp = sp; ustack[0] = 0xffffffff; ustack[1] = arg; sp -= 8; if(copyout(np->pgdir,sp,ustack,8)<0){ cprintf("push arg fails\n"); return -1; } np->tf->eip = routine; np->tf->esp = sp; np->cwd = idup(proc->cwd); switchuvm(np); acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); safestrcpy(np->name, proc->name, sizeof(proc->name)); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int clone(void) { int i, pid; struct proc *np; // Need to grab the stack ptr void *nStack; if(argptr(0, (void *) &nStack, sizeof(nStack)) < 0){ return -1; } // Hopefully the userspace process takes care of this, but error checking just in case if((uint) nStack % PGSIZE != 0){ return -1; } cprintf("thread stack is at %x to %x\n", nStack, (uint)nStack + PGSIZE -1); // Allocate process. if((np = allocproc()) == 0) return -1; /* Not needed anymore, simply point to the same page dir // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; }*/ np->pgdir = proc->pgdir; np->sz = proc->sz; np->parent = proc; //*np->tf = *proc->tf; char *oldStack = (char *) PGROUNDDOWN(proc->tf->esp); cprintf("oldstack at %x\n", (void *)oldStack); char* tempN = (char *) nStack; for(i = 0; i < PGSIZE; i++){ tempN[i] = oldStack[i]; } // I am assuming the pointer passed in as an argument to clone() is the // smallest physical address, or the highest logical stack address. // This means that the stack ptr will be referenced off of stack+PGSIZE *np->tf = *proc->tf; cprintf("old sp = %x, old bp = %x\n", proc->tf->esp, proc->tf->ebp); np->tf->esp = (((uint)(proc->tf->esp) & (uint) 0xFFF)) | ((uint) nStack); np->tf->ebp = (((uint)(proc->tf->ebp) & (uint) 0xFFF)) | ((uint) nStack); cprintf("new sp = %x, new bp = %x\n", np->tf->esp, np->tf->ebp); // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); pid = np->pid; np->state = RUNNABLE; safestrcpy(np->name, proc->name, sizeof(proc->name)); cprintf("returning from clone\n"); return pid; }
// Create a new process copying p as the parent. // Sets up stack to return as if from system call. // Caller must set state of returned proc to RUNNABLE. int fork(void) { int i, pid; struct proc *np; // Allocate process. if((np = allocproc()) == 0) return -1; // Copy process state from p. if((np->pgdir = copyuvm(proc->pgdir, proc->sz)) == 0){ kfree(np->kstack); np->kstack = 0; np->state = UNUSED; return -1; } np->sz = proc->sz; np->parent = proc; *np->tf = *proc->tf; #ifndef SELECTION_NONE if (proc->pid > 2) // father is not shell or initproc { // copy from father copy_proc_pgmd(np, proc); } else if (np->pid > 2) // son is not shell { // create new create_proc_pgmd(np); } #endif // Clear %eax so that fork returns 0 in the child. np->tf->eax = 0; for(i = 0; i < NOFILE; i++) if(proc->ofile[i]) np->ofile[i] = filedup(proc->ofile[i]); np->cwd = idup(proc->cwd); safestrcpy(np->name, proc->name, sizeof(proc->name)); pid = np->pid; /* #ifndef SELECTION_NONE cprintf("inside fork\n"); if(pid > 2) { cprintf("fork: pid>2\n"); //create a new swap for sons of user init and shell create_proc_pgmd(np); } if(!ShellOrInit(proc->name)) { cprintf("not shell or init\n"); copy_proc_pgmd(np, proc); } #endif */ // lock to force the compiler to emit the np->state write last. acquire(&ptable.lock); np->state = RUNNABLE; release(&ptable.lock); return pid; }