【问题标题】:Mutex implementation in Linux kernel (before 3.5.2 ) on ARM platformARM 平台上 Linux 内核(3.5.2 之前)中的互斥锁实现
【发布时间】:2012-11-12 09:42:22
【问题描述】:

我有一个关于在 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

【问题讨论】:

    标签: linux locking arm mutex


    【解决方案1】:

    __res 如果成功则为零

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

    请注意,__res__ex_flag 是 or'd

     __res |= __ex_flag;
    

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

    注意:如果在ldrex之后访问该值,则独占访问失败; strex 失败,不会存储该值。 info center 中有更多相关信息:

    STREX 指令执行一个字的条件存储以 记忆。 如果独占监视器允许存储,则操作 更新内存位置并在目的地返回值 0 注册,表示操作成功。如果独家 监视器不允许存储,操作不会更新 内存位置并在目标寄存器中返回值 1

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

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

    如果一旦递减它就不是零,或者它的回存失败是由于 专卖店纠纷,我们直接通过 在成功之前将重新尝试锁定的慢速路径

    【讨论】:

    • 感谢您的回复。但是,你看到了问题,内核没有检查 %1(__ex_flag) ,所以我们不知道结果是否存储。
    • @user1296994 确实如此,因为它与__res 是或'd,所以如果其中任何一个为真,则操作失败。
    • 不同的是; 1.如果strex成功,lock减1。2.如果不成功,lock不减1。所以结果不一样。
    • @user1296994 啊我明白你的意思,但是如果strex 失败,它不会被存储
    • 考虑这两种情况;如果 %0 在 ("sub %0, %0, #1 \n\t") 中不为零 情况 1:strex 成功,所以 lock_counter 减 1。情况 2:strex 失败,lock_counter 不减。结果不同,但内核不知道。我想知道内核如何处理这两种不同的情况。
    猜你喜欢
    • 2014-10-09
    • 2021-03-08
    • 2023-04-09
    • 2011-06-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-18
    • 2023-03-22
    相关资源
    最近更新 更多