1/* include/asm-i386/rwlock.h 2 * 3 * Helpers used by both rw spinlocks and rw semaphores. 4 * 5 * Based in part on code from semaphore.h and 6 * spinlock.h Copyright 1996 Linus Torvalds. 7 * 8 * Copyright 1999 Red Hat, Inc. 9 * 10 * Written by Benjamin LaHaise. 11 * 12 * This program is free software; you can redistribute it and/or 13 * modify it under the terms of the GNU General Public License 14 * as published by the Free Software Foundation; either version 15 * 2 of the License, or (at your option) any later version. 16 */ 17#ifndef _ASM_I386_RWLOCK_H 18#define _ASM_I386_RWLOCK_H 19 20#define RW_LOCK_BIAS 0x01000000 21#define RW_LOCK_BIAS_STR "0x01000000" 22 23#define __build_read_lock_ptr(rw, helper) \ 24 asm volatile(LOCK "subl $1,(%0)\n\t" \ 25 "js 2f\n" \ 26 "1:\n" \ 27 LOCK_SECTION_START("") \ 28 "2:\tcall " helper "\n\t" \ 29 "jmp 1b\n" \ 30 LOCK_SECTION_END \ 31 ::"a" (rw) : "memory") 32 33#define __build_read_lock_const(rw, helper) \ 34 asm volatile(LOCK "subl $1,%0\n\t" \ 35 "js 2f\n" \ 36 "1:\n" \ 37 LOCK_SECTION_START("") \ 38 "2:\tpushl %%eax\n\t" \ 39 "leal %0,%%eax\n\t" \ 40 "call " helper "\n\t" \ 41 "popl %%eax\n\t" \ 42 "jmp 1b\n" \ 43 LOCK_SECTION_END \ 44 :"=m" (*(volatile int *)rw) : : "memory") 45 46#define __build_read_lock(rw, helper) do { \ 47 if (__builtin_constant_p(rw)) \ 48 __build_read_lock_const(rw, helper); \ 49 else \ 50 __build_read_lock_ptr(rw, helper); \ 51 } while (0) 52 53#define __build_write_lock_ptr(rw, helper) \ 54 asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ 55 "jnz 2f\n" \ 56 "1:\n" \ 57 LOCK_SECTION_START("") \ 58 "2:\tcall " helper "\n\t" \ 59 "jmp 1b\n" \ 60 LOCK_SECTION_END \ 61 ::"a" (rw) : "memory") 62 63#define __build_write_lock_const(rw, helper) \ 64 asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \ 65 "jnz 2f\n" \ 66 "1:\n" \ 67 LOCK_SECTION_START("") \ 68 "2:\tpushl %%eax\n\t" \ 69 "leal %0,%%eax\n\t" \ 70 "call " helper "\n\t" \ 71 "popl %%eax\n\t" \ 72 "jmp 1b\n" \ 73 LOCK_SECTION_END \ 74 :"=m" (*(volatile int *)rw) : : "memory") 75 76#define __build_write_lock(rw, helper) do { \ 77 if (__builtin_constant_p(rw)) \ 78 __build_write_lock_const(rw, helper); \ 79 else \ 80 __build_write_lock_ptr(rw, helper); \ 81 } while (0) 82 83#endif 84