和之前的信号量释放相比,互斥量的释放要复杂一切,关键在于修改优先级的问题。我们来梳理一下,

  (1)判断参数合法性;

  (2)判断线程是否为互斥量的占有线程,不是则返回;

  (3)判断等待队列是否为空,为空的话则返回;

  (4)判断占有任务的优先级有没有发生变化,如果有则需要重新修改优先级,重新加入调度队列中;

  (5)选择下一个可以调度的线程;

  (6)函数返回。

  说了这么些,剩下后一个删除互斥量了,大家再接再厉,一起去学习。

RAW_U16  raw_mutex_delete(RAW_MUTEX *mutex_ptr)
  {
   LIST *block_list_head;
  
   RAW_TASK_OBJ  *mutex_occupy;
  
   RAW_SR_ALLOC();
 
   #if (RAW_MUTEX_FUNCTION_CHECK > 0)
 
   if (mutex_ptr == 0) {
    return RAW_NULL_OBJECT;
   }
  
   #endif
 
   block_list_head = &mutex_ptr->common_block_obj.block_list;
  
   RAW_CRITICAL_ENTER();
 
   mutex_occupy = mutex_ptr->occupy;   
   /*if mutex is occupied and occupy priority is not the original priority*/
   if ((mutex_occupy) &&  (mutex_occupy->priority !=  mutex_ptr->occupy_original_priority)) {
    switch (mutex_occupy->task_state) {                    
     case RAW_RDY:
      /*remove from the ready list*/
      remove_ready_list(&raw_ready_queue, mutex_ptr->occupy);
      /*raise the occupy task priority*/
      mutex_occupy->priority =  mutex_ptr->occupy_original_priority;
      /*readd to the ready list head*/
      add_ready_list_end(&raw_ready_queue, mutex_ptr->occupy);
      break;
 
     case RAW_DLY:
     case RAW_SUSPENDED:
     case RAW_DLY_SUSPENDED:
      /*occupy task is not on any list, so just change the priority*/
      mutex_occupy->priority = mutex_ptr->occupy_original_priority;
      break;
 
     case RAW_PEND:
     case RAW_PEND_TIMEOUT:
     case RAW_PEND_SUSPENDED:
     case RAW_PEND_TIMEOUT_SUSPENDED:
      /*occupy task is on the block list so change the priority on the block list*/
      mutex_occupy->priority = mutex_ptr->occupy_original_priority;
      change_pend_list_priority(mutex_occupy);
 
      break;
 
     default:
      RAW_CRITICAL_EXIT();
      return RAW_STATE_UNKNOWN;
    }
   }
 
  
   /*All task blocked on this queue is waken up*/
   while (!is_list_empty(block_list_head)) {
    delete_pend_obj(list_entry(block_list_head->next, RAW_TASK_OBJ, task_list));
   }            
 
   RAW_CRITICAL_EXIT();
 
   raw_sched();
  
   return RAW_SUCCESS;
  }

  互斥量的操作在实际情形下未必是存在的,所以作者在设计的时候添加了一个编译宏。不过删除所做的工作也不难理解,一个是处理好当前占有者的关系,一个是处理好等待队列的关系。我们来细看一下流程,

  (1)判断当前参数合法性;

  (2)判断占有者的情况,修改任务优先级,这里的情形和上面申请互斥量的处理方式是一样的,不再赘述;

  (3)唤醒所有的等待线程,如果线程已经suspend掉了,那么继续suspend;

  (4)调度到其他线程,防止有优先级高的任务已经被释放出来了;

  (5)函数返回,结束。