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.

231 lines
5.3 KiB

  1. /*++
  2. Copyright (c) 1995 Microsoft Corporation
  3. Module Name:
  4. net\routing\ipx\sap\syncpool.c
  5. Abstract:
  6. This module handles dynamic allocation and assigment of
  7. syncronization objects
  8. Author:
  9. Vadim Eydelman 05-15-1995
  10. Revision History:
  11. --*/
  12. #include "sapp.h"
  13. /*++
  14. *******************************************************************
  15. I n i t i a l i z e S y n c O b j P o o l
  16. Routine Description:
  17. Initialize pool of syncronization objects
  18. Arguments:
  19. objPool - pointer to object pool structure to be initialized
  20. Return Value:
  21. None
  22. *******************************************************************
  23. --*/
  24. VOID
  25. InitializeSyncObjPool (
  26. PSYNC_OBJECT_POOL ObjPool
  27. ) {
  28. InitializeCriticalSection (&ObjPool->SOP_Lock);
  29. ObjPool->SOP_Head.Next = NULL;
  30. }
  31. /*++
  32. *******************************************************************
  33. D e l e t e S y n c O b j P o o l
  34. Routine Description:
  35. Disposes of resources associated with sync obj pool
  36. Arguments:
  37. objPool - pointer to object pool structure to be cleand up
  38. Return Value:
  39. None
  40. *******************************************************************
  41. --*/
  42. VOID
  43. DeleteSyncObjPool (
  44. PSYNC_OBJECT_POOL ObjPool
  45. ) {
  46. PSINGLE_LIST_ENTRY cur;
  47. while (ObjPool->SOP_Head.Next!=NULL) {
  48. cur = PopEntryList (&ObjPool->SOP_Head);
  49. CloseHandle (CONTAINING_RECORD (cur,
  50. SYNC_OBJECT,
  51. SO_Link)->SO_Event);
  52. GlobalFree (CONTAINING_RECORD (cur,
  53. SYNC_OBJECT,
  54. SO_Link));
  55. }
  56. DeleteCriticalSection (&ObjPool->SOP_Lock);
  57. }
  58. HANDLE
  59. GetObjectEvent (
  60. PSYNC_OBJECT_POOL ObjPool,
  61. PPROTECTED_OBJECT ProtectedObj
  62. ) {
  63. DWORD status; // Status of OS calls
  64. PSYNC_OBJECT sync;
  65. EnterCriticalSection (&ObjPool->SOP_Lock);
  66. if (ProtectedObj->PO_Sync==NULL) { // if there is no event to wait on,
  67. // get one
  68. // First see if one is available
  69. // in the stack
  70. PSINGLE_LIST_ENTRY cur = PopEntryList (&ObjPool->SOP_Head);
  71. if (cur==NULL) { // No, we'll have to create one
  72. sync = (PSYNC_OBJECT)GlobalAlloc (
  73. GMEM_FIXED,
  74. sizeof (SYNC_OBJECT));
  75. if (sync == NULL)
  76. {
  77. LeaveCriticalSection(&ObjPool->SOP_Lock);
  78. return NULL;
  79. }
  80. sync->SO_Event = CreateEvent (NULL,
  81. FALSE, // Auto reset event
  82. FALSE, // Initially nonsignaled
  83. NULL);
  84. ASSERT (sync->SO_Event!=NULL);
  85. }
  86. else
  87. sync = CONTAINING_RECORD (cur, SYNC_OBJECT, SO_Link);
  88. ProtectedObj->PO_Sync = sync;
  89. }
  90. else
  91. sync = ProtectedObj->PO_Sync;
  92. // Now as we set up the object to wait, we can leave critical
  93. // section and wait on event
  94. LeaveCriticalSection (&ObjPool->SOP_Lock);
  95. return sync->SO_Event;
  96. }
  97. BOOL
  98. AcquireProtectedObjWait (
  99. #if DBG
  100. ULONG line,
  101. #endif
  102. PSYNC_OBJECT_POOL ObjPool,
  103. PPROTECTED_OBJECT ProtectedObj
  104. ) {
  105. #ifdef LOG_SYNC_STATS
  106. ULONG startTime = GetTickCount ();
  107. #endif
  108. DWORD status; // Status of OS calls
  109. BOOLEAN result; // Result of operation
  110. HANDLE event = GetObjectEvent (ObjPool, ProtectedObj);
  111. while (TRUE) {
  112. status = WaitForSingleObject (
  113. event,
  114. 60000*(ProtectedObj->PO_UseCount+1));
  115. if (status!=WAIT_TIMEOUT)
  116. break;
  117. else {
  118. #if DBG
  119. SYSTEMTIME localTime;
  120. ULONGLONG takenTime;
  121. GetLocalTime (&localTime);
  122. SystemTimeToFileTime (&localTime, (PFILETIME)&takenTime);
  123. takenTime -= (GetTickCount ()-ProtectedObj->PO_Time)*10000i64;
  124. FileTimeToSystemTime ((PFILETIME)&takenTime, &localTime);
  125. #endif
  126. Trace (DEBUG_FAILURES
  127. #if DBG
  128. |TRACE_USE_MSEC
  129. #endif
  130. ,"Timed out on lock:%lx (cnt:%d)"
  131. #if DBG
  132. ", taken at:%02u:%02u:%02u:%03u by:%ld(%lx)"
  133. #endif
  134. #ifdef LOG_SYNC_STATS
  135. ", waited:%ld sec"
  136. #endif
  137. ").",
  138. ProtectedObj,
  139. ProtectedObj->PO_UseCount
  140. #if DBG
  141. ,localTime.wHour, localTime.wMinute, localTime.wSecond,
  142. localTime.wMilliseconds, ProtectedObj->PO_Thread,
  143. ProtectedObj->PO_Thread
  144. #endif
  145. #ifdef LOG_SYNC_STATS
  146. ,(GetTickCount ()-startTime)/1000
  147. #endif
  148. );
  149. }
  150. }
  151. ASSERTERRMSG ("Wait event failed.", status==WAIT_OBJECT_0);
  152. #if DBG
  153. ProtectedObj->PO_Line = line;
  154. ProtectedObj->PO_Thread = GetCurrentThreadId ();
  155. #endif
  156. EnterCriticalSection (&ObjPool->SOP_Lock);
  157. if ((ProtectedObj->PO_UseCount==0)
  158. && (ProtectedObj->PO_Sync!=NULL)) {
  159. PushEntryList (&ObjPool->SOP_Head, &ProtectedObj->PO_Sync->SO_Link);
  160. ProtectedObj->PO_Sync = NULL;
  161. }
  162. #ifdef LOG_SYNC_STATS
  163. ProtectedObj->PO_WaitCount += 1;
  164. ProtectedObj->PO_TotalWait += (GetTickCount () - startTime);
  165. #endif
  166. LeaveCriticalSection (&ObjPool->SOP_Lock);
  167. return TRUE;
  168. }
  169. BOOL
  170. ReleaseProtectedObjNoWait (
  171. #if DBG
  172. ULONG line,
  173. #endif
  174. PSYNC_OBJECT_POOL ObjPool,
  175. PPROTECTED_OBJECT ProtectedObj
  176. ) {
  177. if (InterlockedDecrement (&ProtectedObj->PO_UseCount)==0) {
  178. EnterCriticalSection (&ObjPool->SOP_Lock);
  179. if ((ProtectedObj->PO_UseCount==0)
  180. && (ProtectedObj->PO_Sync!=NULL)) {
  181. PushEntryList (&ObjPool->SOP_Head, &ProtectedObj->PO_Sync->SO_Link);
  182. ProtectedObj->PO_Sync = NULL;
  183. }
  184. LeaveCriticalSection (&ObjPool->SOP_Lock);
  185. }
  186. return FALSE;
  187. }
  188. #ifdef LOG_SYNC_STATS
  189. VOID
  190. DumpProtectedObjStats (
  191. PPROTECTED_OBJECT ProtectedObj
  192. ) {
  193. Trace (TRACE_USE_MASK,
  194. "Lock: %lx, accessed: %ld, waited on: %d, average wait: %i64d.",
  195. ProtectedObj,
  196. ProtectedObj->PO_AccessCount, ProtectedObj->PO_WaitCount,
  197. (ProtectedObj->PO_WaitCount>0)
  198. ? (ULONGLONG)(ProtectedObj->PO_TotalWait/ProtectedObj->PO_WaitCount)
  199. : 0i64);
  200. }
  201. #endif