| 3326 | } |
| 3327 | |
| 3328 | void* malloc_state::internal_memalign(size_t alignment, size_t bytes) |
| 3329 | { |
| 3330 | void* mem = 0; |
| 3331 | if (alignment < MIN_CHUNK_SIZE) // must be at least a minimum chunk size |
| 3332 | alignment = MIN_CHUNK_SIZE; |
| 3333 | if ((alignment & (alignment - 1)) != 0) |
| 3334 | { |
| 3335 | // Ensure a power of 2 |
| 3336 | size_t a = SPP_MALLOC_ALIGNMENT << 1; |
| 3337 | while (a < alignment) |
| 3338 | a <<= 1; |
| 3339 | alignment = a; |
| 3340 | } |
| 3341 | if (bytes >= MAX_REQUEST - alignment) |
| 3342 | SPP_MALLOC_FAILURE_ACTION; |
| 3343 | else |
| 3344 | { |
| 3345 | size_t nb = request2size(bytes); |
| 3346 | size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; |
| 3347 | mem = internal_malloc(req); |
| 3348 | if (mem != 0) |
| 3349 | { |
| 3350 | mchunkptr p = mem2chunk(mem); |
| 3351 | if ((((size_t)(mem)) & (alignment - 1)) != 0) |
| 3352 | { |
| 3353 | // misaligned |
| 3354 | /* |
| 3355 | Find an aligned spot inside chunk. Since we need to give |
| 3356 | back leading space in a chunk of at least MIN_CHUNK_SIZE, if |
| 3357 | the first calculation places us at a spot with less than |
| 3358 | MIN_CHUNK_SIZE leader, we can move to the next aligned spot. |
| 3359 | We've allocated enough total room so that this is always |
| 3360 | possible. |
| 3361 | */ |
| 3362 | char* br = (char*)mem2chunk((void *)(((size_t)((char*)mem + alignment - 1)) & |
| 3363 | -alignment)); |
| 3364 | char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE) ? |
| 3365 | br : br + alignment; |
| 3366 | mchunkptr newp = (mchunkptr)pos; |
| 3367 | size_t leadsize = pos - (char*)(p); |
| 3368 | size_t newsize = p->chunksize() - leadsize; |
| 3369 | |
| 3370 | if (p->is_mmapped()) |
| 3371 | { |
| 3372 | // For mmapped chunks, just adjust offset |
| 3373 | newp->_prev_foot = p->_prev_foot + leadsize; |
| 3374 | newp->_head = newsize; |
| 3375 | } |
| 3376 | else |
| 3377 | { |
| 3378 | // Otherwise, give back leader, use the rest |
| 3379 | set_inuse(newp, newsize); |
| 3380 | set_inuse(p, leadsize); |
| 3381 | dispose_chunk(p, leadsize); |
| 3382 | } |
| 3383 | p = newp; |
| 3384 | } |
| 3385 |
no test coverage detected