This is the first question for me here. I'm implementing spinlock using cmpxchg instruction. There is no lock change after cmpxchg instruction. In that, there is something wrong with my assembly code.
This is my thread function code.
void *t_function(void *data){
volatile int* t_cnt;
t_cnt = (int *)data;
/* Lock */
while(CompareAndSet(&lock, 0, 1));
/* Critical Section */
for(; i<TEST_NUM; i++){
(*t_cnt)++;
}
/* Unlock */
lock = 0;
}
This is my CompareAndSet function with inline assembly code.
unsigned int CompareAndSet(unsigned in *target, unsigned int expected, unsigned int update){
unsigned int rv = *target;
printf("lock : %d, expected : %d, update : %d\n", *target, expected, update);
__asm__ __volatile__(
"cmpxchg %0, %2\n\t"
:"+r" (*target), "+a" (expected)
:"r" (update)
);
printf("lock_after : %d\n", *target);
return rv;
}
When I compile and run this, I got this. It seems that lock doesn't change.
... lock : 0, expected : 0, update : 1 lock_after : 0 Thread [19] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [20] created. lock : 0, expected : 0, update : 1 lock_after : 0 lock : 0, expected : 0, update : 1 lock_after : 0 Thread [21] created. Thread [22] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [23] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [24] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [25] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [26] created. Thread [27] created. Thread [28] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [29] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [30] created. lock : 0, expected : 0, update : 1 lock_after : 0 Thread [31] created. lock : 0, expected : 0, update : 1 lock_after : 0 lock : 0, expected : 0, update : 1 lock_after : 0 lock : 0, expected : 0, update : 1 lock_after : 0 cnt : 9478079
#define THREAD_NUM 32
#define TEST_NUM 10000000
Does anyone have idea with my assembly code?
From 'AMD64 Architecture Programmer’s Manual Volume 3: General Purpose and System Instructions PDF', I got how to use cmpxchg instruction. It says,
Mnemonic :
CMPXCHG reg/mem32, reg32
Opcode : OF B1 /r
Description : Compare EAX register with a 32-bit register or memory location. If equal, copy the second operand to the first operand. Otherwise, copy the first operand to EAX.