// Turn on paging. void vmenable(void) { uint cr0; switchkvm(); // load kpgdir into cr3 cr0 = rcr0(); cr0 |= CR0_PG; lcr0(cr0); }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; int makeShiftTimer = 0; for(;;){ // Enable interrupts on this processor. sti(); makeShiftTimer++; if (makeShiftTimer >= 10000){ for (p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if (p->pri != 1){ continue; } p->pri = 0; //cprintf("Bumping up: %s", p->name); } makeShiftTimer = 0; } int zeroCount = 0; for (p = ptable.proc; p < &ptable.proc[NPROC]; p++){ zeroCount++; } // cprintf("Number of process on queue 0: %d\n", zeroCount); //don't uncomment this if you want to be able to use the terminal. At all. // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if((p->state != RUNNABLE) || (zeroCount != 0 && p->pri == 1)) //im pretty sure the case for there being nothing on the 0 queue and stuff on the 1 queue is implicit here //we'll wait and see I guess continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; int i; #if 0 for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != UNUSED) cprintf("proc %d has priority %d\n", p->pid, p->priority); } #endif for(;;){ // Enable interrupts on this processor. sti(); acquire(&ptable.lock); // Loop through priority queues looking for runnable processe for(i = 0; i < 32; i++) { if(priority_q[i] != NULL) { p = priority_q[i]; #if 0 } } // Loop over process table looking for process to run. for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ #endif if(p->state != RUNNABLE) panic("Not runnable in ready queue"); // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; //**** remove //cprintf("remove in scheduler\n"); removefromq(p); //**** swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } } release(&ptable.lock); }
void SwitchToProccess(struct proc* process) { proc = process; switchuvm(process); process->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; }
void scheduler(void) { struct proc *p; ptable.timeToReset = MAX_TIME_TO_RESET; for(;;){ // Enable interrupts on this processor. sti(); // Check for procs in ready list int pri = 0; for (;;) { acquire(&ptable.lock); if(ptable.pPriQ[pri] != 0) { // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. p = ptable.pPriQ[pri]; if (p->state != RUNNABLE) panic("scheduled unready process"); proc = p; switchuvm(p); p->state = RUNNING; ptable.pPriQ[pri] = ptable.pPriQ[pri]->next; p->next = 0; ptable.timeToReset--; if (ptable.timeToReset == 0) resetPri(); // Run priority-reset function swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; release(&ptable.lock); pri = 0; break; } else { release(&ptable.lock); if (pri == N_PRI-1) pri = 0; else pri++; } } } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p, *q; unsigned long long min ; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); p = 0; min = INFINITO ; for(q = ptable.proc; q < &ptable.proc[NPROC]; q++){ if (q->state == RUNNABLE){ if (min > q->curr_pass){ p = q; min = q->curr_pass; } } } if (p!=0){ /*Testes if (p->pid > 3){ for(q = ptable.proc; q < &ptable.proc[NPROC]; q++){ cprintf("%d %d %d\n", q->pid, q->Ntickts, q->slices); } cprintf("\n\n\n\n"); } End */ p->slices++; proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. p->curr_pass+=p->pass; // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; for(;;) { // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); uint min_order = 1<<30; uint idx = -1; for (p = ptable.proc; p < &ptable.proc[NPROC]; p++) if (p->state == RUNNABLE && p->order < min_order) { min_order = p->order; idx = p - ptable.proc; } if (idx == -1) { release(&ptable.lock); continue; } //for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ // if(p->state != RUNNABLE) // continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. p = ptable.proc + idx; proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; //break; //} release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); /* for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; */ int i; for(i = 0; i < PRIORITIES; i ++) { p = ready[i]; if(p == 0) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; remove_from_ready(p); swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = p = 0; /* if(current_priority == 31) current_priority = 0; else current_priority = i + 1; */ } release(&ptable.lock); } }
void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. if (p->allowed_cpu > -1 && p->allowed_cpu == cpu->id) { //cprintf("\n Processing prod %d, at cpu %d", p->pid, cpu->id); } else if (p->allowed_cpu > -1) { //cprintf("\nSkipping proc %d at cpu %d, proc->allowed_cpu %d", p->pid, cpu->id, p->allowed_cpu); continue; } rerun: proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. if (cpu->preempt_disable_count > 0) { // Go back and reschedule the same process goto rerun; } proc = 0; } release(&ptable.lock); } }
void handleRightClick() { WindowQueue *pwindowQueue; Widget *pwidget; pwindowQueue = getClickedWindowQueue(); if (pwindowQueue) { pwidget = getClickedWidget(pwindowQueue->window); if (pwidget) { } } if (proc == 0) switchkvm(); else switchuvm(proc); }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p, *min; int max; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc, max = MAX_STRIDE, min = 0; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; if(p->passada < max){ max = p->passada; min = p; } } if(min){ min->passada += min->passo; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = min; switchuvm(min); min->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ //wake up inswapper if(p->state == RUNNABLE_SUSPENDED && p->swapped){ p = find_inswapper(); //change p to inswapper p->state = RUNNABLE; //wakeup inswapper } if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; struct proc *hp; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); hp = ptable.proc; for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; if(hp->state != RUNNABLE) //garantiza que tenga runnable hp = p; if(hp->priority < p->priority) hp = p; } p = hp; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; //para matar un proceso tenemos que matar a proc switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; release(&ptable.lock); } }
void scheduler(void){ //struct proc *p; int i; struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); acquire(&ptable.lock); for (i = 0; i < SIZE; ++i) { if (ptable.readyList[i] == 0) continue; p = ptable.readyList[i]; removeFromReadyList(p, p->priority); // Set it back to priority 0 (increments at the end of loop) if (i != 2) i = -1; //Decrement counter --ptable.timeToReset; if (ptable.timeToReset == 0) { //cprintf("Reseting list\n"); resetReadyList(); ptable.timeToReset = COUNT; } proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); proc = 0; } release(&ptable.lock); } }
// Allocate one page table for the machine for the kernel address // space for scheduler processes. // // linear map the first 4GB of physical memory starting at 0xFFFFFFFF80000000 void kvmalloc(void) { int n; kpml4 = (pde_t*) kalloc(); kpdpt = (pde_t*) kalloc(); kpgdir0 = (pde_t*) kalloc(); kpgdir1 = (pde_t*) kalloc(); iopgdir = (pde_t*) kalloc(); memset(kpml4, 0, PGSIZE); memset(kpdpt, 0, PGSIZE); memset(iopgdir, 0, PGSIZE); kpml4[511] = v2p(kpdpt) | PTE_P | PTE_W; kpdpt[511] = v2p(kpgdir1) | PTE_P | PTE_W; kpdpt[510] = v2p(kpgdir0) | PTE_P | PTE_W; kpdpt[509] = v2p(iopgdir) | PTE_P | PTE_W; for (n = 0; n < NPDENTRIES; n++) { kpgdir0[n] = (n << PDXSHIFT) | PTE_PS | PTE_P | PTE_W; kpgdir1[n] = ((n + 512) << PDXSHIFT) | PTE_PS | PTE_P | PTE_W; } for (n = 0; n < 16; n++) iopgdir[n] = (DEVSPACE + (n << PDXSHIFT)) | PTE_PS | PTE_P | PTE_W | PTE_PWT | PTE_PCD; switchkvm(); }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); #ifndef __ORIGINAL_SCHED__ p = pdequeue(); if(p){ #else for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; #endif // For debug, checking the scheduled process priority cprintf("cpu %d get process %s, process prio = %d\n",cpunum(),p->name,p->priority); // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } } // Enter scheduler. Must hold only ptable.lock // and have changed proc->state. void sched(void) { int intena; if(!holding(&ptable.lock)) panic("sched ptable.lock"); if(cpu->ncli != 1) panic("sched locks"); if(proc->state == RUNNING) panic("sched running"); if(readeflags()&FL_IF) panic("sched interruptible"); intena = cpu->intena; swtch(&proc->context, cpu->scheduler); cpu->intena = intena; }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p = 0; int i; for(;;){ // Enable interrupts on this processor. sti(); acquire(&ptable.lock); for(i=0;i<32;i++){ if(readyQ.proc[i]){ p=readyQ.proc[i]; if(p->next == 0){ readyQ.proc[i] = 0; } else{ readyQ.proc[i] = p->next; if(p->next != p->prev){ p->next->prev = p->prev; } else{ p->next->prev = 0; p->next->next = 0; } } p->next = 0; p->prev = 0; // cprintf("Found proc to run\n"); proc=p; switchuvm(p); p->state = RUNNING; // cprintf("Dispatching priority %d\n",p->priority); swtch(&cpu->scheduler, proc->context); switchkvm(); proc=p=0; break; } } release(&ptable.lock); /* // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock);*/ } }
// Allocate one page table for the machine for the kernel address // space for scheduler processes. void kvmalloc(struct cpu *c) { c->kpgdir = setupkvm(); switchkvm(c); }
// Allocate one page table for the machine for the kernel address // space for scheduler processes. void kvmalloc(void) { kpgdir = setupkvm(); switchkvm(); }
// Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { //cprintf("scheduler...\n"); struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); // TODO(byan23): Implement scheduler. // Loops over the priority queues (from 0 to 3) looking for process to run. //p = q0_head; //if (!q0_head) cprintf("q0_head is null\n"); int sched = 0; for (p = q0_head; p != NULL; p = p->next) { if (p->state == RUNNABLE) { //cprintf("found.\n"); sched = 1; break; } } if (!sched) { for (p = q1_head; p != NULL; p = p->next) { //cprintf("1 loop\n"); if (p->state == RUNNABLE) { sched = 1; break; } } } if (!sched) { for (p = q2_head; p != NULL; p = p->next) { //cprintf("2 loop\n"); if (p->state == RUNNABLE) { sched = 1; break; } } } if (!sched) { for (p = q3_head; p != NULL; p = p->next) { //cprintf("3 loop\n"); if (p->state == RUNNABLE) { sched = 1; break; } } } if (sched) { // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. //cprintf("choose pid: %d to run\n", p->pid); proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; int pPendingSignals; sighandler_t handler; sighandler_t defaultHandlers[32]; //32 default functions for handling signals the default way int originalHandlers[32]; int i; int bitwiseSig; int registeredFlag = 0; //anotates that the signal that was handeled was a user signal //registering original handlers: for(i = 0; i< NUM_OF_SIGNALS; i++){ defaultHandlers[i] = doNothingHandler; originalHandlers[i] = SIG_IGN; } defaultHandlers[0] = sigIntHandler; originalHandlers[0] = SIG_DFL; defaultHandlers[1] = sigUsr1Handler; originalHandlers[1] = SIG_DFL; defaultHandlers[2] = sigUsr2Handler; originalHandlers[2] = SIG_DFL; defaultHandlers[3] = sigChldHandler; originalHandlers[3] = SIG_DFL; //end registering original handlers, check also allocproc it should be matched for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; pPendingSignals = p->pendingSignals; for (i = 0; i < NUM_OF_SIGNALS; i++){ registeredFlag = 0; bitwiseSig = getSigBitwise(i); if ((bitwiseSig & pPendingSignals) > 0){ //cprintf("KING: %d", (int)p->signalHandlers[i]); if ((int)p->signalHandlers[i] == SIG_DFL){ //need to take DFL action, it is clear to the process, it does not know that the signal was handeled handler = defaultHandlers[i]; (*handler)(); p->pendingSignals = getBitwiseXor(p->pendingSignals, bitwiseSig); break; } else{ if ((int)p->signalHandlers[i] == SIG_IGN){ p->pendingSignals = getBitwiseXor(p->pendingSignals, bitwiseSig); break; } else{ register_handler(p->signalHandlers[i]); if (originalHandlers[i] == SIG_DFL) proc->signalHandlers[i] = (sighandler_t) SIG_DFL; if (originalHandlers[i] == SIG_IGN) proc->signalHandlers[i] = (sighandler_t) SIG_IGN; registeredFlag = 1; break; //todo XOR to make signal go away - AFTER CPU GETS TIME BEFORE PROC = 0!! } } } } switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); if (registeredFlag == 1){ proc->pendingSignals = getBitwiseXor(proc->pendingSignals, bitwiseSig); //proc->signalHandlers[i] = (sighandler_t) SIG_DFL; registeredFlag =0; } // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); } }
// Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; for(;;){ // Enable interrupts on this processor. sti(); acquire(&ptable.lock); // Loop over process table looking for process to run. for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if ((p->state != RUNNABLE) || ((p->affinity != -1) && (p->affinity != cpu->id))) continue; // START HW4 // see if current process has the highest priority acquire(&runqueue.lock); int i, found=1; for(i=0; i<=p->priority ; i++){ if( runqueue.q[i] != 0 && ( i < p->priority || runqueue.q[i]->pid != p->pid ) ) { found = 0; break; } } if(!found){ release(&runqueue.lock); continue; } // END HW4 //cprintf("found process2 %d cpu %d\n" ,p->pid, cpu->id); // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; // START HW4 // for(i=0; i<NQUEUE; i++) // print_queue( i); //cprintf("scheduling proc %d with priority %d\n",p->pid, p->priority); remove_from_queue( p->pid, p->priority ); release(&runqueue.lock); // END HW4 swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. // START HW4 if( p->state == RUNNABLE ){ acquire(&runqueue.lock); remove_from_queue( p->pid, p->priority ); enqueue( p->pid, p->priority ); release(&runqueue.lock); } // END HW4 proc = 0; } release(&ptable.lock); } }
//PAGEBREAK: 42 // Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; uint mask; sighandler_t *handler; for(;;) { // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++) { if(p->state != RUNNABLE) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); /* A&T - SIGNALS start */ if (p->signal != 0) { /* A&T - were any signals recieved? */ /* cprintf("DEBUG: pid=%d, p->signal=%d\n", p->pid, p->signal); */ mask = (1 << 31); /* the stack is a LIFO structure, so * we'll be pushing the LEAST important * signals first, so they'll run last. */ /* cprintf("DEBUG: mask=%d\n", mask); */ handler = &proc->handlers[31]; while(mask > 8) { /* a mask to check whether a signal's bit is up - not for builtin 3 signal hadlers, since they should be called from kernel space and not userspace. */ if ((p->signal & mask) && (*handler != 0)) register_handler(*handler); /* add the handler to the stack, if it exists */ mask >>= 1; /* move the mask to the next bit to check. */ handler--; /* move the pointer to the next hendler */ } while (mask > 0) { if (p->signal & mask) { if (*handler == 0) /* call the built-in handler */ switch(mask) { case 8: sigchld(); break; case 4: sigusr2(); break; case 2: sigusr1(); break; case 1: sigint(); break; default: break; } else register_handler(*handler); } mask >>= 1; handler--; } p->signal = 0; /* initialize the signal data word to 0 */ } /* A&T - SIGNALS end */ p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } release(&ptable.lock); }
// Other CPUs jump here from entryother.S. static void mpenter(void) { switchkvm(); seginit(); lapicinit(); mpmain(); }
// Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; int queue_flag=2; int tickets=0; int sum_tickets=0; int winner=0; for(;;){ // Enable interrupts on this processor. sti(); tickets = 0; queue_flag=2; // Count the number of tickets acquire(&ptable.lock); for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if((p->queue == 1)&&(p->state==RUNNABLE)) queue_flag=1; // indicates that there are processes in the 1st queue } for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if((p->state == RUNNABLE)&&(p->queue ==queue_flag)) tickets += p->tickets; } if(tickets>0) { winner = random(); if (winner < 0) winner *= -1; tickets = winner % tickets; } //run for the 1st priority queue if(queue_flag==1){ // Loop over process table looking for process to run. for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if((p->state != RUNNABLE)||(p->queue != queue_flag)) continue; tickets -= p->tickets; if (tickets >= 0) continue; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; p->hticks=p->hticks+1; switchuvm(p); p->state = RUNNING; //p->tickets -= 1; //p->queue = 2; //if (p->tickets == 0) //settickets(5); swtch(&cpu->scheduler, proc->context); switchkvm(); //if((p->state==RUNNABLE)||(p->state==RUNNING)) //p->queue=2; // Process is done running for now. // It should have changed its p->state before coming back. // If the process has not completed with its execution then demote to lower priority // if(p->state == RUNNING) // p->queue=2; // cprintf("process:%s , lticks: %d,hticks:%d ,tickets:%d\n",p->name,p->lticks,p->hticks,p->tickets); proc = 0; } } //else run for the 2nd priority queue else{ // Loop over process table looking for process to run. for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){ if((p->state != RUNNABLE)||(p->queue != queue_flag)) continue; tickets -= p->tickets; if (tickets >= 0) continue; //tickets=temp_tickets; //winner = random(); //if (winner < 0) // winner *= -1; //tickets = winner % sum_tickets; // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; p->lticks=p->lticks+1; switchuvm(p); p->state = RUNNING; //p->tickets -= 1; swtch(&cpu->scheduler, proc->context); switchkvm(); // cprintf("process:%s , lticks: %d,hticks:%d ,tickets:%d,win:%d\n",p->name,p->lticks,p->hticks,p->tickets,tickets); if(((p->state)==RUNNABLE)||((p->state)==RUNNING)) { proc=p; p->lticks=p->lticks+1; switchuvm(p); p->state = RUNNING; // cprintf("process:%s , lticks: %d,hticks:%d ,tickets:%d\n",p->name,p->lticks,p->hticks,p->tickets); //p->tickets -= 1; swtch(&cpu->scheduler,proc->context); switchkvm(); } // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; } } release(&ptable.lock); }//for the infinite loop }//function finish
// Per-CPU process scheduler. // Each CPU calls scheduler() after setting itself up. // Scheduler never returns. It loops, doing: // - choose a process to run // - swtch to start running that process // - eventually that process transfers control // via swtch back to the scheduler. void scheduler(void) { struct proc *p; int i; int hproc = NPROC-1, lproc = NPROC-1; uint begin = 0, end = 0; syncpstats(); for(;;){ // Enable interrupts on this processor. sti(); // Loop over process table looking for process to run. acquire(&ptable.lock); for(i = (hproc+1)%NPROC; ; i = (i+1)%NPROC){ p = &ptable.proc[i]; if(p->state == RUNNABLE && p->priority == 2){ hproc = i; goto scheduler_run; } if (i == hproc) break; } for(i = (lproc+1)%NPROC; ; i = (i+1)%NPROC){ p = &ptable.proc[i]; if(p->state == RUNNABLE && p->priority == 1){ lproc = i; goto scheduler_run; } if (i == lproc) break; } goto scheduler_end; scheduler_run: acquire(&tickslock); begin = ticks; release(&tickslock); // Switch to chosen process. It is the process's job // to release ptable.lock and then reacquire it // before jumping back to us. proc = p; switchuvm(p); p->state = RUNNING; swtch(&cpu->scheduler, proc->context); switchkvm(); // Process is done running for now. // It should have changed its p->state before coming back. proc = 0; acquire(&tickslock); end = ticks; release(&tickslock); if (p->priority == 1) pstats.lticks[i] += end - begin; else pstats.hticks[i] += end - begin; syncpstats(); scheduler_end: release(&ptable.lock); } }