说完了这些,我们看看信号量的获取是怎么完成的,代码可能长度稍微长一些,不过也不用太紧张。

RAW_U16 raw_semaphore_get(RAW_SEMAPHORE *semaphore_ptr,  RAW_U32 wait_option)
{

 RAW_U16 error_status;

 RAW_SR_ALLOC();

 #if (RAW_SEMA_FUNCTION_CHECK > 0)

 if (semaphore_ptr == 0) {
  
  return RAW_NULL_OBJECT;
 }
 
 if (raw_int_nesting) {

  return RAW_NOT_CALLED_BY_ISR;
 }

 #endif
 
 
 RAW_CRITICAL_ENTER();
 if (semaphore_ptr->count) {                     
  semaphore_ptr->count--;                                      

  RAW_CRITICAL_EXIT();
  
  return RAW_SUCCESS;
 }
 
 /*Cann't get semphore, and return immediately if wait_option is  RAW_NO_WAIT*/
 if (wait_option == RAW_NO_WAIT) {

  RAW_CRITICAL_EXIT();
  return RAW_NO_PEND_WAIT;
 }     
 
 if (raw_sched_lock) {  
  RAW_CRITICAL_EXIT(); 
  return RAW_SCHED_DISABLE;
 }

 raw_pend_object(&semaphore_ptr->common_block_obj, raw_task_active, wait_option);
 RAW_CRITICAL_EXIT();

 raw_sched();
 
 error_status = block_state_post_process(raw_task_active, 0);
 return error_status;

}

  信号量的获取情况比较复杂一些,这在长度上也体现出来了。不过没关系,我们一步一步看函数做了什么,

  (1)判断参数合法性;

  (2)判断当前函数是否处于中断处理的流程中,如果是选择返回;

  (3)判断当前count是否为0,如果不为 0,则减1返回;

  (4)如果当前count是0,且线程不愿意等待,那么选择返回;

  (5)如果当前禁止调度,那么依然选择返回;

  (6)当前线程将自己挂起,从ready队列中删除,把自己pend到信号量的阻塞队列中;

  (7)阻塞的线程再次获得了运行的机会,我们从task数据结构获得返回结果,此时也不一定是因为获得了资源的缘故哦。