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测试通过

  • 5
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值