xv6 Scheduler - proc never != 0

匿名 (未验证) 提交于 2019-12-03 09:06:55

问题:

Basically, I'm implementing a scheduler for the xv6 kernel that is implementing a multilevel priority queue. I'm having a serious issue I do not understand, the TAs for my course do not understand, and I've missed the deadline for this project, so helping me right now will not gain me any extra points - but I WANT to know why I'm having the following behavior...

First, this is the original scheduler that I'm changing for xv6 (for comparison - this is NOT my implementation):

// 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;        // 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);    } } 

The new scheduler's idea is this: there is an array filled with proc structs inside ptable. I'll call each of these elements in this proc array 'p', and they hold basic information (like the number of "tickets" they have, or it's state, etc). I need to run all high priority (HP) p's for one time slice and then change their priority level to low. When there are no HP procs, I "randomly" choose a LP proc and run it for TWO time slices. My algorithm is as follows:

scheduler()     for(;;) //scheduler NEVER completes         //information gathering         for (entire proc array) //goes over it once             gather how many HP and LP procs             count total HP and LP tickets in each proc (for lottery)          if #HP > 1 //randomly choose a HP proc             hold HP lottery, run one HP proc //afterwards,              int rand = random() % num_HP_tickets             for (entire array)                 curr_index_of_tickets += p->num_tickets;                 if (curr_index_of_tickets >= rand) //we found the right p!                     run p for one time slice         else if #HP == 1             find and run the one HP proc         else if #HP < 1 //then no HP procs! Time to run LP             if #LP > 1                 hold LP lottery, run one LP proc for two time slices, similar to above             else if #LP == 1                 find the LP proc, run it 

Here's the issue... My proc always appears to be equal to 0. It's never seeing information put in p, not gathering proc information from p, etc. I do not know why.

I tested with a crap ton of printout statements. I'll post the output of that here first:

entered scheduler entered INFORMATION loop: iteration 0 Proc is 0 Proc is 0 even after proc gets p from for loop Information 0: found 0 HP procs Information 0: found 0 LP procs Num HP: 0 Num LP: 0 Num HP Tickets: 0 Num LP Tickets: 0 This concludes loop #: 0 entered INFORMATION loop: 1 Proc is 0 entered INFORMATION loop: 2 Proc is 0 entered INFORMATION loop: 3 Proc is 0 etc..... 

Again, no idea why this isn't working... I'm sure there are multiple errors, and I have a crap ton of print out statements just to see where things are going wrong. This is also requiring quite a bit of debugging effort, so I'm not too optimistic about if anyone has an answer... For that purposes, and with those warnings, here is my entire scheduler function. Sorry for the length...

void scheduler(void) {   struct proc *p;   for(;;){     //TODO: Remove statement    cprintf("entered scheduler\n");      // Enable interrupts on this processor.     sti();      // Loop over process table looking for process to run.     acquire(&ptable.lock);      //keeps track of number of procs (to be used for lottery RNG)     int num_LP_t = 0;     int num_HP_t = 0;     int num_HP = 0;     int num_LP = 0;     int rand = 0;     int curr_tickets = 0;      //goes through once to complete information gathering for HP and LP queue      //TODO: remove i - for testing only     int i = -1;     for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){         i++;       //TODO: Remove statement        cprintf("entered INFORMATION loop: %d\n", i);        if (proc == 0) cprintf("Proc is 0\n");               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.       //TODO: uncomment? proc = p;        if (proc == 0) cprintf("Proc is 0 even after proc gets p in INFORMATION LOOP\n");       cprintf("Information %d: found %d HP procs\n", i, num_HP);       cprintf("Information %d: found %d LP procs\n", i, num_LP);       cprintf("Num HP: %d\n", num_HP);       cprintf("Num LP: %d\n", num_LP);       cprintf("Num HP Tickets: %d\n", num_HP_t);       cprintf("Num LP Tickets: %d\n", num_LP_t);       cprintf("This concludes loop #: %d\n", i);         if (p->priority_level == 1){           num_HP++;           num_HP_t += p->num_tickets;       }       if (p->priority_level == 0){           num_LP++;           num_LP_t += p->num_tickets;       }      }//end information loop    cprintf("Begin HP Queue:\n");      if (num_HP > 1){   cprintf("HP Queue had: %d procs to run\n", num_HP);         rand = random() % num_HP_t;   cprintf("We choose our random to be: %d\n", rand);         for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){              if (p->state != RUNNABLE) continue;             //TODO: uncomment? proc = p;             if (proc == 0) cprintf("Proc is 0 even after setting proc = p in HP queue\n");                if (p->priority_level == 1){   cprintf("Found a HP Proc while searching for rand, currently at: %d\n", curr_tickets);                 curr_tickets += p->num_tickets;                 if (curr_tickets >= rand){   if (proc == 0)   cprintf("proc is 0 while in HP queue 1\n");                     //proc = p;                     switchuvm(p);                    p->state = RUNNING;   /*cprintf("Proc Info:");   cprintf("uint sz: %d", proc->sz);        cprintf("enum procstate state: %s", proc->state);          cprintf("volatile int pid: %d", proc->pid);     cprintf("int killed: %d", proc->killed);              cprintf("int priority_level: %d", proc->priority_level);*/                     swtch(&cpu->scheduler, proc->context);                     switchkvm();                     if (p->state == RUNNABLE){   cprintf("HP process still runnable after 1 TS.\nHere is the updated information\n");                         p->priority_level = 0;                         num_HP--;                         num_LP++;                         num_HP_t -= p->num_tickets;                         num_LP_t += p->num_tickets;       cprintf("Num HP: %d\n", num_HP);       cprintf("Num LP: %d\n", num_LP);      cprintf("Num HP Tickets: %d\n", num_HP_t);       cprintf("Num LP Tickets: %d\n", num_LP_t);                     }                 }             }         }         }      else if (num_HP == 1){         for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){              if (p->state != RUNNABLE) continue;             //TODO: Uncomment? proc = p;             if (proc == 0) cprintf("Proc is 0 even after setting proc = p in HP == 1 queue\n");               if (p->priority_level == 1){                 //proc = p;                 switchuvm(p);                p->state = RUNNING;                 swtch(&cpu->scheduler, proc->context);                 switchkvm();                 if (p->state == RUNNABLE){                     p->priority_level = 0;                     num_HP--;                     num_LP++;                     num_HP_t -= p->num_tickets;                     num_LP_t += p->num_tickets;                 }             }         }      }//end else num_HP = 1      else if (num_HP < 1){          if (num_LP > 1){            rand = random() % num_LP_t;             for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){                  if (p->state != RUNNABLE) continue;                 //TODO: uncomment? proc = p;              if (proc == 0) cprintf("Proc is 0 even after setting proc = p in LP > 1 queue\n");                 if (p->priority_level == 0){                     curr_tickets += p->num_tickets;                     if (curr_tickets >= rand) {                         //proc = p;                         switchuvm(p);                        p->state = RUNNING;                         swtch(&cpu->scheduler, proc->context);                         switchkvm();                         if (p->state != RUNNABLE){                             num_LP--;                             num_LP_t -= p->num_tickets;                         }                     }                 }             }         }          else if (num_LP == 1){             for(p = ptable.proc; p < &ptable.proc[NPROC]; p++){                  if (p->state != RUNNABLE) continue;                 //TODO: Uncomment? proc = p;             if (proc == 0) cprintf("Proc is 0 even after setting proc = p in LP == 1 queue\n");                   if (p->priority_level == 0){                     //proc = p;                     switchuvm(p);                    p->state = RUNNING;                     swtch(&cpu->scheduler, proc->context);                     switchkvm();                     if (p->state != RUNNABLE){                         num_LP_t -= p->num_tickets;                     }                                }             }         }     }//end lp     proc = 0;     release(&ptable.lock);     }//end outer for loop (;;) }// end scheduler 

回答1:

commented out proc=p. Obvious things are obvious.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!