utlock.c 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
  2. /******************************************************************************
  3. *
  4. * Module Name: utlock - Reader/Writer lock interfaces
  5. *
  6. * Copyright (C) 2000 - 2018, Intel Corp.
  7. *
  8. *****************************************************************************/
  9. #include <acpi/acpi.h>
  10. #include "accommon.h"
  11. #define _COMPONENT ACPI_UTILITIES
  12. ACPI_MODULE_NAME("utlock")
  13. /*******************************************************************************
  14. *
  15. * FUNCTION: acpi_ut_create_rw_lock
  16. * acpi_ut_delete_rw_lock
  17. *
  18. * PARAMETERS: lock - Pointer to a valid RW lock
  19. *
  20. * RETURN: Status
  21. *
  22. * DESCRIPTION: Reader/writer lock creation and deletion interfaces.
  23. *
  24. ******************************************************************************/
  25. acpi_status acpi_ut_create_rw_lock(struct acpi_rw_lock *lock)
  26. {
  27. acpi_status status;
  28. lock->num_readers = 0;
  29. status = acpi_os_create_mutex(&lock->reader_mutex);
  30. if (ACPI_FAILURE(status)) {
  31. return (status);
  32. }
  33. status = acpi_os_create_mutex(&lock->writer_mutex);
  34. return (status);
  35. }
  36. void acpi_ut_delete_rw_lock(struct acpi_rw_lock *lock)
  37. {
  38. acpi_os_delete_mutex(lock->reader_mutex);
  39. acpi_os_delete_mutex(lock->writer_mutex);
  40. lock->num_readers = 0;
  41. lock->reader_mutex = NULL;
  42. lock->writer_mutex = NULL;
  43. }
  44. /*******************************************************************************
  45. *
  46. * FUNCTION: acpi_ut_acquire_read_lock
  47. * acpi_ut_release_read_lock
  48. *
  49. * PARAMETERS: lock - Pointer to a valid RW lock
  50. *
  51. * RETURN: Status
  52. *
  53. * DESCRIPTION: Reader interfaces for reader/writer locks. On acquisition,
  54. * only the first reader acquires the write mutex. On release,
  55. * only the last reader releases the write mutex. Although this
  56. * algorithm can in theory starve writers, this should not be a
  57. * problem with ACPICA since the subsystem is infrequently used
  58. * in comparison to (for example) an I/O system.
  59. *
  60. ******************************************************************************/
  61. acpi_status acpi_ut_acquire_read_lock(struct acpi_rw_lock *lock)
  62. {
  63. acpi_status status;
  64. status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
  65. if (ACPI_FAILURE(status)) {
  66. return (status);
  67. }
  68. /* Acquire the write lock only for the first reader */
  69. lock->num_readers++;
  70. if (lock->num_readers == 1) {
  71. status =
  72. acpi_os_acquire_mutex(lock->writer_mutex,
  73. ACPI_WAIT_FOREVER);
  74. }
  75. acpi_os_release_mutex(lock->reader_mutex);
  76. return (status);
  77. }
  78. acpi_status acpi_ut_release_read_lock(struct acpi_rw_lock *lock)
  79. {
  80. acpi_status status;
  81. status = acpi_os_acquire_mutex(lock->reader_mutex, ACPI_WAIT_FOREVER);
  82. if (ACPI_FAILURE(status)) {
  83. return (status);
  84. }
  85. /* Release the write lock only for the very last reader */
  86. lock->num_readers--;
  87. if (lock->num_readers == 0) {
  88. acpi_os_release_mutex(lock->writer_mutex);
  89. }
  90. acpi_os_release_mutex(lock->reader_mutex);
  91. return (status);
  92. }
  93. /*******************************************************************************
  94. *
  95. * FUNCTION: acpi_ut_acquire_write_lock
  96. * acpi_ut_release_write_lock
  97. *
  98. * PARAMETERS: lock - Pointer to a valid RW lock
  99. *
  100. * RETURN: Status
  101. *
  102. * DESCRIPTION: Writer interfaces for reader/writer locks. Simply acquire or
  103. * release the writer mutex associated with the lock. Acquisition
  104. * of the lock is fully exclusive and will block all readers and
  105. * writers until it is released.
  106. *
  107. ******************************************************************************/
  108. acpi_status acpi_ut_acquire_write_lock(struct acpi_rw_lock *lock)
  109. {
  110. acpi_status status;
  111. status = acpi_os_acquire_mutex(lock->writer_mutex, ACPI_WAIT_FOREVER);
  112. return (status);
  113. }
  114. void acpi_ut_release_write_lock(struct acpi_rw_lock *lock)
  115. {
  116. acpi_os_release_mutex(lock->writer_mutex);
  117. }