2

I'm trying to implement a spinlock in my code but the spinlock that I implemented based on Wikipedia results in extremely slow performance.

int lockValue = 0;

void lock() {
    __asm__("loop: \n\t"
            "movl $1, %eax \n\t"
            "xchg %eax, lockValue \n\t"
            "test %eax, %eax \n\t"
            "jnz loop");
}

Is there any way of improving this to make it faster?

Thanks.

Jigglypuff
  • 1,363
  • 6
  • 21
  • 34
  • 1
    I think you're trying to optimize the wrong thing. If you have so much lock contention, you need to rethink your algorithm, the code outside of `lock()`, to see how you can reduce said contention. Or you may want to choose to spin on the lock just a few times and then back off and do something useful (or sleep). – Alexey Frunze Aug 12 '12 at 15:07

2 Answers2

5

How about something like this (I understand this is the KeAcquireSpinLock implementation). My at&t assembly is weak unfortunately.

spin_lock:
    rep; nop
    test lockValue, 1
    jnz spin_lock
    lock bts lockValue
    jc spin_lock
cnicutar
  • 164,886
  • 23
  • 329
  • 361
  • 2
    See also: [What does "rep;nop;" mean in x86 assembly?](http://stackoverflow.com/questions/7086220/what-does-rep-nop-mean-in-x86-assembly) and [How does x86 pause instruction work in spinlock and can it be used in other scenarios?](http://stackoverflow.com/questions/4725676/how-does-x86-pause-instruction-work-in-spinlock-and-can-it-be-used-in-other-sc) – nhahtdh Aug 12 '12 at 15:10
  • 2
    See also: [What does the “lock” instruction mean in x86 assembly?](http://stackoverflow.com/questions/8891067/what-does-the-lock-instruction-mean-in-x86-assembly) and [x86 LOCK on multi-core CPU](http://stackoverflow.com/questions/3339141/x86-lock-question-on-multi-core-cpus/3339380#3339380) and [Atomic operation on single core/multi-core](http://wiki.osdev.org/Atomic_operation) – nhahtdh Aug 12 '12 at 15:20
  • @nhahtdh Hey you're providing great links. Keep up the good stuff :-) – cnicutar Aug 12 '12 at 15:20
4
  "movl    $1,%%edx     \n\t"    // edx = 1;
  ".set    lockloop,.   \n\t"    // symbol lockloop set to pc
  "xorl    %%eax,%%eax  \n\t"    // eax = 0;
  "lock cmpxchgl %%edx,(%%ebx)\n\t" // if (*mu_ptr == eax) *mu_ptr = edx;
                                 //    else { eax = *mu_ptr;
  "jnz     lockloop     \n\t"    //           goto lockloop; }
Dave
  • 41
  • 1