next up previous contents
Next: Funkcja goodness() Up: Rozszerzenie dla obsługi wielu Previous: Funkcja __schedule_tail()   Spis rzeczy

Funkcja reschedule_idle()

Jak pamiętamy funckja reschedule_idle wywołana z procesem p w parametrze sprawdza, czy proces ten może wywłaszczyć jakiś inny działający. Jeżeli tak, to powoduje wywołanie funkcji schedule(), która to zrobi.

Funkcja w wersji obsługującej wieloprocesorowość robi generalnie to samo: szuka dla procesu p najbardziej odpowiedniego procesora, na którym działa proces, którego p może wywłaszczyć.

Algorytm:

  1. Jeżeli procesor, na którym ostatnio wykonywał się p jest wolny (tzn działa na nim proces tsk będący procesem typu idle), to ustawiana jest flaga need_resched procesu tsk i wymuszone jest uruchomienie planisty na tamtym procesorze. Dokładniej wymuszenie planisty na procesorze, na ktorym działa tsk następuje wtedy, gdy proces tsk nie miał już wcześniej ustawionej flagi need_reshed.

      best_cpu = p->processor;
      if (can_schedule(p, best_cpu)) {
          tsk = idle_task(best_cpu);
          if (cpu_curr(best_cpu) == tsk) {
             int need_resched;
    send_now_idle:
              need_resched = tsk->need_resched;
              tsk->need_resched = 1;
              if ((best_cpu != this_cpu) && !need_resched)
              smp_send_reschedule(best_cpu);
              return;
          }
      }
    

    Jeżeli to się nie uda wykonywany jest następny punkt:

  2. Znajdowany jest procesor, na którym najdłużej nie pracował proces inny niż idle (na takim procesorze jest bowiem nabardziej zdezaktualizowana pamięć cache i jej wymiana nie będzie wielką stratą). Na zmienną tsk zapamiętywany jest proces idle działający na tym procesorze. Jeżeli na żadnym procesorze nie działa proces idle to znajdowany jest procesor, na którym działa proces o najmniejszym priorytecie mniejszym od priorytetu p. (proces ten zapamiętywany jest na zmienną tsk). Jeżeli w wyniku tych kroków znaleziono jakiś proces tsk, którego p powinien wywłaszczyć to następuje wymuszenie wykonania planisty na procesorze, na którym działa tsk

    Oto kod znajdujący proces do wywłaszczenia:

    oldest_idle = (cycles_t) -1; target_tsk = NULL; max_prio = 1; 
    for (i = 0; i < smp_num_cpus; i++) {     
      cpu = cpu_logical_map(i);     
      if (!can_schedule(p, cpu)) continue;     
      tsk = cpu_curr(cpu);     
      if (tsk == idle_task(cpu)) {         
        if (last_schedule(cpu) < oldest_idle) {                 
          oldest_idle = last_schedule(cpu);                 
          target_tsk = tsk;         
        }     
      } else if (oldest_idle == -1ULL) {         
        int prio = preemption_goodness(tsk, p, cpu);         
        if (prio > max_prio) { max_prio = prio; target_tsk = tsk; }     
      } 
    }
    tsk = target_tsk;
    

    Wywłaszczenie jest wykonywane podobnie jak w punkcie 1 (patrz etykieta send_now_idle:).

W ten sposób został rozwiązany problem postawiony na początku rozdziału.


next up previous contents
Next: Funkcja goodness() Up: Rozszerzenie dla obsługi wielu Previous: Funkcja __schedule_tail()   Spis rzeczy
Ignacy Kowalczyk 2001-11-16