Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

292 lines
5.1 KiB

  1. /*++
  2. Copyright (c) 2000 Microsoft Corporation
  3. Module Name:
  4. fmutex.c
  5. Abstract:
  6. This module implements the code necessary to acquire and release fast
  7. mutexes.
  8. Author:
  9. David N. Cutler (davec) 23-Jun-2000
  10. Environment:
  11. Any mode.
  12. Revision History:
  13. --*/
  14. #include "exp.h"
  15. VOID
  16. ExAcquireFastMutex (
  17. IN PFAST_MUTEX FastMutex
  18. )
  19. /*++
  20. Routine Description:
  21. This function acquires ownership of a fast mutex and raises IRQL to
  22. APC Level.
  23. Arguments:
  24. FastMutex - Supplies a pointer to a fast mutex.
  25. Return Value:
  26. None.
  27. --*/
  28. {
  29. KIRQL OldIrql;
  30. //
  31. // Raise IRQL to APC_LEVEL and decrement the ownership count to determine
  32. // if the fast mutex is owned.
  33. //
  34. OldIrql = KfRaiseIrql(APC_LEVEL);
  35. if (InterlockedDecrement(&FastMutex->Count) != 0) {
  36. //
  37. // The fast mutex is owned - wait for ownership to be granted.
  38. //
  39. FastMutex->Contention += 1;
  40. KeWaitForSingleObject(&FastMutex->Event,
  41. WrExecutive,
  42. KernelMode,
  43. FALSE,
  44. NULL);
  45. }
  46. //
  47. // Grant ownership of the fast mutext to the current thread.
  48. //
  49. FastMutex->Owner = KeGetCurrentThread();
  50. FastMutex->OldIrql = OldIrql;
  51. return;
  52. }
  53. VOID
  54. ExReleaseFastMutex (
  55. IN PFAST_MUTEX FastMutex
  56. )
  57. /*++
  58. Routine Description:
  59. This function releases ownership to a fast mutex and lowers IRQL to
  60. its previous level.
  61. Arguments:
  62. FastMutex - Supplies a pointer to a fast mutex.
  63. Return Value:
  64. None.
  65. --*/
  66. {
  67. KIRQL OldIrql;
  68. //
  69. // Save the old IRQL, clear the owner thread, and increment the fast mutex
  70. // count to detemine is there are any threads waiting for ownership to be
  71. // granted.
  72. //
  73. OldIrql = (KIRQL)FastMutex->OldIrql;
  74. ASSERT(FastMutex->Owner == KeGetCurrentThread());
  75. ASSERT(KeGetCurrentIrql() == APC_LEVEL);
  76. FastMutex->Owner = NULL;
  77. if (InterlockedIncrement(&FastMutex->Count) <= 0) {
  78. //
  79. // There are one or more threads waiting for ownership of the fast
  80. // mutex.
  81. //
  82. KeSetEventBoostPriority(&FastMutex->Event, NULL);
  83. }
  84. //
  85. // Lower IRQL to its previous value.
  86. //
  87. KeLowerIrql(OldIrql);
  88. return;
  89. }
  90. BOOLEAN
  91. ExTryToAcquireFastMutex (
  92. IN PFAST_MUTEX FastMutex
  93. )
  94. /*++
  95. Routine Description:
  96. This function attempts to acquire ownership of a fast mutex, and if
  97. successful, raises IRQL to APC level.
  98. Arguments:
  99. FastMutex - Supplies a pointer to a fast mutex.
  100. Return Value:
  101. If the fast mutex was successfully acquired, then a value of TRUE
  102. is returned as the function value. Otherwise, a value of FALSE is
  103. returned.
  104. --*/
  105. {
  106. KIRQL OldIrql;
  107. //
  108. // Raise IRQL to APC_LEVEL and attempt to acquire ownership of the fast
  109. // mutex.
  110. //
  111. OldIrql = KfRaiseIrql(APC_LEVEL);
  112. if (InterlockedCompareExchange(&FastMutex->Count, 0, 1) != 1) {
  113. //
  114. // The fast mutex is owned - lower IRQL to its previous value
  115. // and return FALSE.
  116. //
  117. KeLowerIrql(OldIrql);
  118. return FALSE;
  119. } else {
  120. //
  121. // Grant ownership of the fast mutext to the current thread and
  122. // return TRUE.
  123. //
  124. FastMutex->Owner = KeGetCurrentThread();
  125. FastMutex->OldIrql = OldIrql;
  126. return TRUE;
  127. }
  128. }
  129. VOID
  130. ExAcquireFastMutexUnsafe (
  131. IN PFAST_MUTEX FastMutex
  132. )
  133. /*++
  134. Routine Description:
  135. This function acquires ownership of a fast mutex, but does not raise
  136. IRQL to APC Level.
  137. Arguments:
  138. FastMutex - Supplies a pointer to a fast mutex.
  139. Return Value:
  140. None.
  141. --*/
  142. {
  143. //
  144. // Decrement the ownership count to determine if the fast mutex is owned.
  145. //
  146. if (InterlockedDecrement(&FastMutex->Count) != 0) {
  147. //
  148. // The fast mutex is owned - wait for ownership to be granted.
  149. //
  150. FastMutex->Contention += 1;
  151. KeWaitForSingleObject(&FastMutex->Event,
  152. WrExecutive,
  153. KernelMode,
  154. FALSE,
  155. NULL);
  156. }
  157. //
  158. // Grant ownership of the fast mutext to the current thread.
  159. //
  160. FastMutex->Owner = KeGetCurrentThread();
  161. return;
  162. }
  163. VOID
  164. ExReleaseFastMutexUnsafe (
  165. IN PFAST_MUTEX FastMutex
  166. )
  167. /*++
  168. Routine Description:
  169. This function releases ownership to a fast mutex, and does not
  170. restore IRQL to its previous level.
  171. Arguments:
  172. FastMutex - Supplies a pointer to a fast mutex.
  173. Return Value:
  174. None.
  175. --*/
  176. {
  177. //
  178. // Clear the owner thread and increment the fast mutex count to detemine
  179. // is there are any threads waiting for ownership to be granted.
  180. //
  181. ASSERT(FastMutex->Owner == KeGetCurrentThread());
  182. FastMutex->Owner = NULL;
  183. if (InterlockedIncrement(&FastMutex->Count) <= 0) {
  184. //
  185. // There are one or more threads waiting for ownership of the fast
  186. // mutex.
  187. //
  188. KeSetEventBoostPriority(&FastMutex->Event, NULL);
  189. }
  190. return;
  191. }