* reserve a block of data in an existing malloc_elem. If the malloc_elem * is much larger than the data block requested, we split the element in two. * This function is only called from malloc_heap_alloc so parameter checking * is not done here, as it's done there previously. */
| 425 | * is not done here, as it's done there previously. |
| 426 | */ |
| 427 | struct malloc_elem * |
| 428 | malloc_elem_alloc(struct malloc_elem *elem, size_t size, unsigned align, |
| 429 | size_t bound, bool contig) |
| 430 | { |
| 431 | struct malloc_elem *new_elem = elem_start_pt(elem, size, align, bound, |
| 432 | contig); |
| 433 | const size_t old_elem_size = (uintptr_t)new_elem - (uintptr_t)elem; |
| 434 | const size_t trailer_size = elem->size - old_elem_size - size - |
| 435 | MALLOC_ELEM_OVERHEAD; |
| 436 | |
| 437 | malloc_elem_free_list_remove(elem); |
| 438 | |
| 439 | if (trailer_size > MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) { |
| 440 | /* split it, too much free space after elem */ |
| 441 | struct malloc_elem *new_free_elem = |
| 442 | RTE_PTR_ADD(new_elem, size + MALLOC_ELEM_OVERHEAD); |
| 443 | |
| 444 | asan_clear_split_alloczone(new_free_elem); |
| 445 | |
| 446 | split_elem(elem, new_free_elem); |
| 447 | malloc_elem_free_list_insert(new_free_elem); |
| 448 | |
| 449 | if (elem == elem->heap->last) |
| 450 | elem->heap->last = new_free_elem; |
| 451 | } |
| 452 | |
| 453 | if (old_elem_size < MALLOC_ELEM_OVERHEAD + MIN_DATA_SIZE) { |
| 454 | /* don't split it, pad the element instead */ |
| 455 | elem->state = ELEM_BUSY; |
| 456 | elem->pad = old_elem_size; |
| 457 | |
| 458 | asan_clear_alloczone(elem); |
| 459 | |
| 460 | /* put a dummy header in padding, to point to real element header */ |
| 461 | if (elem->pad > 0) { /* pad will be at least 64-bytes, as everything |
| 462 | * is cache-line aligned */ |
| 463 | new_elem->pad = elem->pad; |
| 464 | new_elem->state = ELEM_PAD; |
| 465 | new_elem->size = elem->size - elem->pad; |
| 466 | set_header(new_elem); |
| 467 | } |
| 468 | |
| 469 | return new_elem; |
| 470 | } |
| 471 | |
| 472 | asan_clear_split_alloczone(new_elem); |
| 473 | |
| 474 | /* we are going to split the element in two. The original element |
| 475 | * remains free, and the new element is the one allocated. |
| 476 | * Re-insert original element, in case its new size makes it |
| 477 | * belong on a different list. |
| 478 | */ |
| 479 | |
| 480 | split_elem(elem, new_elem); |
| 481 | |
| 482 | asan_clear_alloczone(new_elem); |
| 483 | |
| 484 | new_elem->state = ELEM_BUSY; |
no test coverage detected