有了上面的讲解,我们发现os的代码其实也没有那么恐怖。所以,请大家一鼓作气,看看信号量是怎么删除的吧:

RAW_U16 raw_semaphore_delete(RAW_SEMAPHORE *semaphore_ptr)
{
 LIST *block_list_head;
 
 RAW_SR_ALLOC();

 #if (RAW_SEMA_FUNCTION_CHECK > 0)
 
 if (semaphore_ptr == 0) {
 
  return RAW_NULL_OBJECT;
 }
 
 #endif

 block_list_head = &semaphore_ptr->common_block_obj.block_list;
 
 RAW_CRITICAL_ENTER();

 /*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;
}RAW_U16 raw_semaphore_delete(RAW_SEMAPHORE *semaphore_ptr)
{
 LIST *block_list_head;
 
 RAW_SR_ALLOC();

 #if (RAW_SEMA_FUNCTION_CHECK > 0)
 
 if (semaphore_ptr == 0) {
 
  return RAW_NULL_OBJECT;
 }
 
 #endif

 block_list_head = &semaphore_ptr->common_block_obj.block_list;
 
 RAW_CRITICAL_ENTER();

 /*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)调用系统调度函数,因为高优先级的任务很有可能刚刚从阻塞队列中释放出来;

  (4)当前线程再次运行,函数返回。

  通过上面几个函数的讲解,我们发现关于os互斥部分的代码其实也不复杂。只要对系统本身和中断有一些了解,其实代码都是可以看懂的。当然,上面的代码我们还是讲的比较粗糙,所以有些细节还是要补充一下,

  (1)多线程共享的函数必须在关中断的情况下进行操作,当然多核的时候关中断也不好使了;

  (2)实时系统的抢占是每时每刻都在进行的,比如中断返回时、信号量释放时、调用延时函数、调用调度函数的时候,所以大家心中要有抢占的概念;

  (3)互斥函数中大量使用了链表的结构,建议大家好好掌握链表的相关算法;

  (4)关于os的代码一定要多看、多思考、多练习才会有进步和提高,纸上得来终觉浅、绝知此事要躬行。