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.

168 lines
3.3 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. resource.h
  5. Abstract:
  6. This header holds declarations for a shared-resource synchronization object.
  7. Author:
  8. Abolade Gbadegesin (t-abolag) 11-July-1997
  9. Revision History:
  10. --*/
  11. #ifndef _NAT_RESOURCE_H_
  12. #define _NAT_RESOURCE_H_
  13. //
  14. // NAT_RESOURCE
  15. //
  16. // This structure contains the fields used for shared-exclusive synchronization.
  17. //
  18. typedef struct _NAT_RESOURCE {
  19. KSPIN_LOCK ReaderSpinLock;
  20. LONG ReaderCount;
  21. KSPIN_LOCK WriterSpinLock;
  22. KIRQL WriterIrql;
  23. } NAT_RESOURCE, *PNAT_RESOURCE;
  24. //
  25. // RESOURCE ROUTINES
  26. //
  27. #define USES_NAT_RESOURCE() \
  28. KIRQL _ReaderIrql; \
  29. KIRQL _WriterIrql
  30. //
  31. // VOID
  32. // NatInitializeResource(
  33. // PNAT_RESOURCE Resource
  34. // );
  35. //
  36. #define NatInitializeResource(Resource) { \
  37. (Resource)->ReaderCount = 0; \
  38. KeInitializeSpinLock(&(Resource)->ReaderSpinLock); \
  39. KeInitializeSpinLock(&(Resource)->WriterSpinLock); \
  40. }
  41. //
  42. // VOID
  43. // NatAcquireResourceShared(
  44. // PNAT_RESOURCE Resource
  45. // );
  46. //
  47. #define NatAcquireResourceShared(Resource) { \
  48. KeAcquireSpinLock(&(Resource)->ReaderSpinLock, &_ReaderIrql); \
  49. if (InterlockedIncrement(&(Resource)->ReaderCount) == 1) { \
  50. KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
  51. } \
  52. KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
  53. }
  54. //
  55. // VOID
  56. // NatReleaseResourceShared(
  57. // PNAT_RESOURCE Resource
  58. // );
  59. //
  60. #define NatReleaseResourceShared(Resource) { \
  61. if (InterlockedDecrement(&(Resource)->ReaderCount) == 0) { \
  62. KeReleaseSpinLockFromDpcLevel(&(Resource)->WriterSpinLock); \
  63. } \
  64. KeLowerIrql(_ReaderIrql); \
  65. }
  66. //
  67. // VOID
  68. // NatAcquireResourceExclusive(
  69. // PNAT_RESOURCE Resource
  70. // );
  71. //
  72. #define NatAcquireResourceExclusive(Resource) \
  73. KeAcquireSpinLock(&(Resource)->WriterSpinLock, &(Resource)->WriterIrql)
  74. //
  75. // VOID
  76. // NatReleaseResourceExclusive(
  77. // PNAT_RESOURCE Resource
  78. // );
  79. //
  80. #define NatReleaseResourceExclusive(Resource) \
  81. KeReleaseSpinLock(&(Resource)->WriterSpinLock, (Resource)->WriterIrql)
  82. //
  83. // VOID
  84. // NatConvertSharedToExclusive(
  85. // PNAT_RESOURCE Resource
  86. // );
  87. //
  88. #define NatConvertSharedToExclusive(Resource) { \
  89. KeAcquireSpinLockAtDpcLevel(&(Resource)->ReaderSpinLock); \
  90. if (InterlockedDecrement(&(Resource)->ReaderCount) == 0) { \
  91. KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
  92. } \
  93. else { \
  94. KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
  95. KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
  96. } \
  97. }
  98. //
  99. // VOID
  100. // NatConvertedExclusiveToShared(
  101. // PNAT_RESOURCE Resource
  102. // );
  103. //
  104. #define NatConvertedExclusiveToShared(Resource) { \
  105. KeReleaseSpinLockFromDpcLevel(&(Resource)->WriterSpinLock); \
  106. KeAcquireSpinLockAtDpcLevel(&(Resource)->ReaderSpinLock); \
  107. if (InterlockedIncrement(&(Resource)->ReaderCount) == 1) { \
  108. KeAcquireSpinLockAtDpcLevel(&(Resource)->WriterSpinLock); \
  109. } \
  110. KeReleaseSpinLockFromDpcLevel(&(Resource)->ReaderSpinLock); \
  111. }
  112. //
  113. // VOID
  114. // NatReleaseConvertedExclusive(
  115. // PNAT_RESOURCE Resource
  116. // );
  117. //
  118. #define NatReleaseConvertedExclusive(Resource) { \
  119. KeReleaseSpinLock(&(Resource)->WriterSpinLock, _ReaderIrql); \
  120. }
  121. #endif // _NAT_RESOURCE_H_