双核互斥问题

想利用cmpxchg指令来实现双核对临界资源的互斥访问。如下代码:


static volatile __com u32 spinlock;
void spin_lock(void)
{
 u32 lock = 1;
 u32 ret0 = 0;
 u32 ret1 = 1;
 u32 unlock;
 s32 ret;
 while(1){
  unlock = 0;
   asm("cmpxchg %0,%1,%2":"+r"(unlock):"r"(lock),"r"(&spinlock));
   asm("cmov %0,%1,%2":"=r"(ret):"r"(ret0),"r"(ret1));
  if(ret)
   break;
 }
}

void spin_unlock()
{
#if 1
 spinlock = 0;
#else
 u32 unlock = 0;
 u32 lock;
 u32 ret0 = 0;
 u32 ret1 = 1;
 s32 ret;
 while(1){
  lock = 1;
   asm("cmpxchg %0,%1,%2":"+r"(lock):"r"(unlock),"r"(&spinlock));
   asm("cmov %0,%1,%2":"=r"(ret):"r"(ret0),"r"(ret1));
  if(ret)
   break;
 }
#endif
}

在RISC0调用spin_lock() 和 spin_unlock()发现正常,能锁住,也能解锁。
但RISC0和RISC1都使用它们对临界资源进行保护时,发现不能正常上锁。
例如,在spin_lock()函数中,即使spinlock=0,经过cmpxchg指令后,unlock变成了1,但spinlock仍然等于0.
怀疑cmpxchg指令有问题。。

cmpxchg is an atomic compare-exchange instruction.  Its operation is as follows:
cmpxchg rD,rA,rB
T = MEM32[rB]
if(T == rD) {
        T = rA;
        flag = 0;
} else
        flag = 1;
MEM32[rB] = T;
rD = T;

cmov rD,rA,rB
Description:
According to the condition flag, either rA or rB is selected to be copied to the general-purpose register
rD. If flag is set, rA is selected. If flag is cleared, rB is selected.
rD[31:0] <- flag ? rA[31:0] : rB[31:0]

你可能感兴趣的:(双核互斥问题)