ARM平台上的Linux内核(3.5.2之前)中的Mutex实现

时间:2012-11-12 09:42:22

标签: linux locking arm mutex

我对ARM平台上Linux内核中的互斥锁实现有疑问。

__mutex_fastpath_lock(atomic_t *count, void (*fail_fn)(atomic_t *))
{
    int __ex_flag, __res;

    __asm__ (

             "ldrex  %0, [%2]        \n\t"
             "sub    %0, %0, #1      \n\t"
             "strex  %1, %0, [%2]    "  //for ARMv6+ ,kernel use ldrex/strex implement mutex lock.

              : "=&r" (__res), "=&r" (__ex_flag)
              : "r" (&(count)->counter)
              : "cc","memory" );

             __res |= __ex_flag;    //How can we know the "strex" operation is successfully finished or not? 
                                    //The status of (atomic_t *count) is different in these two cases. 
                                    //I wonder this is a bug ,or I did not understand the lock mechanism so well.

      if (unlikely(__res != 0))
           fail_fn(count);
      }

非常感谢您对此问题的建议或回答。任何事情都会受到赞赏。

有关源代码的更多信息,请参阅; http://lxr.oss.org.cn/source/arch/arm/include/asm/mutex.h?v=3.5.2;a=arm

文件路径为:

linux-3.5.2/arch/arm/include/asm/mutex.h

1 个答案:

答案 0 :(得分:4)

如果成功,

__res为零

  

STREX {cond} Rd,Rm,[Rn]存储到Rn中的地址,如果在Rd中成功则标记                              (如果成功则Rd = 0)

请注意__res__ex_flag

相同
 __res |= __ex_flag;

因此,如果ldrexstrex操作失败,则检查失败。

注意:如果在ldrex之后访问该值,则独占访问失败; strex失败,并且不会存储该值。有关此内容的更多信息,请参见info center

  

STREX指令执行单词的条件存储   记忆。 如果专用监视器允许存储,则操作   更新内存位置并在目标中返回值0   注册,表示操作成功。如果是独家的   监视器不允许存储,操作不更新   内存位置并在目标寄存器中返回值

重点是,如果独占访问失败,无论是加载还是存储,内核都会知道它,因为__ex_flags=1__res=1,如果它没有失败,但互斥锁已被锁定我们仍然会知道它,因为__res=0xFFFFFFFF此时独占访问权限是否失败并不重要,因为互斥锁已锁定

现在,我看到的唯一问题是它会将0xFFFFFFFF存储到计数中,但是当锁定互斥锁的人解锁时,它可能会再次增加,这意味着它可能是多个线程在互斥锁上等待的方法。这来自您链接中的评论:

  

如果一旦递减它不为零,或者由于a而导致其存储失败   关于专卖店的争议,我们只是立即通过纾困   慢速路径锁定将被重新尝试,直到成功为止