• strex,ldrex


    volatile bool lock = false;
    void func(void)
    {
    int i;
    while(lock);
     
    lock = true;
    for(i = 0; i < 4; i++)
    {
    printk("pid = %d comm = %s ", 
    current->pid, current->comm);
    mdelay(1000);
    }
    lock = false;
    }
    对于上面的例子,在SMP系统中,假设cpu0的进程A获得了锁,cpu1的进程B、 cpu2的进程C由于拿不到锁而一直在while处空转,等待锁的释放。但是当cpu0的进程A在释放锁时,如果不能保证原子性,那么cpu1的进程B、 cpu2的进程C是有可能同时拿到锁的,此时临界区中的资源访问就不会按照预定的方式执行。在C的软件层面上,是不能保证原子性的,那么只有在硬件层面上去保证,庆幸的是armv6及以上的版本支持strex和ldrex指令来保证多核之间的数据同步和控制并发问题。
     
    static inline void arch_spin_lock(arch_spinlock_t *lock)
    {
        unsigned long tmp;

        __asm__ __volatile__(
    "1: ldrex   %0, [%1] "
    "   teq %0, #0 "                         //TEQ 按位异或,这里判断tmp是否为0,即锁是否被占用。
        WFE("ne")                              //tmp不等於0就执行WFE,使处理器进入a low-power state等待状态
    "   strexeq %0, %2, [%1] "        //当前进程加锁操作,成功tmp=0,失败tmp=1
    "   teqeq   %0, #0 "
    "   bne 1b"
        : "=&r" (tmp)
        : "r" (&lock->lock), "r" (1)
        : "cc");                                   //如果你使用的指令会改变CPU的条件寄存器cc,需要在修改描述部分增加“cc”

        smp_mb();
    }
    ========================
    WFE:
         Wait For Event is a hint instruction that permits the processor to enter a low-power state until one of a number of
    events occurs,
         Encoding A1 ARMv6K, ARMv7 (executes as NOP in ARMv6T2)
         WFE <c>
    ========================
    LDREX
         Load Register Exclusive calculates an address from a base register value and an immediate offset, loads a word from
    memory, writes it to a register and:
    •     if the address has the Shared Memory attribute, marks the physical address as exclusive access for the
          executing processor in a global monitor
    •     causes the executing processor to indicate an active exclusive access in the local monitor.
     
    Encoding A1           ARMv6*, ARMv7
         LDREX<c> <Rt>, [<Rn>]
     
    Assembler syntax
    LDREX{<c>}{<q>}  <Rt>, [<Rn> {, #<imm>}]
    where:
                   
    <c>, <q>     See Standard assembler syntax fields on page A8-287.
                   
    <Rt>           The destination register.
                   
    <Rn>          The base register. The SP can be used.
                   
    <imm>        The immediate offset added to the value of <Rn> to form the address. <imm> can be omitted, meaning
                   an offset of 0. Values are:
                   Encoding T1              multiples of 4 in the range 0-1020
                   Encoding A1              omitted or 0.
     
    Operation
    if ConditionPassed() then
        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
        address = R[n] + imm32;
        SetExclusiveMonitors(address,4);
        R[t] = MemA[address,4];
     
     
    ==========================
    STREX
         Store Register Exclusive calculates an address from a base register value and an immediate offset, and stores a word
    from a register to memory if the executing processor has exclusive access to the memory addressed.
     
    Encoding A1           ARMv6*, ARMv7
    STREX<c> <Rd>, <Rt>, [<Rn>]
     
    Assembler syntax
    STREX{<c>}{<q>} <Rd>, <Rt>, [<Rn> {, #<imm>}]
    where:
             
    <c>, <q>     See Standard assembler syntax fields on page A8-287. 
             
    <Rd>        The destination register for the returned status value. The value returned is:                  
                       0           if the operation updates memory              
                       1           if the operation fails to update memory. 
            
    <Rt>      The source register. 
             
    <Rn>     The base register. The SP can be used. 
             
    <imm>     The immediate offset added to the value of <Rn> to form the address. Values are multiples of 4 in the 
                       range 0-1020 for encoding T1, and 0 for encoding A1. <imm> can be omitted, meaning an offset of 0.
     
    Operation
    if ConditionPassed() then
        EncodingSpecificOperations(); NullCheckIfThumbEE(n);
        address = R[n] + imm32;
        if ExclusiveMonitorsPass(address,4) then
             MemA[address,4] = R[t];
             R[d] = 0;
        else
             R[d] = 1;
  • 相关阅读:
    【C#界面库】关于C#界面库的选择
    asp.net mvc 学习笔记
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(7)- EF增删改查
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(6)- 创建数据库
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(5)- 创建项目结构
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(4)- 漂亮的登录界面
    ASP.NET MVC5 + EF6 + LayUI实战教程,通用后台管理系统框架(3)
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(2)
    ASP.NET MVC5+EF6+LayUI实战教程,通用后台管理系统框架(1)
    初学编程:8款最佳Raspberry Pi 操作系统/项目
  • 原文地址:https://www.cnblogs.com/black-mamba/p/4986284.html
Copyright © 2020-2023  润新知