| 4152 | /* --------------------------- memalign support -------------------------- */ |
| 4153 | |
| 4154 | static void* internal_memalign(mstate m, size_t alignment, size_t bytes) { |
| 4155 | if (alignment <= MALLOC_ALIGNMENT) /* Can just use malloc */ |
| 4156 | return internal_malloc(m, bytes); |
| 4157 | if (alignment < MIN_CHUNK_SIZE) /* must be at least a minimum chunk size */ |
| 4158 | alignment = MIN_CHUNK_SIZE; |
| 4159 | if ((alignment & (alignment-SIZE_T_ONE)) != 0) {/* Ensure a power of 2 */ |
| 4160 | size_t a = MALLOC_ALIGNMENT << 1; |
| 4161 | while (a < alignment) a <<= 1; |
| 4162 | alignment = a; |
| 4163 | } |
| 4164 | |
| 4165 | if (bytes >= MAX_REQUEST - alignment) { |
| 4166 | if (m != 0) { /* Test isn't needed but avoids compiler warning */ |
| 4167 | MALLOC_FAILURE_ACTION; |
| 4168 | } |
| 4169 | } |
| 4170 | else { |
| 4171 | size_t nb = request2size(bytes); |
| 4172 | size_t req = nb + alignment + MIN_CHUNK_SIZE - CHUNK_OVERHEAD; |
| 4173 | char* mem = internal_malloc(m, req); |
| 4174 | if (mem != 0) { |
| 4175 | void* leader = 0; |
| 4176 | void* trailer = 0; |
| 4177 | mchunkptr p = mem2chunk(mem); |
| 4178 | |
| 4179 | if (PREACTION(m)) return 0; |
| 4180 | if ((((size_t)(mem)) % alignment) != 0) { /* misaligned */ |
| 4181 | /* |
| 4182 | Find an aligned spot inside chunk. Since we need to give |
| 4183 | back leading space in a chunk of at least MIN_CHUNK_SIZE, if |
| 4184 | the first calculation places us at a spot with less than |
| 4185 | MIN_CHUNK_SIZE leader, we can move to the next aligned spot. |
| 4186 | We've allocated enough total room so that this is always |
| 4187 | possible. |
| 4188 | */ |
| 4189 | char* br = (char*)mem2chunk((size_t)(((size_t)(mem + |
| 4190 | alignment - |
| 4191 | SIZE_T_ONE)) & |
| 4192 | -alignment)); |
| 4193 | char* pos = ((size_t)(br - (char*)(p)) >= MIN_CHUNK_SIZE)? |
| 4194 | br : br+alignment; |
| 4195 | mchunkptr newp = (mchunkptr)pos; |
| 4196 | size_t leadsize = pos - (char*)(p); |
| 4197 | size_t newsize = chunksize(p) - leadsize; |
| 4198 | |
| 4199 | if (is_mmapped(p)) { /* For mmapped chunks, just adjust offset */ |
| 4200 | newp->prev_foot = p->prev_foot + leadsize; |
| 4201 | newp->head = (newsize|CINUSE_BIT); |
| 4202 | } |
| 4203 | else { /* Otherwise, give back leader, use the rest */ |
| 4204 | set_inuse(m, newp, newsize); |
| 4205 | set_inuse(m, p, leadsize); |
| 4206 | leader = chunk2mem(p); |
| 4207 | } |
| 4208 | p = newp; |
| 4209 | } |
| 4210 | |
| 4211 | /* Give back spare room at the end */ |
no outgoing calls
no test coverage detected