From 275d93c9ab0f533fa70d698726afc8adaaefb664 Mon Sep 17 00:00:00 2001
From: Adeniyi Mayokun adeniyimayokun17@gmail.com Date: Wed, 14 Mar 2018 06:30:20 +0100 Subject: [PATCH] ntdll/heap.c: align everything to 64 byte to reduce false-sharing issues.
Signed-off-by: Adeniyi Mayokun <adeniyimayokun17@gmail.com@gmail.com> --- dlls/ntdll/heap.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-)
diff --git a/dlls/ntdll/heap.c b/dlls/ntdll/heap.c index e0ffdfec99..d59f3c8414 100644 --- a/dlls/ntdll/heap.c +++ b/dlls/ntdll/heap.c @@ -90,24 +90,27 @@ typedef struct #define ARENA_TAIL_FILLER 0xab #define ARENA_FREE_FILLER 0xfeeefeee
-/* everything is aligned on 8 byte boundaries (16 for Win64) */ -#define ALIGNMENT (2*sizeof(void*)) +/* everything is aligned on 64 byte boundaries */ +#define ALIGNMENT 64 #define LARGE_ALIGNMENT 16 /* large blocks have stricter alignment */ -#define ARENA_OFFSET (ALIGNMENT - sizeof(ARENA_INUSE))
C_ASSERT( sizeof(ARENA_LARGE) % LARGE_ALIGNMENT == 0 );
-#define ROUND_SIZE(size) ((((size) + ALIGNMENT - 1) & ~(ALIGNMENT-1)) + ARENA_OFFSET) +#define ROUND_SIZE(size) ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1)) +#define ROUND_DATA_SIZE(size) (((size + sizeof(ARENA_INUSE) + ALIGNMENT - 1) \ + & ~(ALIGNMENT - 1)) - sizeof(ARENA_INUSE))
#define QUIET 1 /* Suppress messages */ #define NOISY 0 /* Report all errors */
+/* minimum size of a block with arena */ +#define HEAP_MIN_BLOCK_SIZE ROUND_SIZE(max(sizeof(ARENA_FREE) + sizeof(ARENA_FREE*),\ + sizeof(ARENA_INUSE))) /* minimum data size (without arenas) of an allocated block */ -/* make sure that it's larger than a free list entry */ -#define HEAP_MIN_DATA_SIZE ROUND_SIZE(2 * sizeof(struct list)) +#define HEAP_MIN_DATA_SIZE HEAP_MIN_BLOCK_SIZE - sizeof(ARENA_INUSE) /* minimum size by which an allocated block must be shrunk */ /* must be enough to fit the free block that will be created after it */ -#define HEAP_MIN_SHRINK_SIZE (HEAP_MIN_DATA_SIZE+sizeof(ARENA_FREE)) +#define HEAP_MIN_SHRINK_SIZE HEAP_MIN_BLOCK_SIZE /* minimum size to start allocating large blocks */ #define HEAP_MIN_LARGE_BLOCK_SIZE 0x7f000 /* extra size to add at the end of block for tail checking */ @@ -1316,7 +1319,7 @@ grow: return NULL; }
- total_size = size + ROUND_SIZE(sizeof(SUBHEAP)) + sizeof(ARENA_INUSE); + total_size = size + ROUND_SIZE(sizeof(SUBHEAP) + sizeof(ARENA_INUSE)); if (total_size < size) return NULL; /* overflow */
if ((subheap = HEAP_CreateSubHeap( heap, NULL, heap->flags, total_size, @@ -1369,7 +1372,7 @@ static BOOL HEAP_ValidateFreeArena( SUBHEAP *subheap, ARENA_FREE *pArena ) char *heapEnd = (char *)subheap->base + subheap->size;
/* Check for unaligned pointers */ - if ((ULONG_PTR)pArena % ALIGNMENT != ARENA_OFFSET) + if ((ULONG_PTR)pArena % ALIGNMENT != 0) { ERR("Heap %p: unaligned arena pointer %p\n", subheap->heap, pArena ); return FALSE; @@ -1478,7 +1481,7 @@ static BOOL HEAP_ValidateInUseArena( const SUBHEAP *subheap, const ARENA_INUSE * const char *heapEnd = (const char *)subheap->base + subheap->size;
/* Check for unaligned pointers */ - if ((ULONG_PTR)pArena % ALIGNMENT != ARENA_OFFSET) + if ((ULONG_PTR)pArena % ALIGNMENT != 0) { if ( quiet == NOISY ) { @@ -1709,7 +1712,7 @@ static BOOL validate_block_pointer( HEAP *heap, SUBHEAP **ret_subheap, const ARE WARN( "Heap %p: pointer %p is inside subheap %p header\n", subheap->heap, arena + 1, subheap ); else if (subheap->heap->flags & HEAP_VALIDATE) /* do the full validation */ ret = HEAP_ValidateInUseArena( subheap, arena, QUIET ); - else if ((ULONG_PTR)arena % ALIGNMENT != ARENA_OFFSET) + else if ((ULONG_PTR)arena % ALIGNMENT != 0) WARN( "Heap %p: unaligned arena pointer %p\n", subheap->heap, arena ); else if (arena->magic == ARENA_PENDING_MAGIC) WARN( "Heap %p: block %p used after free\n", subheap->heap, arena + 1 ); @@ -1957,7 +1960,7 @@ PVOID WINAPI RtlAllocateHeap( HANDLE heap, ULONG flags, SIZE_T size ) if (!heapPtr) return NULL; flags &= HEAP_GENERATE_EXCEPTIONS | HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY; flags |= heapPtr->flags; - rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags ); + rounded_size = ROUND_DATA_SIZE(size) + HEAP_TAIL_EXTRA_SIZE( flags ); if (rounded_size < size) /* overflow */ { if (flags & HEAP_GENERATE_EXCEPTIONS) RtlRaiseStatus( STATUS_NO_MEMORY ); @@ -2110,7 +2113,7 @@ PVOID WINAPI RtlReAllocateHeap( HANDLE heap, ULONG flags, PVOID ptr, SIZE_T size flags |= heapPtr->flags; if (!(flags & HEAP_NO_SERIALIZE)) RtlEnterCriticalSection( &heapPtr->critSection );
- rounded_size = ROUND_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); + rounded_size = ROUND_DATA_SIZE(size) + HEAP_TAIL_EXTRA_SIZE(flags); if (rounded_size < size) goto oom; /* overflow */ if (rounded_size < HEAP_MIN_DATA_SIZE) rounded_size = HEAP_MIN_DATA_SIZE;