myxiaonia 发表于 2014-6-2 16:37:39

rtx 写的真有那么牛!!!???

本帖最后由 myxiaonia 于 2014-6-2 20:57 编辑

之前看其手册和坛友讨论,觉得必须好好研究其优越性,这段时间一直在看rtx的源码,情况似乎有些不尽人意


不说之前对membox的alloc和free函数封皮的疑问,现在看到mutex部分,疑问更加大了???

OS_RESULT rt_mut_release (OS_ID mutex)
{
...
/* Remove mutex from task mutex owner list. */
p_mlnk = os_tsk.run->p_mlnk;
if (p_mlnk == p_MCB) {
    os_tsk.run->p_mlnk = p_MCB->p_mlnk;
}
else {
    while (p_mlnk) {
      if (p_mlnk->p_mlnk == p_MCB) {
      p_mlnk->p_mlnk = p_MCB->p_mlnk;
      break;
      }
      p_mlnk = p_mlnk->p_mlnk;
    }
}

/* Restore owner task's priority. */
prio = os_tsk.run->prio_base;
p_mlnk = os_tsk.run->p_mlnk;
while (p_mlnk) {
    if (p_mlnk->p_lnk && (p_mlnk->p_lnk->prio > prio)) {
      /* A task with higher priority is waiting for mutex. */
      prio = p_mlnk->p_lnk->prio;
    }
    p_mlnk = p_mlnk->p_mlnk;
}
os_tsk.run->prio = prio;
if (p_MCB->p_lnk != NULL) {
...                                        //这段代码段已忽略------互斥量释放给其等待任务,这个等待任务获得了这个互斥量
}
else {
    /* Check if own priority lowered by priority inversion. */
    if (rt_rdy_prio() > os_tsk.run->prio) {
      rt_put_prio (&os_rdy, os_tsk.run);
      os_tsk.run->state = READY;
      rt_dispatch (NULL);
      os_tsk.run->ret_val = OS_R_OK;
    }
}

}

这个释放互斥量的链表操作一点都不简练,可以使用二级指针嘛,之前看到linus大神批判一个链表删除操作的问题,一模一样;然后是优先级恢复,怎么也应该先判断下释放的互斥量任务列表有没有导致优先级变化嘛;而且这里2个遍历互斥量链表操作,难道就不能合并在一起???优化工作很不到位啊
最后这个检查更是让人觉得笑掉大牙,这个互斥量都没有等待的任务链表,怎么可能会有优先级变化呢,更不要说降低了,实在是太不严谨了!!!!



呼唤wuzhujian大神答疑解惑

DWDM 发表于 2014-6-2 16:47:17

{:lol:} 以前不懂系统的时候用过这个,后来玩ucos

myxiaonia 发表于 2014-6-2 16:51:00

DWDM 发表于 2014-6-2 16:47
以前不懂系统的时候用过这个,后来玩ucos

可有对着两个系统的研究???网上说ucos2,内核效率绝对杠杠的,只是没有对cm3系列优化过,如果这个rtx评估到最后感觉不好,再去评估下ucos2把,,,,freertos又怎么样呢?

fengyunyu 发表于 2014-6-2 17:02:27

有批评才有进步,学习!

kinsno 发表于 2014-6-2 17:09:17

myxiaonia 发表于 2014-6-2 16:51
可有对着两个系统的研究???网上说ucos2,内核效率绝对杠杠的,只是没有对cm3系列优化过,如果这个rtx ...

哈哈,我一直在盯着你的笔记呢?不过话说对RTX一窍不通,没时间去折腾啊,UCOS2和UCOS3都用过,谈不上精通,基本跑着做产品问题是不大了;但依然不太想用,个人不喜欢掌控不住的东西;可能是早年写裸奔写多了的程序洁癖吧

myxiaonia 发表于 2014-6-2 17:12:58

kinsno 发表于 2014-6-2 17:09
哈哈,我一直在盯着你的笔记呢?不过话说对RTX一窍不通,没时间去折腾啊,UCOS2和UCOS3都用过,谈不上精 ...

这不是在深入学习么,嘿嘿

wuzhujian 发表于 2014-6-2 18:50:51

