On Mon, Sep 18, 2000 at 09:37:43PM -0400, John Wehle wrote: > It's perhaps not optimal, however I'm not sure that it's wrong. In It's not "wrong" in the sense that something breaks but it's definitely suboptimal. There's no reason to reload a value that can't change because it's embedded into the opcodes of the asm and set a static linking time. > any case if you can supply a small standalone test case (i.e. preprocessed > source code) I'll take a quick look at things. I take it that you haven't > tried the current gcc sources? The first testcase is the current spinlock implementation, the second testcase adds the "memory" clobber and it generates the _spurious_ reload of `p'. You should be able to compile with `gcc -O2 -S p-*.i`. Andrea
# 1 "p.c" # 1 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 1 # 1 "/usr/include/asm/spinlock.h" 1 3 # 134 "/usr/include/asm/spinlock.h" 3 typedef struct { volatile unsigned int lock; } spinlock_t; typedef struct { unsigned long a[100]; } __dummy_lock_t; # 169 "/usr/include/asm/spinlock.h" 3 typedef struct { volatile unsigned int lock; unsigned long previous; } rwlock_t; # 231 "/usr/include/asm/spinlock.h" 3 # 249 "/usr/include/asm/spinlock.h" 3 # 3 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 2 # 1 "p.c" 2 int * p; spinlock_t lock = (spinlock_t) { 0 } ; void dummy(int x , int y) {} main() { int a, b; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; a = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; b = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) )) ; dummy(a,b); }
# 1 "p.c" # 1 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 1 # 1 "/usr/include/asm/spinlock.h" 1 3 # 134 "/usr/include/asm/spinlock.h" 3 typedef struct { volatile unsigned int lock; } spinlock_t; typedef struct { unsigned long a[100]; } __dummy_lock_t; # 169 "/usr/include/asm/spinlock.h" 3 typedef struct { volatile unsigned int lock; unsigned long previous; } rwlock_t; # 231 "/usr/include/asm/spinlock.h" 3 # 249 "/usr/include/asm/spinlock.h" 3 # 3 "/home/andrea/kernel/devel/2.2.18pre9aa1/include/linux/spinlock.h" 2 # 1 "p.c" 2 int * p; spinlock_t lock = (spinlock_t) { 0 } ; void dummy(int x , int y) {} main() { int a, b; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; a = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; __asm__ __volatile__( "\n1:\t" "lock ; btsl $0,%0\n\t" "jc 2f\n" ".section .text.lock,\"ax\"\n" "2:\t" "testb $1,%0\n\t" "jne 2b\n\t" "jmp 1b\n" ".previous" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; b = *p; __asm__ __volatile__( "lock ; btrl $0,%0" :"=m" ((*(__dummy_lock_t *)( &lock )) ) : : "memory") ; dummy(a,b); }