rwsem.c 1.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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);