From: Peter V. E. <pva...@de...> - 2005-03-14 15:12:07
|
Hello, While investigating why the lazy memory allocation stuff fails on me when using :sb-thread even before I start to allocate I noticed that get_spinlock gets compiled to (gcc version 3.3.5 (Debian 1:3.3.5-11) without the -O3 option): Dump of assembler code for function get_spinlock: 0x08060ebf <get_spinlock+0>: push %ebp 0x08060ec0 <get_spinlock+1>: mov %esp,%ebp 0x08060ec2 <get_spinlock+3>: sub $0x18,%esp 0x08060ec5 <get_spinlock+6>: movl $0x0,0xfffffffc(%ebp) 0x08060ecc <get_spinlock+13>: mov 0x8(%ebp),%eax 0x08060ecf <get_spinlock+16>: mov (%eax),%eax 0x08060ed1 <get_spinlock+18>: cmp 0xc(%ebp),%eax 0x08060ed4 <get_spinlock+21>: jne 0x8060ef0 <get_spinlock+49> 0x08060ed6 <get_spinlock+23>: mov 0xc(%ebp),%eax 0x08060ed9 <get_spinlock+26>: mov %eax,0x8(%esp) 0x08060edd <get_spinlock+30>: mov 0x8(%ebp),%eax 0x08060ee0 <get_spinlock+33>: mov %eax,0x4(%esp) 0x08060ee4 <get_spinlock+37>: movl $0x80653a0,(%esp) 0x08060eeb <get_spinlock+44>: call 0x8051ccb <lose> 0x08060ef0 <get_spinlock+49>: nop 0x08060ef1 <get_spinlock+50>: mov 0xc(%ebp),%edx 0x08060ef4 <get_spinlock+53>: mov 0x8(%ebp),%eax 0x08060ef7 <get_spinlock+56>: xor %eax,%eax 0x08060ef9 <get_spinlock+58>: lock cmpxchg %edx,(%eax) 0x08060efd <get_spinlock+62>: mov %eax,0xfffffffc(%ebp) 0x08060f00 <get_spinlock+65>: cmpl $0x0,0xfffffffc(%ebp) 0x08060f04 <get_spinlock+69>: jne 0x8060ef1 <get_spinlock+50> 0x08060f06 <get_spinlock+71>: leave 0x08060f07 <get_spinlock+72>: ret End of assembler dump. And when I enter the function and interrupt it at 0x08060ef7 I see: (gdb) print word $21 = (volatile lispobj *) 0x80674a8 (gdb) print &free_pages_lock $22 = (lispobj *) 0x80674a8 (gdb) print /x *((unsigned int *)($ebp + 0xc)) $28 = 0x827bb0c (gdb) print /x *((unsigned int *)($ebp + 0x8)) $29 = 0x80674a8 So as far as I can see it is using the wrong lock location (!). I changed the get_spinlock function to look like the assembler used in the Linux kernel (file linux-2.6.9/arch/i386/lib/dec_and_lock.c): --- ../sbcl/src/runtime/x86-arch.h 2004-09-10 17:36:18.000000000 +0200 +++ src/runtime/x86-arch.h 2005-03-14 14:16:15.000000000 +0100 @@ -31,11 +31,9 @@ if(*word==value) lose("recursive get_spinlock: 0x%x,%d\n",word,value); do { - asm ("xor %0,%0\n\ - lock cmpxchg %1,%2" - : "=a" (eax) - : "r" (value), "m" (*word) - : "memory", "cc"); + asm ("lock; cmpxchg %1,%2" + : "=a" (value) + : "r" (value), "m" (*word), "0" (*word)); } while(eax!=0); } This seems to work, but don't ask me why :-). (I only have a uniprocessor machine to test this with) Groetjes, Peter |