Planificateur xv6 – proc never! = 0

Fondamentalement, j’implémente un planificateur pour le kernel xv6 qui implémente une queue prioritaire à plusieurs niveaux. J’ai un problème sérieux que je ne comprends pas, les assistants de mon cours ne comprennent pas et j’ai raté la date limite de ce projet. Je ne gagnerai donc pas de points supplémentaires, mais je VEUX savoir pourquoi j’ai le comportement suivant …

Tout d’abord, il s’agit du planificateur d’origine que je modifie pour xv6 (à titre de comparaison – ce n’est pas mon implémentation):

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

L’idée du nouvel ordonnanceur est la suivante: il y a un tableau rempli de structures de proc à l’intérieur de la table. J’appellerai chacun de ces éléments dans ce tableau proc ‘p’, et ils détiendront des informations de base (comme le nombre de “tickets” qu’ils ont ou leur état, etc.). Je dois exécuter tous les p de haute priorité (HP) pour une tranche de temps, puis modifier leur niveau de priorité sur faible. Lorsqu’il n’y a pas de procs HP, je choisis “au hasard” un proc et l’exécute pour DEUX tranches de temps. Mon algorithme est le suivant:

 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 hold LP lottery, run one LP proc for two time slices, similar to above else if #LP == 1 find the LP proc, run it 

Voici le problème … Mon proc semble toujours être égal à 0. Il ne voit jamais d’informations placées dans p, ne collecte pas d’informations proc à partir de p, etc. Je ne sais pas pourquoi.

J’ai testé avec une tonne de déclarations d’impression. Je vais poster la sortie de cela ici en premier:

 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..... 

Encore une fois, je ne sais pas pourquoi cela ne fonctionne pas … Je suis sûr qu’il y a de nombreuses erreurs et j’ai une tonne de déclarations imprimées juste pour voir où les choses ne vont pas. Cela nécessite également un peu d’effort de débogage, donc je ne suis pas trop optimiste quant à savoir si quelqu’un a une réponse … Pour cela, et avec ces avertissements, voici toute ma fonction de planificateur. Désolé pour la longueur …

 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 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 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 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){ rand = random() % num_LP_t; for(p = ptable.proc; 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 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 

    a commenté proc = p. Les choses évidentes sont évidentes.