Commits

Paweł Wieczorek committed 8730e75

* dodano komentarze do lib/sched.c

Comments (0)

Files changed (1)

  * public
  */
 
+/**
+ * @brief inicjalizacja programu planisty
+ *
+ * Procedura powinna być uruchamiana na~końcu inicjalizacji biblioteki.
+ */
 void
 pwuthread_sched_init(void)
 {
+    assert(IS_PREEMPTIVE());
     LIST_CREATE(&Q_run, pwuthread_s, L_sched1, 1);
     LIST_CREATE(&Q_wait, pwuthread_s, L_sched2, 0);
     LIST_CREATE(&Q_sleep, pwuthread_s, L_sched2, 0);
     pwuthread_time_get(last_time);
     
     pwuthread_sched_install();
+    // tworzenie wątku idle
     pwuthread_create(&idle_thread, NULL, sched_idle, NULL);
 }
 
+/**
+ * @brief dodanie wątku do kolejki działających
+ * @param t deskryptor wątku
+ * @warning wchodzi w sekcję krytyczną planisty
+ *
+ * Zewnętrzna procedura używana w module lib/thread.c
+ */
 void
 pwuthread_sched_insert(pwuthread_t t)
 {
     pwuthread_sched_unlock();
 }
 
+/**
+ * @brief odłączenie martwego wątku
+ * @param t martwy wątek do odłączenia
+ * @warning wymaga bycia w sekcji krytycznej planisty
+ *
+ * Zewnętrzna procedura służąca do przeniesienia wątku
+ * z kolejki żywych trupów do kolejki wątków do zniszczenia
+ */
 void
 pwuthread_sched_detach(pwuthread_t t)
 {
     Qdetached_insert(t);
 }
 
+/**
+ * @brief przekazanie czasu procesora do danego wątku
+ * @param t wątek który powinine otrzymać czas procesora
+ * @warning może być używane jedynie przez program planisty
+ *
+ * Procedura może ulec przeróbką przy implementacji
+ * modelu koooperatywnego.
+ */
 void
 pwuthread_sched_switch(pwuthread_t t)
 {
     }
 }
 
-/*
+/**
+ * @brief zakończenie pracy obecnego wątku
+ * @warning wchodzi w sekcję krytyczną planisty
  *
+ * Procedura jest odpowiedzialna za zakończenie obecnego wątku, a w tym
+ * przeniesienie go do kolejki żywych trupów lub wątków do odłączonych
+ * oraz obudzenie wątku dołączonego (join).
  */
 void
 pwuthread_sched_exit(void)
 }
 
 
+/**
+ * @brief uśpienie obecngo wątku
+ * @warning zachowuje stan bycia w sekcji krytycznej planisty
+ *
+ * Procedura zatrzymuje obecny wątek, a w tym przenosi go do kolejki wątków
+ * oczekujących.
+ */
 void
 pwuthread_sched_wait(void)
 {
     }
 }
 
+/**
+ * @brief procedura budzi dany wątek
+ * @warning wymaga bycia w sekcji krytycznej planisty
+ * @param t oczekujących wątek do obudzenia
+ */
 void
 pwuthread_sched_wakeup(pwuthread_t t)
 {
     sched_wakeup(t);
 }
 
