当前位置:编程学习 > 网站相关 >>

RAW-OS学习之mutex源码注释与解析

 
         mutex的出现是为了解决优先级反转的问题,由于优先级反转对实时性影响太大,所以mutex 的稳定性直接影响了实时性。纵观目前多种实时操作系统mutex 的设计原理是多多少少有一点问题的,raw os 的mutex 模块成功弥补了其它实时系统在这方面的不足。
raw os 的mutex同时支持优先级置顶和优先级继承的方式来解决优先级反转的问题。
raw os 的mutex比较其它实时系统,比如ucos, ecos, freertos 等占尽了优势,因为当一个任务经历两次以上的优先级提升时,其它系统基本都不支持优先级的逐步还原,那样带来的后果是不能解决优先级反转带来的问题。而且像ucos系统去改变一个优先级被提升之后的任务的优先级的话,整个逻辑都会出错。而且rawos 的mutex 同时支持优先级置顶和优先级反转的策略,增加了用户使用的策略,显得更为灵活强大。
当有一个临界区资源同时存在不同优先级的任务抢占时,推荐使用mutex而不是semaphore, 因为优先级反转的问题对实时性伤害太大。
 
上一段话来着raw-os的作者jorya_txj的博客:http://blog.csdn.net/jorya_txj/article/details/8545145
 
 
 
 
 
下面可以通过mutex相关源码来看看raw-os是如何做到优先级的逐步还原,最主要看raw_mutex_get和raw_mutex_put函数
 
//创建一个mutex
RAW_U16 raw_mutex_create(RAW_MUTEX *mutex_ptr, RAW_U8 *name_ptr, RAW_U8 policy, RAW_U8 ceiling_prio)
{
              #if (RAW_MUTEX_FUNCTION_CHECK > 0)
              if (mutex_ptr == 0) {
                            return RAW_NULL_OBJECT;
              }
              if ((policy != RAW_MUTEX_CEILING_POLICY) && (policy != RAW_MUTEX_INHERIT_POLICY) && (policy != RAW_MUTEX_NONE_POLICY)) {
                            return RAW_MUTEX_NO_POLICY;
              }
              #endif
             
              list_init(&mutex_ptr->common_block_obj.block_list);//初始化该互斥锁的阻塞任务链表
              mutex_ptr->common_block_obj.block_way = RAW_BLOCKED_WAY_PRIO;//初始化任务阻塞方式,规定使用基于优先级
              mutex_ptr->common_block_obj.name  =  name_ptr;//初始化互斥锁名称
              mutex_ptr->mtxtsk                = 0;//初始化该互斥锁获得者,初始化为0
              mutex_ptr->mtxlist                 = 0;//初始化该互斥锁链接的下一个节点指针为0
              mutex_ptr->policy = policy;//初始化该互斥锁使用策略(RAW_MUTEX_INHERIT_POLICY:优先级继承
                                                                           RAW_MUTEX_CEILING_POLICY:优先级置顶//)
             
              /*
              ***************************************************
              *优先级继承策略:如果有高优先级的任务task1进入运行态并且要获取互斥锁mutex,而此时mutex被低优先级任务task2占用,
              *这时需要把task2的任务暂时置为与task1一样的优先级,让task2快点运行然后释放mutex,再恢复task2的优先级,让task1能够得以尽快执行。
              *优先级置顶策略:如果任务需要获取互斥锁,并且该互斥锁没有被占用,则把该任务的优先级先置为该互斥锁设定的优
              *先级置顶值。(使用优先级置顶策略时,该优先级置顶值必须比可能获取该互斥锁的所有任务优先级别都高)
              ***************************************************
              */
              mutex_ptr->ceiling_prio = ceiling_prio;//初始化ceiling_prio,用于使用优先级置顶策略,设定置顶的优先级号,
                                                     //该优先级必须高于所有可能会获取该锁的所有任务级别。
              mutex_ptr->common_block_obj.object_type = RAW_MUTEX_OBJ_TYPE;//object类型标准             
              return RAW_SUCCESS;
}
 
/*用于获取指定互斥锁*/
RAW_U16 raw_mutex_get(RAW_MUTEX *mutex_ptr, RAW_U32 wait_option)
 
{
              RAW_U16                    error_status;
              RAW_TASK_OBJ          *mtxtsk;
             
              RAW_SR_ALLOC();
 
              #if (RAW_MUTEX_FUNCTION_CHECK > 0)
              if (mutex_ptr == 0) { 
                            return RAW_NULL_OBJECT;
              }
              if (raw_int_nesting) {  //中断中不允许获取互斥锁,因为该函数可能引起任务阻塞      
                            return RAW_NOT_CALLED_BY_ISR;            
              }
              #endif
 
              if (mutex_ptr->common_block_obj.object_type != RAW_MUTEX_OBJ_TYPE) {
                            return RAW_ERROR_OBJECT_TYPE;
              }
 
              RAW_CRITICAL_ENTER();
 
              if (raw_task_active == mutex_ptr->mtxtsk) { //如果当前任务已经占用着这个互斥锁了,返回RAW_MUTEX_DEADLOCK
 
                            #if (CONFIG_RAW_ASSERT > 0)
                            RAW_ASSERT(0);
                            #endif
                   RAW_CRITICAL_EXIT();  
              &n
补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,