heap: Fix spurious heap_caps_check_integrity() errors in Comprehensive mode

Heap was not being locked before poisoning, so heap_caps_check_integrity()
would sometimes race with checking the poison bytes and print unnecessary
errors.

Details: https://esp32.com/viewtopic.php?f=2&t=3348&p=15732#p15732
This commit is contained in:
Angus Gratton
2017-10-18 14:54:55 +08:00
committed by Angus Gratton
parent 2e8441df9e
commit 04188d8ec7
5 changed files with 108 additions and 42 deletions

View File

@@ -329,6 +329,16 @@ void multi_heap_set_lock(multi_heap_handle_t heap, void *lock)
heap->lock = lock;
}
void inline multi_heap_internal_lock(multi_heap_handle_t heap)
{
MULTI_HEAP_LOCK(heap->lock);
}
void inline multi_heap_internal_unlock(multi_heap_handle_t heap)
{
MULTI_HEAP_UNLOCK(heap->lock);
}
void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
{
heap_block_t *best_block = NULL;
@@ -341,7 +351,7 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
return NULL;
}
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
/* Find best free block to perform the allocation in */
prev = &heap->first_block;
@@ -361,7 +371,7 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
}
if (best_block == NULL) {
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
return NULL; /* No room in heap */
}
@@ -376,7 +386,7 @@ void *multi_heap_malloc_impl(multi_heap_handle_t heap, size_t size)
heap->minimum_free_bytes = heap->free_bytes;
}
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
return best_block->data;
}
@@ -389,7 +399,7 @@ void multi_heap_free_impl(multi_heap_handle_t heap, void *p)
return;
}
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
assert_valid_block(heap, pb);
MULTI_HEAP_ASSERT(!is_free(pb), pb); // block should not be free
@@ -420,7 +430,7 @@ void multi_heap_free_impl(multi_heap_handle_t heap, void *p)
pb = merge_adjacent(heap, pb, next);
}
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
}
@@ -451,7 +461,7 @@ void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size)
return NULL;
}
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
result = NULL;
if (size <= block_data_size(pb)) {
@@ -461,7 +471,7 @@ void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size)
}
else if (heap->free_bytes < size - block_data_size(pb)) {
// Growing, but there's not enough total free space in the heap
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
return NULL;
}
@@ -512,7 +522,7 @@ void *multi_heap_realloc_impl(multi_heap_handle_t heap, void *p, size_t size)
heap->minimum_free_bytes = heap->free_bytes;
}
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
return result;
}
@@ -530,7 +540,7 @@ bool multi_heap_check(multi_heap_handle_t heap, bool print_errors)
size_t total_free_bytes = 0;
assert(heap != NULL);
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
heap_block_t *prev = NULL;
heap_block_t *prev_free = NULL;
@@ -593,7 +603,7 @@ bool multi_heap_check(multi_heap_handle_t heap, bool print_errors)
}
done:
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
return valid;
}
@@ -602,7 +612,7 @@ void multi_heap_dump(multi_heap_handle_t heap)
{
assert(heap != NULL);
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
printf("Heap start %p end %p\nFirst free block %p\n", &heap->first_block, heap->last_block, heap->first_block.next_free);
for(heap_block_t *b = &heap->first_block; b != NULL; b = get_next_block(b)) {
printf("Block %p data size 0x%08zx bytes next block %p", b, block_data_size(b), get_next_block(b));
@@ -612,7 +622,7 @@ void multi_heap_dump(multi_heap_handle_t heap)
printf("\n");
}
}
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
}
size_t multi_heap_free_size_impl(multi_heap_handle_t heap)
@@ -639,7 +649,7 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info)
return;
}
MULTI_HEAP_LOCK(heap->lock);
multi_heap_internal_lock(heap);
for(heap_block_t *b = get_next_block(&heap->first_block); !is_last_block(b); b = get_next_block(b)) {
info->total_blocks++;
if (is_free(b)) {
@@ -659,6 +669,6 @@ void multi_heap_get_info_impl(multi_heap_handle_t heap, multi_heap_info_t *info)
// heap has wrong total size (address printed here is not indicative of the real error)
MULTI_HEAP_ASSERT(info->total_free_bytes == heap->free_bytes, heap);
MULTI_HEAP_UNLOCK(heap->lock);
multi_heap_internal_unlock(heap);
}