[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [PATCH 2/5] Add a new XENBUS_CACHE_MASK absraction
From: Paul Durrant <pdurrant@xxxxxxxxxx> This abstracts away the current array along with the size of the mask. This slightly shortens the slab pre-amble, potentially allowing more objects per slab. The __CacheMaskScan() is also dropped in favour of a simple loop implemented directly in CacheGetObjectFromSlab(). This is done to simplify subsequent patches. Signed-off-by: Paul Durrant <pdurrant@xxxxxxxxxx> --- src/xenbus/cache.c | 175 +++++++++++++++++++++++++-------------------- 1 file changed, 97 insertions(+), 78 deletions(-) diff --git a/src/xenbus/cache.c b/src/xenbus/cache.c index 3813e414de58..591a6fca550d 100644 --- a/src/xenbus/cache.c +++ b/src/xenbus/cache.c @@ -52,20 +52,25 @@ typedef struct _XENBUS_CACHE_MAGAZINE { PVOID Slot[XENBUS_CACHE_MAGAZINE_SLOTS]; } XENBUS_CACHE_MAGAZINE, *PXENBUS_CACHE_MAGAZINE; - #define XENBUS_CACHE_SLAB_MAGIC 'BALS' +typedef struct _XENBUS_CACHE_MASK { + ULONG Size; + ULONG Mask[1]; +} XENBUS_CACHE_MASK, *PXENBUS_CACHE_MASK; + +#define BITS_PER_ULONG (sizeof (ULONG) * 8) + typedef struct _XENBUS_CACHE_SLAB { - ULONG Magic; - PXENBUS_CACHE Cache; - LIST_ENTRY ListEntry; - USHORT MaximumOccupancy; - USHORT CurrentOccupancy; - ULONG *Mask; - UCHAR Buffer[1]; + ULONG Magic; + PXENBUS_CACHE Cache; + LIST_ENTRY ListEntry; + USHORT MaximumOccupancy; + USHORT CurrentOccupancy; + PXENBUS_CACHE_MASK Mask; + UCHAR Buffer[1]; } XENBUS_CACHE_SLAB, *PXENBUS_CACHE_SLAB; -#define BITS_PER_ULONG (sizeof (ULONG) * 8) #define MAXNAMELEN 128 struct _XENBUS_CACHE { @@ -195,6 +200,79 @@ CachePutObjectToMagazine( return STATUS_UNSUCCESSFUL; } +static PXENBUS_CACHE_MASK +CacheMaskCreate( + IN ULONG Size + ) +{ + ULONG NumberOfBytes; + PXENBUS_CACHE_MASK Mask; + + NumberOfBytes = FIELD_OFFSET(XENBUS_CACHE_MASK, Mask) + + (P2ROUNDUP(ULONG, Size, BITS_PER_ULONG) / 8); + + Mask = __CacheAllocate(NumberOfBytes); + if (Mask == NULL) + goto fail1; + + Mask->Size = Size; + + return Mask; + +fail1: + return NULL; +} + +static VOID +CacheMaskDestroy( + IN PXENBUS_CACHE_MASK Mask + ) +{ + __CacheFree(Mask); +} + +static FORCEINLINE VOID +__CacheMaskSet( + IN PXENBUS_CACHE_MASK Mask, + IN ULONG Bit + ) +{ + ULONG Index = Bit / BITS_PER_ULONG; + ULONG Value = 1u << (Bit % BITS_PER_ULONG); + + ASSERT3U(Bit, <, Mask->Size); + + Mask->Mask[Index] |= Value; +} + +static FORCEINLINE BOOLEAN +__CacheMaskTest( + IN PXENBUS_CACHE_MASK Mask, + IN ULONG Bit + ) +{ + ULONG Index = Bit / BITS_PER_ULONG; + ULONG Value = 1u << (Bit % BITS_PER_ULONG); + + ASSERT3U(Bit, <, Mask->Size); + + return (Mask->Mask[Index] & Value) ? TRUE : FALSE; +} + +static FORCEINLINE VOID +__CacheMaskClear( + IN PXENBUS_CACHE_MASK Mask, + IN ULONG Bit + ) +{ + ULONG Index = Bit / BITS_PER_ULONG; + ULONG Value = 1u << (Bit % BITS_PER_ULONG); + + ASSERT3U(Bit, <, Mask->Size); + + Mask->Mask[Index] &= ~Value; +} + static VOID CacheInsertSlab( IN PXENBUS_CACHE Cache, @@ -294,7 +372,6 @@ CacheCreateSlab( PXENBUS_CACHE_SLAB Slab; ULONG NumberOfBytes; ULONG Count; - ULONG Size; LONG Index; LONG SlabCount; NTSTATUS status; @@ -324,10 +401,7 @@ CacheCreateSlab( Slab->Cache = Cache; Slab->MaximumOccupancy = (USHORT)Count; - Size = P2ROUNDUP(ULONG, Count, BITS_PER_ULONG); - Size /= 8; - - Slab->Mask = __CacheAllocate(Size); + Slab->Mask = CacheMaskCreate(Count); if (Slab->Mask == NULL) goto fail3; @@ -357,7 +431,7 @@ fail4: __CacheDtor(Cache, Object); } - __CacheFree(Slab->Mask); + CacheMaskDestroy(Slab->Mask); fail3: Error("fail3\n"); @@ -409,71 +483,10 @@ CacheDestroySlab( ASSERT(Cache->CurrentSlabs != 0); InterlockedDecrement(&Cache->CurrentSlabs); - __CacheFree(Slab->Mask); + CacheMaskDestroy(Slab->Mask); __CacheFree(Slab); } -static FORCEINLINE ULONG -__CacheMaskScan( - IN ULONG *Mask, - IN ULONG Maximum - ) -{ - ULONG Size; - ULONG Index; - - Size = P2ROUNDUP(ULONG, Maximum, BITS_PER_ULONG); - Size /= sizeof (ULONG); - ASSERT(Size != 0); - - for (Index = 0; Index < Size; Index++) { - ULONG Free = ~Mask[Index]; - ULONG Bit; - - if (!_BitScanForward(&Bit, Free)) - continue; - - Bit += Index * BITS_PER_ULONG; - if (Bit < Maximum) - return Bit; - } - - return Maximum; -} - -static FORCEINLINE VOID -__CacheMaskSet( - IN ULONG *Mask, - IN ULONG Bit - ) -{ - ULONG Index = Bit / BITS_PER_ULONG; - - Mask[Index] |= 1u << (Bit % BITS_PER_ULONG); -} - -static FORCEINLINE BOOLEAN -__CacheMaskTest( - IN ULONG *Mask, - IN ULONG Bit - ) -{ - ULONG Index = Bit / BITS_PER_ULONG; - - return (Mask[Index] & (1u << (Bit % BITS_PER_ULONG))) ? TRUE : FALSE; -} - -static FORCEINLINE VOID -__CacheMaskClear( - IN ULONG *Mask, - IN ULONG Bit - ) -{ - ULONG Index = Bit / BITS_PER_ULONG; - - Mask[Index] &= ~(1u << (Bit % BITS_PER_ULONG)); -} - // Must be called with lock held static PVOID CacheGetObjectFromSlab( @@ -490,7 +503,13 @@ CacheGetObjectFromSlab( if (Slab->CurrentOccupancy == Slab->MaximumOccupancy) return NULL; - Index = __CacheMaskScan(Slab->Mask, Slab->MaximumOccupancy); + Index = 0; + while (Index < Slab->MaximumOccupancy) { + if (!__CacheMaskTest(Slab->Mask, Index)) + break; + + Index++; + } BUG_ON(Index >= Slab->MaximumOccupancy); __CacheMaskSet(Slab->Mask, Index); -- 2.25.1
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |