| 492 | } |
| 493 | |
| 494 | static void *alloc_aligned(size_t align, size_t size, struct memory_type *type) |
| 495 | { |
| 496 | /* Define a large request to be 1024 bytes for either alignment or |
| 497 | * size of allocation. */ |
| 498 | const size_t large_request = 1024; |
| 499 | |
| 500 | if (size == 0) return 0; |
| 501 | if (type->align_regions == 0) { |
| 502 | type->align_regions = malloc(sizeof(struct align_region_t)); |
| 503 | if (type->align_regions == NULL) |
| 504 | return NULL; |
| 505 | memset(type->align_regions, 0, sizeof(struct align_region_t)); |
| 506 | } |
| 507 | struct align_region_t *reg = type->align_regions; |
| 508 | |
| 509 | if (size >= large_request || align >= large_request) { |
| 510 | reg = allocate_region(align, 0, size, type); |
| 511 | if (reg == NULL) |
| 512 | return NULL; |
| 513 | return reg->start_data; |
| 514 | } |
| 515 | |
| 516 | look_further: |
| 517 | while (reg != 0) |
| 518 | { |
| 519 | if ((reg->alignment == align) && (reg->free >= (size + align - 1)/align)) |
| 520 | { |
| 521 | #if CONFIG(LP_DEBUG_MALLOC) |
| 522 | printf(" found memalign region. %u free, %zu required\n", reg->free, (size + align - 1)/align); |
| 523 | #endif |
| 524 | break; |
| 525 | } |
| 526 | reg = reg->next; |
| 527 | } |
| 528 | if (reg == 0) |
| 529 | { |
| 530 | #if CONFIG(LP_DEBUG_MALLOC) |
| 531 | printf(" need to allocate a new memalign region\n"); |
| 532 | #endif |
| 533 | /* get align regions */ |
| 534 | reg = allocate_region(align, large_request/align, size, type); |
| 535 | #if CONFIG(LP_DEBUG_MALLOC) |
| 536 | printf(" ... returned %p\n", reg); |
| 537 | #endif |
| 538 | } |
| 539 | if (reg == 0) { |
| 540 | /* Nothing available. */ |
| 541 | return (void *)NULL; |
| 542 | } |
| 543 | |
| 544 | int i, count = 0, target = (size+align-1)/align; |
| 545 | for (i = 0; i < (reg->size/align); i++) |
| 546 | { |
| 547 | if (((u8*)reg->start)[i] == 0) |
| 548 | { |
| 549 | count++; |
| 550 | if (count == target) { |
| 551 | count = i+1-count; |
no test coverage detected