zoukankan      html  css  js  c++  java
  • 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;
  • 相关阅读:
    Android中的Handler, Looper, MessageQueue和Thread
    ANR程序无响应原因及应对办法
    避免内存泄露的一些简单方法
    android内存泄露及OOM介绍
    listview异步加载图片优化
    利用convertView及viewHolder优化Adapter
    Sqlite介绍及其语句
    关于单页面和传统页面跳转的思考
    快速入门Vue
    JS编码
  • 原文地址:https://www.cnblogs.com/black-mamba/p/4986284.html
Copyright © 2011-2022 走看看