| 1389 | } |
| 1390 | |
| 1391 | static int |
| 1392 | _rpmalloc_span_finalize(heap_t* heap, size_t iclass, span_t* span, span_t** list_head) { |
| 1393 | void* free_list = heap->size_class[iclass].free_list; |
| 1394 | span_t* class_span = (span_t*)((uintptr_t)free_list & _memory_span_mask); |
| 1395 | if (span == class_span) { |
| 1396 | // Adopt the heap class free list back into the span free list |
| 1397 | void* block = span->free_list; |
| 1398 | void* last_block = 0; |
| 1399 | while (block) { |
| 1400 | last_block = block; |
| 1401 | block = *((void**)block); |
| 1402 | } |
| 1403 | uint32_t free_count = 0; |
| 1404 | block = free_list; |
| 1405 | while (block) { |
| 1406 | ++free_count; |
| 1407 | block = *((void**)block); |
| 1408 | } |
| 1409 | if (last_block) { |
| 1410 | *((void**)last_block) = free_list; |
| 1411 | } else { |
| 1412 | span->free_list = free_list; |
| 1413 | } |
| 1414 | heap->size_class[iclass].free_list = 0; |
| 1415 | span->used_count -= free_count; |
| 1416 | } |
| 1417 | //If this assert triggers you have memory leaks |
| 1418 | rpmalloc_assert(span->list_size == span->used_count, "Memory leak detected"); |
| 1419 | if (span->list_size == span->used_count) { |
| 1420 | _rpmalloc_stat_dec(&heap->span_use[0].current); |
| 1421 | _rpmalloc_stat_dec(&heap->size_class_use[iclass].spans_current); |
| 1422 | // This function only used for spans in double linked lists |
| 1423 | if (list_head) |
| 1424 | _rpmalloc_span_double_link_list_remove(list_head, span); |
| 1425 | _rpmalloc_span_unmap(span); |
| 1426 | return 1; |
| 1427 | } |
| 1428 | return 0; |
| 1429 | } |
| 1430 | |
| 1431 | |
| 1432 | //////////// |
no test coverage detected