debuggers.hg
changeset 18954:6a3c2b4459ad
x86: Clean up and simplify rwlock implementation.
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author | Keir Fraser <keir.fraser@citrix.com> |
---|---|
date | Sat Dec 13 15:56:16 2008 +0000 (2008-12-13) |
parents | e767f80d4bcc |
children | 045f70d1acdb |
files | xen/arch/x86/Makefile xen/arch/x86/rwlock.c xen/include/asm-x86/rwlock.h xen/include/asm-x86/spinlock.h |
line diff
1.1 --- a/xen/arch/x86/Makefile Sat Dec 13 15:28:10 2008 +0000 1.2 +++ b/xen/arch/x86/Makefile Sat Dec 13 15:56:16 2008 +0000 1.3 @@ -37,7 +37,6 @@ obj-y += nmi.o 1.4 obj-y += numa.o 1.5 obj-y += pci.o 1.6 obj-y += physdev.o 1.7 -obj-y += rwlock.o 1.8 obj-y += setup.o 1.9 obj-y += shutdown.o 1.10 obj-y += smp.o
2.1 --- a/xen/arch/x86/rwlock.c Sat Dec 13 15:28:10 2008 +0000 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,28 +0,0 @@ 2.4 -#include <asm/atomic.h> 2.5 -#include <asm/rwlock.h> 2.6 - 2.7 -#if defined(CONFIG_SMP) 2.8 -asm( 2.9 -".align 4\n" 2.10 -".globl __write_lock_failed\n" 2.11 -"__write_lock_failed:\n" 2.12 -" " LOCK "addl $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n" 2.13 -"1: rep; nop\n" 2.14 -" cmpl $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n" 2.15 -" jne 1b\n" 2.16 -" " LOCK "subl $" RW_LOCK_BIAS_STR ",(%"__OP"ax)\n" 2.17 -" jnz __write_lock_failed\n" 2.18 -" ret\n" 2.19 - 2.20 -".align 4\n" 2.21 -".globl __read_lock_failed\n" 2.22 -"__read_lock_failed:\n" 2.23 -" lock ; incl (%"__OP"ax)\n" 2.24 -"1: rep; nop\n" 2.25 -" cmpl $1,(%"__OP"ax)\n" 2.26 -" js 1b\n" 2.27 -" lock ; decl (%"__OP"ax)\n" 2.28 -" js __read_lock_failed\n" 2.29 -" ret\n" 2.30 -); 2.31 -#endif
3.1 --- a/xen/include/asm-x86/rwlock.h Sat Dec 13 15:28:10 2008 +0000 3.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 3.3 @@ -1,71 +0,0 @@ 3.4 -/* include/asm-x86/rwlock.h 3.5 - * 3.6 - * Helpers used by both rw spinlocks and rw semaphores. 3.7 - * 3.8 - * Based in part on code from semaphore.h and 3.9 - * spinlock.h Copyright 1996 Linus Torvalds. 3.10 - * 3.11 - * Copyright 1999 Red Hat, Inc. 3.12 - * 3.13 - * Written by Benjamin LaHaise. 3.14 - * 3.15 - * This program is free software; you can redistribute it and/or 3.16 - * modify it under the terms of the GNU General Public License 3.17 - * as published by the Free Software Foundation; either version 3.18 - * 2 of the License, or (at your option) any later version. 3.19 - */ 3.20 -#ifndef _ASM_X86_RWLOCK_H 3.21 -#define _ASM_X86_RWLOCK_H 3.22 - 3.23 -#define RW_LOCK_BIAS 0x01000000 3.24 -#define RW_LOCK_BIAS_STR "0x01000000" 3.25 - 3.26 -#define __build_read_lock_ptr(rw, helper) \ 3.27 - asm volatile(LOCK "subl $1,(%0)\n\t" \ 3.28 - "jns 1f\n\t" \ 3.29 - "call " helper "\n\t" \ 3.30 - "1:\n" \ 3.31 - ::"a" (rw) : "memory") 3.32 - 3.33 -#define __build_read_lock_const(rw, helper) \ 3.34 - asm volatile(LOCK "subl $1,%0\n\t" \ 3.35 - "jns 1f\n\t" \ 3.36 - "push %%"__OP"ax\n\t" \ 3.37 - "lea %0,%%"__OP"ax\n\t" \ 3.38 - "call " helper "\n\t" \ 3.39 - "pop %%"__OP"ax\n\t" \ 3.40 - "1:\n" \ 3.41 - :"=m" (*(volatile int *)rw) : : "memory") 3.42 - 3.43 -#define __build_read_lock(rw, helper) do { \ 3.44 - if (__builtin_constant_p(rw)) \ 3.45 - __build_read_lock_const(rw, helper); \ 3.46 - else \ 3.47 - __build_read_lock_ptr(rw, helper); \ 3.48 - } while (0) 3.49 - 3.50 -#define __build_write_lock_ptr(rw, helper) \ 3.51 - asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ 3.52 - "jz 1f\n\t" \ 3.53 - "call " helper "\n\t" \ 3.54 - "1:\n" \ 3.55 - ::"a" (rw) : "memory") 3.56 - 3.57 -#define __build_write_lock_const(rw, helper) \ 3.58 - asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ 3.59 - "jz 1f\n\t" \ 3.60 - "push %%"__OP"ax\n\t" \ 3.61 - "lea %0,%%"__OP"ax\n\t" \ 3.62 - "call " helper "\n\t" \ 3.63 - "pop %%"__OP"ax\n\t" \ 3.64 - "1:\n" \ 3.65 - :"=m" (*(volatile int *)rw) : : "memory") 3.66 - 3.67 -#define __build_write_lock(rw, helper) do { \ 3.68 - if (__builtin_constant_p(rw)) \ 3.69 - __build_write_lock_const(rw, helper); \ 3.70 - else \ 3.71 - __build_write_lock_ptr(rw, helper); \ 3.72 - } while (0) 3.73 - 3.74 -#endif
4.1 --- a/xen/include/asm-x86/spinlock.h Sat Dec 13 15:28:10 2008 +0000 4.2 +++ b/xen/include/asm-x86/spinlock.h Sat Dec 13 15:56:16 2008 +0000 4.3 @@ -4,7 +4,6 @@ 4.4 #include <xen/config.h> 4.5 #include <xen/lib.h> 4.6 #include <asm/atomic.h> 4.7 -#include <asm/rwlock.h> 4.8 4.9 typedef struct { 4.10 volatile s16 lock; 4.11 @@ -49,30 +48,50 @@ typedef struct { 4.12 volatile unsigned int lock; 4.13 } raw_rwlock_t; 4.14 4.15 +#define RW_LOCK_BIAS 0x01000000 4.16 #define _RAW_RW_LOCK_UNLOCKED /*(raw_rwlock_t)*/ { RW_LOCK_BIAS } 4.17 4.18 -/* 4.19 - * On x86, we implement read-write locks as a 32-bit counter 4.20 - * with the high bit (sign) being the "contended" bit. 4.21 - */ 4.22 static always_inline void _raw_read_lock(raw_rwlock_t *rw) 4.23 { 4.24 - __build_read_lock(rw, "__read_lock_failed"); 4.25 + asm volatile ( 4.26 + "1: lock; decl %0 \n" 4.27 + " jns 3f \n" 4.28 + " lock; incl %0 \n" 4.29 + "2: rep; nop \n" 4.30 + " cmpl $1,%0 \n" 4.31 + " js 2b \n" 4.32 + " jmp 1b \n" 4.33 + "3:" 4.34 + : "=m" (rw->lock) : : "memory" ); 4.35 } 4.36 4.37 static always_inline void _raw_write_lock(raw_rwlock_t *rw) 4.38 { 4.39 - __build_write_lock(rw, "__write_lock_failed"); 4.40 + asm volatile ( 4.41 + "1: lock; subl %1,%0 \n" 4.42 + " jz 3f \n" 4.43 + " lock; addl %1,%0 \n" 4.44 + "2: rep; nop \n" 4.45 + " cmpl %1,%0 \n" 4.46 + " jne 2b \n" 4.47 + " jmp 1b \n" 4.48 + "3:" 4.49 + : "=m" (rw->lock) : "i" (RW_LOCK_BIAS) : "memory" ); 4.50 } 4.51 4.52 -#define _raw_read_unlock(rw) \ 4.53 - asm volatile ( \ 4.54 - "lock ; incl %0" : \ 4.55 - "=m" ((rw)->lock) : : "memory" ) 4.56 -#define _raw_write_unlock(rw) \ 4.57 - asm volatile ( \ 4.58 - "lock ; addl $" RW_LOCK_BIAS_STR ",%0" : \ 4.59 - "=m" ((rw)->lock) : : "memory" ) 4.60 +static always_inline void _raw_read_unlock(raw_rwlock_t *rw) 4.61 +{ 4.62 + asm volatile ( 4.63 + "lock ; incl %0" 4.64 + : "=m" ((rw)->lock) : : "memory" ); 4.65 +} 4.66 + 4.67 +static always_inline void _raw_write_unlock(raw_rwlock_t *rw) 4.68 +{ 4.69 + asm volatile ( 4.70 + "lock ; addl %1,%0" 4.71 + : "=m" ((rw)->lock) : "i" (RW_LOCK_BIAS) : "memory" ); 4.72 +} 4.73 4.74 #define _raw_rw_is_locked(x) ((x)->lock < RW_LOCK_BIAS) 4.75