pintos (2) --Priority Scheduling

爲Pintos建立優先級調度機制,並確保任何時刻CPU上運行的都是最高優先級線程。

  • 爲確保最高優先級的線程運行,需要重新計算調度的時刻有:創建新線程,設置線程優先級。故將ready_list改爲有序隊列,優先級較高在前,同時在thread_yield()時,如果下個線程的優先級小於當前線程,則不進行調度。
  • 信號量和條件變量的優先級,均可通過保證waiters list 按優先級排列實現喚醒優先級最高的線程。

基礎優先級:

thread_create()函數結尾處增加調度判斷:

/* If the new thread have a greater priority,
   * we should add current thread to ready list and schedule.*/
  struct thread * cur_t = thread_current();
  if(priority > cur_t->priority){
      thread_yield();
  }

thread_unblock()中將list_push_back(),改爲list_insert_ordered(&ready_list, &t->elem, priority_less, NULL);

priority_less()函數實現如下:

/* Compare struct thread by priority.
 * The bigger number means the bigger priority,
 * so use '>' to make the bigger priority in the front of list.*/
bool
priority_less(const struct list_elem *e1,const struct list_elem *e2, void *aux){
    return list_entry(e1, struct thread, elem)->priority > list_entry(e2, struct thread, elem)->priority;
}

thread_yield()中判斷下個線程的優先級,如果小於當前線程則不調度:

void
thread_yield (void) 
{
  struct thread *cur = thread_current ();
  enum intr_level old_level;

  ASSERT (!intr_context ());

  old_level = intr_disable ();
  if (cur != idle_thread){
      /* If the next ready thread priority is lower than current, just do nothing.*/
      if(!list_empty(&ready_list)){
          int next_thread_priority = list_entry (list_front(&ready_list), struct thread, elem)->priority;
          if(next_thread_priority >= cur->priority){
              list_insert_ordered(&ready_list, &cur->elem, priority_less, NULL);
              cur->status = THREAD_READY;
              schedule ();
          }
      }
  }
  intr_set_level (old_level);
}

設置線程優先級後進行一次thread_yield():

/* Sets the current thread's priority to NEW_PRIORITY. */
void
thread_set_priority (int new_priority) 
{
    enum intr_level old_level = intr_disable ();
    thread_current ()->priority = new_priority;
    thread_yield();
    intr_set_level (old_level);
}

至此,alarm-priority priority-change priority-fifo priority-preempt測試通過


信號量優先級:

將等待該信號量的線程按優先級排列後,sema_up()函數即可實現喚醒優先級最高的等待線程。

sema_down()中的list_push_back()修改爲:
list_insert_ordered(&sema->waiters, &thread_current ()->elem, priority_less, NULL);
priority_less()複用上文中的函數。

priority-sema測試通過


條件變量優先級:

  • 一個條件變量是由一個 struct conditon 和 一個 lock 組成,lock用來保證condtion操作不發生衝突,conditon 包含一個等待該條件的sema list。
  • 當條件成立的時候,即cond_signal()函數被調用,其喚醒sema list中的第一個的信號量。我們希望喚醒優先級最高的線程,所以我們需要將sema list按擁有sema的線程優先級排列。

在semaphore_elem中增加指向擁有該信號量的線程的指針owner:

/* One semaphore in a list. */
struct semaphore_elem 
  {
    struct list_elem elem;              /* List element. */
    struct semaphore semaphore;         /* This semaphore. */
    struct thread *owner;               /* Owner of this semaphore.*/
  };

在cond_wait()中,對owner進行初始化:
waiter.owner = thread_current();

同時將list_push_back()改爲:
list_insert_ordered(&cond->waiters, &waiter.elem, priority_less_cond, NULL);

其中,priority_less_cond()實現如下:

/*
 * Compare the cond->waiters list element semaphore_elem's owner thread priority.
 * See as thread/priority_less()
 * */
bool
priority_less_cond(const struct list_elem *e1,const struct list_elem *e2, void *aux){
    return list_entry(e1, struct semaphore_elem, elem)->owner->priority > list_entry(e2, struct semaphore_elem, elem)->owner->priority;
}

priority-condvar測試通過

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章