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.

196 lines
4.7 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\ipx\sap\syncpool.h
  5. Abstract:
  6. Header file for allocation and assigment of
  7. syncronization objects module
  8. Author:
  9. Vadim Eydelman 05-15-1995
  10. Revision History:
  11. --*/
  12. #ifndef _SAP_SYNCPOOL_
  13. #define _SAP_SYNCPOOL_
  14. // Event with link to store it in the pool
  15. typedef struct _SYNC_OBJECT {
  16. HANDLE SO_Event; // Event itself
  17. SINGLE_LIST_ENTRY SO_Link; // Link to next event in pool
  18. } SYNC_OBJECT, *PSYNC_OBJECT;
  19. // Pool of synchronization objects
  20. typedef struct _SYNC_OBJECT_POOL {
  21. CRITICAL_SECTION SOP_Lock; // Pool protection
  22. SINGLE_LIST_ENTRY SOP_Head; // Top of the stack
  23. } SYNC_OBJECT_POOL, *PSYNC_OBJECT_POOL;
  24. // Object that can protect shared resource with a help of
  25. // syncronization object from a pool
  26. typedef struct _PROTECTED_OBJECT {
  27. PSYNC_OBJECT PO_Sync; // Assigned event
  28. LONG PO_UseCount; // Number of user accessing or waiting
  29. #if DBG
  30. DWORD PO_Thread;
  31. ULONG PO_Time;
  32. ULONG PO_Line;
  33. #endif
  34. #ifdef LOG_SYNC_STATS
  35. ULONG PO_AccessCount;
  36. ULONG PO_WaitCount;
  37. ULONGLONG PO_TotalWait;
  38. #endif
  39. } PROTECTED_OBJECT, *PPROTECTED_OBJECT;
  40. VOID
  41. InitializeSyncObjPool (
  42. PSYNC_OBJECT_POOL ObjPool
  43. );
  44. VOID
  45. DeleteSyncObjPool (
  46. PSYNC_OBJECT_POOL ObjPool
  47. );
  48. // Initializes protected object
  49. // VOID
  50. // InitializeProtectedObj (
  51. // PPROTECTED_OBJECT ProtectedObj
  52. // )
  53. #ifdef LOG_SYNC_STATS
  54. #define InitializeProtectedObj(ProtectedObj) { \
  55. (ProtectedObj)->PO_Sync = NULL; \
  56. (ProtectedObj)->PO_UseCount = -1; \
  57. (ProtectedObj)->PO_AccessCount = 0; \
  58. (ProtectedObj)->PO_WaitCount = 0; \
  59. (ProtectedObj)->PO_TotalWait = 0; \
  60. }
  61. #else
  62. #define InitializeProtectedObj(ProtectedObj) { \
  63. (ProtectedObj)->PO_Sync = NULL; \
  64. (ProtectedObj)->PO_UseCount = -1; \
  65. }
  66. #endif
  67. #ifdef LOG_SYNC_STATS
  68. #define DeleteProtectedObj(ProtectedObj) \
  69. DumpProtectedObjStats (ProtectedObj);
  70. VOID
  71. DumpProtectedObjStats (
  72. PPROTECTED_OBJECT ProtectedObj
  73. );
  74. #else
  75. #define DeleteProtectedObj(ProtectedObj)
  76. #endif
  77. BOOL
  78. AcquireProtectedObjWait (
  79. #if DBG
  80. ULONG line,
  81. #endif
  82. PSYNC_OBJECT_POOL ObjPool,
  83. PPROTECTED_OBJECT ProtectedObj
  84. );
  85. BOOL
  86. ReleaseProtectedObjNoWait (
  87. #if DBG
  88. ULONG line,
  89. #endif
  90. PSYNC_OBJECT_POOL ObjPool,
  91. PPROTECTED_OBJECT ProtectedObj
  92. );
  93. HANDLE
  94. GetObjectEvent (
  95. PSYNC_OBJECT_POOL ObjPool,
  96. PPROTECTED_OBJECT ProtectedObj
  97. );
  98. #if DBG
  99. #ifdef LOG_SYNC_STATS
  100. #define AcquireProtectedObj(pool,obj,wait) ( \
  101. (InterlockedIncrement(&(obj)->PO_UseCount)==0) \
  102. ? ((obj)->PO_Line = __LINE__, \
  103. (obj)->PO_Thread = GetCurrentThreadId (), \
  104. (obj)->PO_Time = GetTickCount (), \
  105. InterlockedIncrement (&(obj)->PO_AccessCount), \
  106. TRUE) \
  107. : (wait \
  108. ? AcquireProtectedObjWait(__LINE__,pool,obj) \
  109. : ReleaseProtectedObjNoWait(__LINE__,pool,obj) \
  110. ) \
  111. )
  112. #else
  113. #define AcquireProtectedObj(pool,obj,wait) ( \
  114. (InterlockedIncrement(&(obj)->PO_UseCount)==0) \
  115. ? ((obj)->PO_Line = __LINE__, \
  116. (obj)->PO_Thread = GetCurrentThreadId (), \
  117. (obj)->PO_Time = GetTickCount (), \
  118. TRUE) \
  119. : (wait \
  120. ? AcquireProtectedObjWait(__LINE__,pool,obj) \
  121. : ReleaseProtectedObjNoWait(__LINE__,pool,obj) \
  122. ) \
  123. )
  124. #endif
  125. #define ReleaseProtectedObj(pool,obj) ( \
  126. ((((GetTickCount()-(obj)->PO_Time)<5000) \
  127. ? 0 \
  128. : Trace (DEBUG_FAILURES, \
  129. "Held lock for %ld sec in %s at %ld.\n",\
  130. (GetTickCount()-(obj)->PO_Time)/1000, \
  131. __FILE__, __LINE__)), \
  132. (InterlockedDecrement(&(obj)->PO_UseCount)<0)) \
  133. ? TRUE \
  134. : SetEvent (GetObjectEvent(pool,obj)) \
  135. )
  136. #else
  137. #define AcquireProtectedObj(pool,obj,wait) ( \
  138. (InterlockedIncrement(&(obj)->PO_UseCount)==0) \
  139. ? (TRUE) \
  140. : (wait \
  141. ? AcquireProtectedObjWait(pool,obj) \
  142. : ReleaseProtectedObjNoWait(pool,obj) \
  143. ) \
  144. )
  145. #define ReleaseProtectedObj(pool,obj) ( \
  146. (InterlockedDecrement(&(obj)->PO_UseCount)<0) \
  147. ? TRUE \
  148. : SetEvent (GetObjectEvent(pool,obj)) \
  149. )
  150. #endif
  151. // Special case for protection of doubly-linked lists
  152. typedef struct _PROTECTED_LIST {
  153. PROTECTED_OBJECT PL_PObj;
  154. LIST_ENTRY PL_Head;
  155. } PROTECTED_LIST, *PPROTECTED_LIST;
  156. #define InitializeProtectedList(ProtectedList) { \
  157. InitializeProtectedObj(&(ProtectedList)->PL_PObj); \
  158. InitializeListHead(&(ProtectedList)->PL_Head); \
  159. }
  160. #define AcquireProtectedList(ObjPool,ProtectedList,wait) \
  161. AcquireProtectedObj(ObjPool,&(ProtectedList)->PL_PObj,wait)
  162. #define ReleaseProtectedList(ObjPool,ProtectedList) \
  163. ReleaseProtectedObj(ObjPool,&(ProtectedList)->PL_PObj)
  164. #define DeleteProtectedList(ProtectedList) \
  165. DeleteProtectedObj(&(ProtectedList)->PL_PObj);
  166. #endif