Page 1 of 1

Inline assembly (spinlock using xchg instruction)

Posted: Thu May 28, 2009 1:08 am
by pChan
Hi,

I have some trouble understanding the following code. It is used in spinlock implementation.

Code: Select all

struct spinlock *lock; //spinlock uses the "locked" variable in the struct for locking

99  while(xchg(&lock->locked, 1) == 1) ; //xchg is a wrapper function having inline asm
.
.
.
      static inline uint
100 xchg(volatile uint *addr, uint newval)
101 {   
102   uint result;
103   
104   // The + in "+m" denotes a read-modify-write operand.
105   asm volatile("lock; xchgl %0, %1" :
106                "+m" (*addr), "=a" (result) :
107                "1" (newval) :
108                "cc");
109   return result;
110 } 

Even after going through the various references for gcc inline assembly I still can't wrap my head around the xchg function. This is the rough picture I have of the above code.

The value 1 is passed to xchg so newval=1 . The "1" in the line 107 means the first (after zeroth) output operand so it refers to "=a" which is the eax register. so eax now becomes equal to newval .

The xchg now exchanges dwords between memory "locked" and eax register (having value 1). The new value in the eax register (after xchg swapping) is now transferred to the c expression "result" (and eax register).

The result is then returned to the user. Did I get the sequence right?

If so initially when spinlock is unlocked (lock->locked=0) then the while loop(in line 99) will run twice (as the first time zero would be returned to the user) to get the lock. Am I right?

Sorry for the winding post. Thanks in advance.

Re: Inline assembly (spinlock using xchg instruction)

Posted: Thu May 28, 2009 1:28 am
by xenos
The while loop is executed, while the function returns 1. Since it returns 0 at first, the loop is indeed never executed, since the while condition is not true.

Re: Inline assembly (spinlock using xchg instruction)

Posted: Thu May 28, 2009 2:20 am
by pChan
Oh my bad. Yes the while loop will not be executed (if lock->locked=0) otherwise it will keep looping. I had "assumed" the while result loop which had confused me into thinking that I was getting the sequence in the inline asm wrong.

Thanks for the clarification.