|
|
/*++
Copyright (c) 2001-2001 Microsoft Corporation
Module Name:
ownerref.h
Abstract:
This module contains public declarations and definitions for tracing and debugging reference count problems - by owner. It's an enhanced version of the reftracing in reftrace.h.
Reference counting implies ownership. We associate a REF_OWNER structure with every object that holds a reference on the refcounted object and keep track of its relative refcount. Currently, this is used to keep track of which UL_CONNECTIONs have an active reference to their UL_ENDPOINT. Because UL_CONNECTIONs are recycled, we use the MonotonicId to keep track of each generation.
Author:
George V. Reilly Jan-2001
Revision History:
--*/
#ifndef _OWNERREF_H_
#define _OWNERREF_H_
#if defined(__cplusplus)
extern "C" { #endif // __cplusplus
// Owned Reference stuff
typedef struct _OWNER_REF_TRACELOG *POWNER_REF_TRACELOG; // fwd decl
typedef struct _OWNED_REFERENCE { LONGLONG RefIndex; // index of corresponding OWNER_REF_TRACE_LOG_ENTRY
// in the master OwnerRefTraceLog
LONG MonotonicId;// "generation" of this owner
USHORT Action; // what happened
} OWNED_REFERENCE;
#define OWNED_REF_NUM_ENTRIES 16
#define OWNER_REF_SIGNATURE ((ULONG) 'wOfR')
// Each owner has one of these associated with it. Note: it is not
// stored inline within the owner, as it must survive past the lifetime
// of the owner
typedef struct _REF_OWNER { ULONG Signature; // OWNER_REF_SIGNATURE
ULONG OwnerSignature; // e.g., UL_CONNECTION_SIGNATURE
PVOID pOwner; // owning object
POWNER_REF_TRACELOG pOwnerRefTraceLog; // back pointer
LIST_ENTRY ListEntry; // within list of REF_OWNERs
LONG RelativeRefCount;// held by this owner
LONG OwnedNextEntry; // index within RecentEntries
OWNED_REFERENCE RecentEntries[OWNED_REF_NUM_ENTRIES]; // circular buff
} REF_OWNER, *PREF_OWNER, **PPREF_OWNER;
// Additional data stored at the end of the TRACELOG header.
typedef struct _OWNER_REF_TRACELOG_HEADER { UL_SPIN_LOCK SpinLock; LONG OwnersCount; // length of list of REF_OWNERs
LONG MonotonicId; LIST_ENTRY ListHead; // list of REF_OWNERs
LIST_ENTRY GlobalListEntry;// entry within global list of ORTLs
} OWNER_REF_TRACELOG_HEADER, *POWNER_REF_TRACELOG_HEADER;
#define OWNER_REF_TRACELOG_SIGNATURE ((ULONG) 'gLRO')
typedef struct _OWNER_REF_TRACELOG { TRACE_LOG TraceLog; OWNER_REF_TRACELOG_HEADER OwnerHeader; } OWNER_REF_TRACELOG, *POWNER_REF_TRACELOG;
typedef struct _OWNER_REF_TRACE_LOG_ENTRY { PVOID pOwner; // an object that has an assoc'd REF_OWNER
PVOID pFileName; // source file
LONG NewRefCount; // new absolute refcount. -1 => non ref action
USHORT LineNumber; // line within source file
USHORT Action : REF_TRACE_ACTION_BITS; USHORT Pad : REF_TRACE_PROCESSOR_BITS; } OWNER_REF_TRACE_LOG_ENTRY, *POWNER_REF_TRACE_LOG_ENTRY;
//
// Manipulators.
//
VOID UlInitializeOwnerRefTraceLog( VOID);
VOID UlTerminateOwnerRefTraceLog( VOID);
POWNER_REF_TRACELOG CreateOwnerRefTraceLog( IN ULONG LogSize, IN ULONG ExtraBytesInHeader );
LONGLONG WriteOwnerRefTraceLog( IN POWNER_REF_TRACELOG pOwnerRefTraceLog, IN PVOID pOwner, IN PPREF_OWNER ppRefOwner, IN ULONG OwnerSignature, IN USHORT Action, IN LONG NewRefCount, IN LONG MonotonicId, IN LONG IncrementValue, IN PVOID pFileName, IN USHORT LineNumber );
VOID DestroyOwnerRefTraceLog( IN POWNER_REF_TRACELOG pOwnerRefTraceLog );
VOID ResetOwnerRefTraceLog( IN POWNER_REF_TRACELOG pOwnerRefTraceLog );
#if ENABLE_OWNER_REF_TRACE
// Owner RefTrace stuff
#define CREATE_OWNER_REF_TRACE_LOG( ptr, size, extra ) \
(ptr) = CreateOwnerRefTraceLog( (size), (extra) )
#define DESTROY_OWNER_REF_TRACE_LOG( ptr ) \
do \ { \ DestroyOwnerRefTraceLog( ptr ); \ (ptr) = NULL; \ } while (FALSE)
#define WRITE_OWNER_REF_TRACE_LOG( \
plog, powner, pprefowner, sig, act, newrefct, monoid, incrval, pfile, line )\ WriteOwnerRefTraceLog( \ (plog), \ (powner), \ (pprefowner), \ (sig), \ (act), \ (newrefct), \ (monoid), \ (incrval), \ (pfile), \ (line) \ )
#define SET_OWNER_REF_TRACE_LOG_MONOTONIC_ID( var, plog ) \
(var) = (((plog) == NULL) \ ? -1 : InterlockedIncrement(&(plog)->OwnerHeader.MonotonicId))
#define OWNER_REFERENCE_DEBUG_FORMAL_PARAMS \
, PVOID pOwner \ , PPREF_OWNER ppRefOwner \ , ULONG OwnerSignature \ , USHORT Action \ , LONG MonotonicId \ , PSTR pFileName \ , USHORT LineNumber
#define OWNER_REFERENCE_DEBUG_ACTUAL_PARAMS \
, act, powner, pprefowner, monoid \ , (PSTR)__FILE__,(USHORT)__LINE__
#else // !ENABLE_OWNER_REF_TRACE
#define CREATE_OWNER_REF_TRACE_LOG( ptr, size, extra ) \
(ptr) = NULL
#define DESTROY_OWNER_REF_TRACE_LOG( ptr )
#define WRITE_OWNER_REF_TRACE_LOG( \
plog, powner, pprefowner, sig, act, newrefct, monoid, incrval, pfile, line )
#define SET_OWNER_REF_TRACE_LOG_MONOTONIC_ID( var, plog )
#define OWNER_REFERENCE_DEBUG_FORMAL_PARAMS
#define OWNER_REFERENCE_DEBUG_ACTUAL_PARAMS
#endif // !ENABLE_OWNER_REF_TRACE
#if defined(__cplusplus)
} // extern "C"
#endif // __cplusplus
#endif // _OWNERREF_H_
|