windows-nt/Source/XPSP1/NT/net/homenet/bridge/sys/brdgcach.h

174 lines
3.4 KiB
C
Raw Normal View History

2020-09-26 03:20:57 -05:00
/*++
Copyright(c) 1999-2000 Microsoft Corporation
Module Name:
brdgcach.h
Abstract:
Ethernet MAC level bridge.
Cache implementation header
Author:
Mark Aiken
Environment:
Kernel mode driver
Revision History:
December 2000 - Original version
--*/
// ===========================================================================
//
// DECLARATIONS
//
// ===========================================================================
typedef struct _CACHE_ENTRY
{
UINT32 key;
UINT32 data;
UINT64 hits;
UINT64 misses;
} CACHE_ENTRY, *PCACHE_ENTRY;
typedef struct _CACHE
{
// lock protects all cache fields
NDIS_SPIN_LOCK lock;
// stats
UINT64 hits;
UINT64 misses;
// 2^shiftFactor is the number of entries
USHORT shiftFactor;
// Pointer to the array of entries
PCACHE_ENTRY pEntries;
} CACHE, *PCACHE;
//
// Determines the cache slot for key k in cache c. The slot is determined
// as the bottom bits of k.
//
#define CACHE_INDEX(c, k) (k & ((1 << c->shiftFactor) - 1))
// ===========================================================================
//
// INLINES
//
// ===========================================================================
__inline
VOID
BrdgClearCache(
IN PCACHE pCache
)
{
NdisAcquireSpinLock( &pCache->lock );
memset( pCache->pEntries, 0, sizeof(CACHE_ENTRY) * (1 << pCache->shiftFactor) );
NdisReleaseSpinLock( &pCache->lock );
}
__inline
NDIS_STATUS
BrdgInitializeCache(
IN PCACHE pCache,
IN USHORT shiftFactor
)
{
ULONG numEntries = 1 << shiftFactor;
NDIS_STATUS status;
pCache->shiftFactor = shiftFactor;
NdisAllocateSpinLock( &pCache->lock );
status = NdisAllocateMemoryWithTag( &pCache->pEntries, sizeof(CACHE_ENTRY) * numEntries, 'gdrB' );
pCache->hits = 0L;
pCache->misses = 0L;
if( status != NDIS_STATUS_SUCCESS )
{
return status;
}
// Zero out the array of entries
memset( pCache->pEntries, 0, sizeof(CACHE_ENTRY) * (1 << pCache->shiftFactor) );
return NDIS_STATUS_SUCCESS;
}
__inline
VOID
BrdgFreeCache(
IN PCACHE pCache
)
{
NdisFreeMemory( pCache->pEntries, sizeof(CACHE_ENTRY) * (1 << pCache->shiftFactor), 0 );
}
__inline
UINT32
BrdgProbeCache(
IN PCACHE pCache,
IN UINT32 key
)
{
UINT32 index = CACHE_INDEX(pCache, key);
PCACHE_ENTRY pEntry = &pCache->pEntries[index];
UINT32 data = 0L;
NdisAcquireSpinLock( &pCache->lock );
if( pEntry->key == key )
{
data = pEntry->data;
pEntry->hits++;
pCache->hits++;
}
else
{
pEntry->misses++;
pCache->misses++;
}
NdisReleaseSpinLock( &pCache->lock );
return data;
}
__inline
BOOLEAN
BrdgUpdateCache(
IN PCACHE pCache,
IN UINT32 key,
IN UINT32 data
)
{
UINT32 index = CACHE_INDEX(pCache, key);
PCACHE_ENTRY pEntry = &pCache->pEntries[index];
BOOLEAN bUpdated = FALSE;
NdisAcquireSpinLock( &pCache->lock );
if( pEntry->key != key &&
(pEntry->hits < pEntry->misses) )
{
pEntry->key = key;
pEntry->data = data;
pEntry->hits = 0L;
pEntry->misses = 0L;
bUpdated = TRUE;
}
NdisReleaseSpinLock( &pCache->lock );
return bUpdated;
}