+/**
+ * @brief uśpienie obecnego wątku na czas
+ * @param ts ilość sekund
+ * @param tus ilość mikrosekund
+ * @warning zachowuje stan bycia w sekcji krytycznej planisty
+ *
+ * Procedura zatrzymuje obecny wątek, a w tym przenosi go do kolejki
+ * śpiochów.
+ */
 void
 pwuthread_sched_timedwait(int ts, int tus)
 {
  * glowny kod planisty
  */
 
-/*
+/**
+ * @brief program planisty
+ * @warning nie może być użyta jawnie
  *
+ * Procedura realizuje główny program planisty, a w tym wybranie kolejnego
+ * wątku który powinien dostać czas procesora oraz zadania administracyjne.
  */
 void
 pwuthread_sched_tick(void)
 {
     pwuthread_t cur = pwuthread_current;
     pwuthread_t next = sched_next();
-
-    sched_handle_detached();
-    sched_handle_sleepers();
-    
+ 
+    /* 
+     * Zatrzymanie obecnego wątku na żądanie nie jest możliwe, stąd
+     * operacja odbywa się za pomocą bitu PWUTHREAD_NEED_STOP.
+     */
     if (BIT_ISSET(cur->sched_flags, PWUTHREAD_NEED_STOP)) {
         pwuthread_log("thread %p removed from run queue", cur);
         BIT_UNSET(cur->sched_flags, PWUTHREAD_NEED_STOP);
         Qrun_remove(cur);
     }
+    
+    sched_handle_detached();
+    sched_handle_sleepers();
+
     pwuthread_sched_switch(next);
 }
 
+/**
+ * @brief obsługa śpiochów
+ * @warning może być użyte jedynie przez program planisty
+ *
+ * Procedura wykonuje zadanie administracyjne, w którym pomniejsza
+ * czasomierz każdego śpiocha, a kiedy ten odmierzy odpowiedni czas
+ * to budzi wątek.
+ */
 void
 sched_handle_sleepers(void)
 {
     for (t = list_head(&Q_sleep); t != NULL; t = tnext) {
         tnext = list_next(&Q_sleep, t);
         if (pwuthread_time_sub(t->wakeup_timer, diff_time)) {
+            /*
+             * Poniższa konstrukcja może być myląca, ale jest konieczna
+             * ze względów estetycznych. Można budzić jedynie wątki
+             * OCZEKUJĄCE, a nie ŚPIOCHY. Stąd aby obudzić śpiocha
+             * należy najpierw przenieść go do kolejki oczekujących.
+             */
             Qsleep_remove(t);
             Qwait_insert(t);
             sched_wakeup(t);
     pwuthread_time_get(last_time);
 }
 
+/**
+ * @brief niszczenie niepotrzebnych wątków
+ * @warning może być użyte jedynie przez program planisty
+ *
+ * Procedura wykonuje zadanie administracyjne, w którym niszczy zasoby
+ * wątków.
+ */
 void
 sched_handle_detached(void)
 {
  * internal
  */
 
+/**
+ * @brief wątek nierób
+ * 
+ * Wątek idle jest tworzony przez program planisty aby zawsze w kolejce
+ * Q_run był co najmniej jeden wątek chcący działać. Mechanizm można
+ * z optymalizować przez przenoszenie idle do Q_run tylko gdy ta stanie
+ * się pusta. Lub usypiać proces.
+ *
+ * Wątek idle prosi system operacyjny o uśpienie procesu na jedną sekundę,
+ * lecz tak się nie dzieję. System po uśpieniu procesu obudzi go za raz
+ * po dostarczeniu sygnału czasomierza - że czas na "tyknięcie zegara" 
+ * i uruchomienie podprogramu planisty. W efekcie wątek idle usypia proces
+ * na czas ,,do następnego tyknięcia''.
+ */
 void *
 sched_idle(void *a)
 {
     while (1) {
-        if (0)
-        pwuthread_log("Q run:%u wait:%u sleep:%u zombie:%u detached:%u",
-        list_length(&Q_run), list_length(&Q_wait), list_length(&Q_sleep),
-        list_length(&Q_zombie), list_length(&Q_detached));
+        if (0) pwuthread_log("Q run:%u wait:%u sleep:%u zombie:%u detached:%u",
+            list_length(&Q_run), list_length(&Q_wait), list_length(&Q_sleep),
+            list_length(&Q_zombie), list_length(&Q_detached));
         sleep(1);
     }
 }
 
+/**
+ * @brief wybiera kolejny wątek zasługujący na czas procesora
+ * @warning może być użyte jedynie przez program planisty
+ * @return deskryptor kolejnego wątku
+ * 
+ * Procedura obecnie nie uwzględnia żadnych priorytetów, po prostu
+ * zwraca kolejny proces z kolejki.
+ */
 pwuthread_t
 sched_next()
 {
     return list_next(&Q_run, pwuthread_current);
 }
 
+/**
+ * @brief wewnętrzna procedura budząca dany wątek oczekujący
+ * @param t oczekujący wątek do obudzenia
+ * @warning wymaga bycia w sekcji krytycznej planisty
+ */
 void
 sched_wakeup(pwuthread_t t)
 {
     pwuthread_log("thread %p wakeup", t);
 }
 
+/**
+ * @brief wewnętrzna procedura usypiająca dany wątek
+ * @warning wymaga bycia w sekcji krytycznej planisty
+ */
 void
 sched_wait(void)
 {
     BIT_SET(cur->sched_flags, PWUTHREAD_NEED_STOP);
 }
 
+/**
+ * @brief wewnętrzna procedura usypiająca dany wątek na czas
+ * @warning wymaga bycia w sekcji krytycznej planisty
+ */
 void
 sched_timedwait(int s, int u)
 {
     BIT_SET(cur->sched_flags, PWUTHREAD_NEED_STOP);
 }
 
-/*
- *
+/**
+ * @brief wstawia wątek w odpowiednią kolejkę
+ * @param Q kolejka
+ * @param t wątek
+ * @param b bit związany z kolejką
  */
 void
 Q_insert(list_t *Q, pwuthread_t t, int b)
     BIT_SET(t->sched_flags, b);
 }
 
-/*
- *
+/**
+ * @brief kasuje wątek z odpowiedniej kolejki
+ * @param Q kolejka
+ * @param t wątek
+ * @param b bit związany z kolejką
  */
 void
 Q_remove(list_t *Q, pwuthread_t t, int b)