rtx的线程,有可能同时位于2个链表中:
1> 信号量、互斥量、队列等的等待链表;
2> 延时的计时链表。

因为有2个同时存在的双向链表,所以要设计2组指针,分别用于这2个链表的操作。

互斥量的主要应用场合是:保护一段代码互斥的访问。所以,一样有等待线程链表。
信号量的主要应用场合是:保护数据的互斥访问。所以,很多时候,互斥量与信号量可以通用。

但这二者是有区别的。

lcl 发表于 2014-6-2 19:08:57

搬凳子学习。。。。。。。。。

myxiaonia 发表于 2014-6-2 20:07:32

wuzhujian 发表于 2014-6-2 18:50
rtx的线程,有可能同时位于2个链表中:
1> 信号量、互斥量、队列等的等待链表;
2> 延时的计时链表。


确实如此,从TCB结构体中可以看到这2个双向链表的4个指针

之前这个函数的第3个代码 段,很明显这个互斥量没有等待任务,因此当前任务必定不会有优先级变化的疑问,所以这个代码段完全可以去掉,是这样的道理吗?

lulu爱 发表于 2014-6-3 12:02:10

raw-os的mutex的逻辑严谨性是目前rtos中几乎是最严谨的,mutex的逻辑是内核中最复杂的,因为涉及到优先级反转的重大问题。

prince2010 发表于 2014-6-4 12:26:40

顶一个{:smile:}

myxiaonia 发表于 2014-6-24 21:29:02

本帖最后由 myxiaonia 于 2014-6-24 21:30 编辑

这是最后修改的rt_mut_release函数,又修改了当释放互斥量的等待任务调度回来和当前任务运行的情况,原来的思路还是不清啊,只需要当前任务和此调度任务进行互相比较优先级即可,大家看看是不是简洁不少啊
OS_RESULT rt_mut_release (OS_ID mutex) {
/* Release a mutex object */
P_MUCB p_MCB = mutex;
P_TCBp_TCB;
P_TCBprun = os_tsk.run;

if (p_MCB->level == 0 || p_MCB->owner != prun) {
    /* Unbalanced mutex release or task is not the owner */
    return (OS_R_NOK);
}
if (--p_MCB->level != 0) {
    return (OS_R_OK);
}

/* Remove mutex from task mutex owner list. */
{
          P_MUCB *p = &prun->p_mlnk;
          do
          {
                  if (*p == p_MCB) {
                        *p = (*p)->p_mlnk;break;
                  }
                  else
                  {
                          p = &(*p)->p_mlnk;
                  }
          }while(*p);
}

if (p_MCB->p_lnk != NULL) {
    /* Restore owner task's priority. */
    if(p_MCB->p_lnk->prio >= prun->prio_base)
    {
          U8 prio = prun->prio_base;
          P_MUCBp_mlnk = prun->p_mlnk;
          while (p_mlnk != NULL) {
                if (p_mlnk->p_lnk != NULL && (p_mlnk->p_lnk->prio > prio)) {
                  /* A task with higher priority is waiting for mutex. */
                  prio = p_mlnk->p_lnk->prio;
                }
                p_mlnk = p_mlnk->p_mlnk;
          }
          prun->prio = prio;
    }
    /* A task is waiting for mutex. */
    p_TCB = rt_get_first ((P_XCB)p_MCB);
    rt_rmv_dly (p_TCB);
    /* A waiting task becomes the owner of this mutex. */
    p_MCB->level= 1;
    p_MCB->owner= p_TCB;
    p_MCB->p_mlnk = p_TCB->p_mlnk;
    p_TCB->p_mlnk = p_MCB;
    p_TCB->ret_val = OS_R_MUT;
        prun->ret_val = OS_R_OK;
    /* Priority inversion, check which task continues. */
    rt_dispatch (p_TCB);
    return (OS_R_OK);
}

hejiang177 发表于 2014-6-25 09:52:26

kinsno 发表于 2014-6-2 17:09
哈哈,我一直在盯着你的笔记呢?不过话说对RTX一窍不通,没时间去折腾啊,UCOS2和UCOS3都用过,谈不上精 ...

我现在也喜欢裸奔
页: [1]
查看完整版本: rtx 写的真有那么牛!!!???