PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { volatile int lock; DISABLE_INTR(lock); int i; for(i = 1; i < MAX_PROCS; i++) { if(pcb[i].used == FALSE) { pcb[i].magic = MAGIC_PCB; pcb[i].used = TRUE; pcb[i].priority = (unsigned short) prio; pcb[i].state = STATE_READY; pcb[i].esp = get_new_stack_frame(i, ptr_to_new_proc, param); pcb[i].first_port = create_new_port(&pcb[i]); pcb[i].name = name; add_ready_queue(&pcb[i]); ENABLE_INTR(lock); return pcb[i].first_port; } } ENABLE_INTR(lock); return (PORT) NULL; }
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { //For interrupts volatile int saved_if; DISABLE_INTR(saved_if); //end for interrupts //Look for empty int i; for(i = 0; i < MAX_PROCS; i++){ if(pcb[i].used == FALSE) break; } MEM_ADDR esp; PROCESS new_proc = &pcb[i]; new_proc->magic = MAGIC_PCB; new_proc->used = TRUE; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; PORT p = create_new_port(new_proc); esp = PROCESS_BASE - PROCESS_SIZE * i; poke_l(esp, param); esp -= sizeof(LONG); poke_l(esp, new_proc); esp -= sizeof(LONG); poke_l(esp, 0); esp -= sizeof(LONG); //For interrupts if(interrupts_initialized == TRUE) poke_l(esp, 512); else poke_l(esp, 0); esp -= sizeof(LONG); poke_l(esp, CODE_SELECTOR); esp -= sizeof(LONG); //End for interrupts poke_l(esp, ptr_to_new_proc); esp -= sizeof(LONG); //0 out register poke_l(esp, 0); //EAX esp -= sizeof(LONG); poke_l(esp, 0); //ECX esp -= sizeof(LONG); poke_l(esp, 0); //EDX esp -= sizeof(LONG); poke_l(esp, 0); //EBX esp -= sizeof(LONG); poke_l(esp, 0); //EBP esp -= sizeof(LONG); poke_l(esp, 0); //ESI esp -= sizeof(LONG); poke_l(esp, 0); //EDI //Save the Stack pointer new_proc->esp = esp; add_ready_queue(new_proc); //For interrupts ENABLE_INTR(saved_if); //End for interrupts return p; }
PORT create_port() { return create_new_port (active_proc); }
//HOMEWORK 3 PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { //initialize the process values LONG default_value = 0; MEM_ADDR esp; PROCESS new_proc; PORT new_port; //HW7 volatile int flag;//disable interrupts DISABLE_INTR(flag); new_proc = next_proc_ptr; next_proc_ptr = new_proc->next; //HW7 ENABLE_INTR (flag);//reenable interrupts new_proc->magic = MAGIC_PCB; new_proc->used = TRUE; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; new_port = create_new_port(new_proc); esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024; //PARAM esp = pushStack(esp, (LONG)param); //PROCESS esp = pushStack(esp, (LONG)new_proc); //RETURN ADDRESS esp = pushStack(esp, default_value); //Push interrupt flags if initialized //HW7 - slide 20 EFLAGS if (interrupts_initialized) { esp = pushStack(esp, 512); } else { esp = pushStack(esp, default_value); } //Push CodeSelector esp = pushStack(esp, CODE_SELECTOR); //ADDRESS OF NEW PROCESS esp = pushStack(esp, (LONG)ptr_to_new_proc); //EAX esp = pushStack(esp, default_value); //ECX esp = pushStack(esp, default_value); //EDX esp = pushStack(esp, default_value); //EBX esp = pushStack(esp, default_value); //EBP esp = pushStack(esp, default_value); //ESI esp = pushStack(esp, default_value); //EDI esp = pushStack(esp, default_value); new_proc->esp = esp; add_ready_queue (new_proc); return new_port; }
//creates a port to the active process PORT create_port() { PORT newport = create_new_port(active_proc); return newport; }
PORT create_process (void (*ptr_to_new_proc) (PROCESS, PARAM), int prio, PARAM param, char *name) { MEM_ADDR esp; PROCESS new_proc; PORT new_port; volatile int flag; DISABLE_INTR (flag); if (prio >= MAX_READY_QUEUES) panic ("create(): Bad priority"); if (next_free_pcb == NULL) panic ("create(): PCB full"); new_proc = next_free_pcb; next_free_pcb = new_proc->next; ENABLE_INTR (flag); new_proc->used = TRUE; new_proc->magic = MAGIC_PCB; new_proc->state = STATE_READY; new_proc->priority = prio; new_proc->first_port = NULL; new_proc->name = name; new_port = create_new_port (new_proc); /* Compute linear address of new process' system stack */ esp = 640 * 1024 - (new_proc - pcb) * 16 * 1024; #define PUSH(x) esp -= 4; \ poke_l (esp, (LONG) x); /* Initialize the stack for the new process */ PUSH (param); /* First data */ PUSH (new_proc); /* Self */ PUSH (0); /* Dummy return address */ if (interrupts_initialized) { PUSH (512); /* Flags with enabled Interrupts */ } else { PUSH (0); /* Flags with disabled Interrupts */ } PUSH (CODE_SELECTOR); /* Kernel code selector */ PUSH (ptr_to_new_proc); /* Entry point of new process */ PUSH (0); /* EAX */ PUSH (0); /* ECX */ PUSH (0); /* EDX */ PUSH (0); /* EBX */ PUSH (0); /* EBP */ PUSH (0); /* ESI */ PUSH (0); /* EDI */ #undef PUSH /* Save context ptr (actually current stack pointer) */ new_proc->esp = esp; add_ready_queue (new_proc); return new_port; }