|
|
/*++
Copyright (c) 1995 Microsoft Corporation
Module Name:
net\routing\ipx\sap\syncpool.h
Abstract:
Header file for allocation and assigment of syncronization objects module Author:
Vadim Eydelman 05-15-1995
Revision History:
--*/ #ifndef _SAP_SYNCPOOL_
#define _SAP_SYNCPOOL_
// Event with link to store it in the pool
typedef struct _SYNC_OBJECT { HANDLE SO_Event; // Event itself
SINGLE_LIST_ENTRY SO_Link; // Link to next event in pool
} SYNC_OBJECT, *PSYNC_OBJECT;
// Pool of synchronization objects
typedef struct _SYNC_OBJECT_POOL { CRITICAL_SECTION SOP_Lock; // Pool protection
SINGLE_LIST_ENTRY SOP_Head; // Top of the stack
} SYNC_OBJECT_POOL, *PSYNC_OBJECT_POOL;
// Object that can protect shared resource with a help of
// syncronization object from a pool
typedef struct _PROTECTED_OBJECT { PSYNC_OBJECT PO_Sync; // Assigned event
LONG PO_UseCount; // Number of user accessing or waiting
#if DBG
DWORD PO_Thread; ULONG PO_Time; ULONG PO_Line; #endif
#ifdef LOG_SYNC_STATS
ULONG PO_AccessCount; ULONG PO_WaitCount; ULONGLONG PO_TotalWait; #endif
} PROTECTED_OBJECT, *PPROTECTED_OBJECT;
VOID InitializeSyncObjPool ( PSYNC_OBJECT_POOL ObjPool );
VOID DeleteSyncObjPool ( PSYNC_OBJECT_POOL ObjPool );
// Initializes protected object
// VOID
// InitializeProtectedObj (
// PPROTECTED_OBJECT ProtectedObj
// )
#ifdef LOG_SYNC_STATS
#define InitializeProtectedObj(ProtectedObj) { \
(ProtectedObj)->PO_Sync = NULL; \ (ProtectedObj)->PO_UseCount = -1; \ (ProtectedObj)->PO_AccessCount = 0; \ (ProtectedObj)->PO_WaitCount = 0; \ (ProtectedObj)->PO_TotalWait = 0; \ } #else
#define InitializeProtectedObj(ProtectedObj) { \
(ProtectedObj)->PO_Sync = NULL; \ (ProtectedObj)->PO_UseCount = -1; \ } #endif
#ifdef LOG_SYNC_STATS
#define DeleteProtectedObj(ProtectedObj) \
DumpProtectedObjStats (ProtectedObj); VOID DumpProtectedObjStats ( PPROTECTED_OBJECT ProtectedObj ); #else
#define DeleteProtectedObj(ProtectedObj)
#endif
BOOL AcquireProtectedObjWait ( #if DBG
ULONG line, #endif
PSYNC_OBJECT_POOL ObjPool, PPROTECTED_OBJECT ProtectedObj );
BOOL ReleaseProtectedObjNoWait ( #if DBG
ULONG line, #endif
PSYNC_OBJECT_POOL ObjPool, PPROTECTED_OBJECT ProtectedObj );
HANDLE GetObjectEvent ( PSYNC_OBJECT_POOL ObjPool, PPROTECTED_OBJECT ProtectedObj );
#if DBG
#ifdef LOG_SYNC_STATS
#define AcquireProtectedObj(pool,obj,wait) ( \
(InterlockedIncrement(&(obj)->PO_UseCount)==0) \ ? ((obj)->PO_Line = __LINE__, \ (obj)->PO_Thread = GetCurrentThreadId (), \ (obj)->PO_Time = GetTickCount (), \ InterlockedIncrement (&(obj)->PO_AccessCount), \ TRUE) \ : (wait \ ? AcquireProtectedObjWait(__LINE__,pool,obj) \ : ReleaseProtectedObjNoWait(__LINE__,pool,obj) \ ) \ ) #else
#define AcquireProtectedObj(pool,obj,wait) ( \
(InterlockedIncrement(&(obj)->PO_UseCount)==0) \ ? ((obj)->PO_Line = __LINE__, \ (obj)->PO_Thread = GetCurrentThreadId (), \ (obj)->PO_Time = GetTickCount (), \ TRUE) \ : (wait \ ? AcquireProtectedObjWait(__LINE__,pool,obj) \ : ReleaseProtectedObjNoWait(__LINE__,pool,obj) \ ) \ ) #endif
#define ReleaseProtectedObj(pool,obj) ( \
((((GetTickCount()-(obj)->PO_Time)<5000) \ ? 0 \ : Trace (DEBUG_FAILURES, \ "Held lock for %ld sec in %s at %ld.\n",\ (GetTickCount()-(obj)->PO_Time)/1000, \ __FILE__, __LINE__)), \ (InterlockedDecrement(&(obj)->PO_UseCount)<0)) \ ? TRUE \ : SetEvent (GetObjectEvent(pool,obj)) \ ) #else
#define AcquireProtectedObj(pool,obj,wait) ( \
(InterlockedIncrement(&(obj)->PO_UseCount)==0) \ ? (TRUE) \ : (wait \ ? AcquireProtectedObjWait(pool,obj) \ : ReleaseProtectedObjNoWait(pool,obj) \ ) \ ) #define ReleaseProtectedObj(pool,obj) ( \
(InterlockedDecrement(&(obj)->PO_UseCount)<0) \ ? TRUE \ : SetEvent (GetObjectEvent(pool,obj)) \ ) #endif
// Special case for protection of doubly-linked lists
typedef struct _PROTECTED_LIST { PROTECTED_OBJECT PL_PObj; LIST_ENTRY PL_Head; } PROTECTED_LIST, *PPROTECTED_LIST;
#define InitializeProtectedList(ProtectedList) { \
InitializeProtectedObj(&(ProtectedList)->PL_PObj); \ InitializeListHead(&(ProtectedList)->PL_Head); \ }
#define AcquireProtectedList(ObjPool,ProtectedList,wait) \
AcquireProtectedObj(ObjPool,&(ProtectedList)->PL_PObj,wait)
#define ReleaseProtectedList(ObjPool,ProtectedList) \
ReleaseProtectedObj(ObjPool,&(ProtectedList)->PL_PObj)
#define DeleteProtectedList(ProtectedList) \
DeleteProtectedObj(&(ProtectedList)->PL_PObj);
#endif
|