rwsem.c 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* kernel/rwsem.c: R/W semaphores, public implementation
  2. *
  3. * Written by David Howells (dhowells@redhat.com).
  4. * Derived from asm-i386/semaphore.h
  5. */
  6. #include <linux/types.h>
  7. #include <linux/kernel.h>
  8. #include <linux/module.h>
  9. #include <linux/rwsem.h>
  10. #include <asm/system.h>
  11. #include <asm/atomic.h>
  12. /*
  13. * lock for reading
  14. */
  15. void down_read(struct rw_semaphore *sem)
  16. {
  17. might_sleep();
  18. rwsem_acquire_read(&sem->dep_map, 0, 0, _RET_IP_);
  19. __down_read(sem);
  20. }
  21. EXPORT_SYMBOL(down_read);
  22. /*
  23. * trylock for reading -- returns 1 if successful, 0 if contention
  24. */
  25. int down_read_trylock(struct rw_semaphore *sem)
  26. {
  27. int ret = __down_read_trylock(sem);
  28. if (ret == 1)
  29. rwsem_acquire_read(&sem->dep_map, 0, 1, _RET_IP_);
  30. return ret;
  31. }
  32. EXPORT_SYMBOL(down_read_trylock);
  33. /*
  34. * lock for writing
  35. */
  36. void down_write(struct rw_semaphore *sem)
  37. {
  38. might_sleep();
  39. rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
  40. __down_write(sem);
  41. }
  42. EXPORT_SYMBOL(down_write);
  43. /*
  44. * trylock for writing -- returns 1 if successful, 0 if contention
  45. */
  46. int down_write_trylock(struct rw_semaphore *sem)
  47. {
  48. int ret = __down_write_trylock(sem);
  49. if (ret == 1)
  50. rwsem_acquire(&sem->dep_map, 0, 0, _RET_IP_);
  51. return ret;
  52. }
  53. EXPORT_SYMBOL(down_write_trylock);
  54. /*
  55. * release a read lock
  56. */
  57. void up_read(struct rw_semaphore *sem)
  58. {
  59. rwsem_release(&sem->dep_map, 1, _RET_IP_);
  60. __up_read(sem);
  61. }
  62. EXPORT_SYMBOL(up_read);
  63. /*
  64. * release a write lock
  65. */
  66. void up_write(struct rw_semaphore *sem)
  67. {
  68. rwsem_release(&sem->dep_map, 1, _RET_IP_);
  69. __up_write(sem);
  70. }
  71. EXPORT_SYMBOL(up_write);
  72. /*
  73. * downgrade write lock to read lock
  74. */
  75. void downgrade_write(struct rw_semaphore *sem)
  76. {
  77. /*
  78. * lockdep: a downgraded write will live on as a write
  79. * dependency.
  80. */
  81. __downgrade_write(sem);
  82. }
  83. EXPORT_SYMBOL(downgrade_write);
  84. #ifdef CONFIG_DEBUG_LOCK_ALLOC
  85. void down_read_nested(struct rw_semaphore *sem, int subclass)
  86. {
  87. might_sleep();
  88. rwsem_acquire_read(&sem->dep_map, subclass, 0, _RET_IP_);
  89. __down_read(sem);
  90. }
  91. EXPORT_SYMBOL(down_read_nested);
  92. void down_read_non_owner(struct rw_semaphore *sem)
  93. {
  94. might_sleep();
  95. __down_read(sem);
  96. }
  97. EXPORT_SYMBOL(down_read_non_owner);
  98. void down_write_nested(struct rw_semaphore *sem, int subclass)
  99. {
  100. might_sleep();
  101. rwsem_acquire(&sem->dep_map, subclass, 0, _RET_IP_);
  102. __down_write_nested(sem, subclass);
  103. }
  104. EXPORT_SYMBOL(down_write_nested);
  105. void up_read_non_owner(struct rw_semaphore *sem)
  106. {
  107. __up_read(sem);
  108. }
  109. EXPORT_SYMBOL(up_read_non_owner);
  110. #endif