rwlock.h 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /* include/asm-x86_64/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. * Copyright 2001,2002 SuSE labs
  10. *
  11. * Written by Benjamin LaHaise.
  12. *
  13. * This program is free software; you can redistribute it and/or
  14. * modify it under the terms of the GNU General Public License
  15. * as published by the Free Software Foundation; either version
  16. * 2 of the License, or (at your option) any later version.
  17. */
  18. #ifndef _ASM_X86_64_RWLOCK_H
  19. #define _ASM_X86_64_RWLOCK_H
  20. #include <linux/stringify.h>
  21. #define RW_LOCK_BIAS 0x01000000
  22. #define RW_LOCK_BIAS_STR "0x01000000"
  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. #define __build_read_lock_const(rw, helper) \
  33. asm volatile(LOCK "subl $1,%0\n\t" \
  34. "js 2f\n" \
  35. "1:\n" \
  36. LOCK_SECTION_START("") \
  37. "2:\tpushq %%rax\n\t" \
  38. "leaq %0,%%rax\n\t" \
  39. "call " helper "\n\t" \
  40. "popq %%rax\n\t" \
  41. "jmp 1b\n" \
  42. LOCK_SECTION_END \
  43. :"=m" (*((volatile int *)rw))::"memory")
  44. #define __build_read_lock(rw, helper) do { \
  45. if (__builtin_constant_p(rw)) \
  46. __build_read_lock_const(rw, helper); \
  47. else \
  48. __build_read_lock_ptr(rw, helper); \
  49. } while (0)
  50. #define __build_write_lock_ptr(rw, helper) \
  51. asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
  52. "jnz 2f\n" \
  53. "1:\n" \
  54. LOCK_SECTION_START("") \
  55. "2:\tcall " helper "\n\t" \
  56. "jmp 1b\n" \
  57. LOCK_SECTION_END \
  58. ::"a" (rw) : "memory")
  59. #define __build_write_lock_const(rw, helper) \
  60. asm volatile(LOCK "subl $" RW_LOCK_BIAS_STR ",(%0)\n\t" \
  61. "jnz 2f\n" \
  62. "1:\n" \
  63. LOCK_SECTION_START("") \
  64. "2:\tpushq %%rax\n\t" \
  65. "leaq %0,%%rax\n\t" \
  66. "call " helper "\n\t" \
  67. "popq %%rax\n\t" \
  68. "jmp 1b\n" \
  69. LOCK_SECTION_END \
  70. :"=m" (*((volatile long *)rw))::"memory")
  71. #define __build_write_lock(rw, helper) do { \
  72. if (__builtin_constant_p(rw)) \
  73. __build_write_lock_const(rw, helper); \
  74. else \
  75. __build_write_lock_ptr(rw, helper); \
  76. } while (0)
  77. #endif