Rev 4600 | Rev 4607 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed
Rev 4600 | Rev 4606 | ||
---|---|---|---|
Line 274... | Line 274... | ||
274 | if (addr == aligned) { |
274 | if (addr == aligned) { |
275 | /* Exact block start including alignment. */ |
275 | /* Exact block start including alignment. */ |
276 | split_mark(cur, real_size); |
276 | split_mark(cur, real_size); |
277 | result = addr; |
277 | result = addr; |
278 | } else { |
278 | } else { |
279 | /* Block start has to be aligned, thus |
279 | /* Block start has to be aligned */ |
280 | the previous block needs to be enlarged */ |
- | |
281 | size_t excess = (size_t) (aligned - addr); |
280 | size_t excess = (size_t) (aligned - addr); |
282 | 281 | ||
283 | if (cur->size >= real_size + excess) { |
282 | if (cur->size >= real_size + excess) { |
- | 283 | /* The current block is large enought to fit |
|
- | 284 | data in including alignment */ |
|
284 | if ((void *) cur > heap_start) { |
285 | if ((void *) cur > heap_start) { |
285 | // TODO: This can be optimized further in case |
286 | /* There is a block before the current block. |
286 | // of expanding a previous allocated block if the |
287 | This previous block can be enlarged to compensate |
287 | // excess is large enought to put another free |
- | |
288 | // block in between |
288 | for the alignment excess */ |
289 | heap_block_foot_t *prev_foot = |
289 | heap_block_foot_t *prev_foot = |
290 | ((void *) cur) - sizeof(heap_block_foot_t); |
290 | ((void *) cur) - sizeof(heap_block_foot_t); |
291 | 291 | ||
292 | heap_block_head_t *prev_head = |
292 | heap_block_head_t *prev_head = |
293 | (heap_block_head_t *) (((void *) cur) - prev_foot->size); |
293 | (heap_block_head_t *) (((void *) cur) - prev_foot->size); |
294 | 294 | ||
295 | block_check(prev_head); |
295 | block_check(prev_head); |
296 | 296 | ||
297 | size_t reduced_size = cur->size - excess; |
297 | size_t reduced_size = cur->size - excess; |
298 | cur = ((void *) cur) + excess; |
298 | heap_block_head_t *next_head = ((void *) cur) + excess; |
299 | 299 | ||
- | 300 | if ((!prev_head->free) && (excess >= STRUCT_OVERHEAD)) { |
|
- | 301 | /* The previous block is not free and there is enought |
|
- | 302 | space to fill in a new free block between the previous |
|
- | 303 | and current block */ |
|
- | 304 | block_init(cur, excess, true); |
|
- | 305 | } else { |
|
- | 306 | /* The previous block is free (thus there is no need to |
|
- | 307 | induce additional fragmentation to the heap) or the |
|
- | 308 | excess is small, thus just enlarge the previous block */ |
|
300 | block_init(prev_head, prev_head->size + excess, prev_head->free); |
309 | block_init(prev_head, prev_head->size + excess, prev_head->free); |
- | 310 | } |
|
- | 311 | ||
301 | block_init(cur, reduced_size, true); |
312 | block_init(next_head, reduced_size, true); |
302 | split_mark(cur, real_size); |
313 | split_mark(next_head, real_size); |
303 | result = aligned; |
314 | result = aligned; |
- | 315 | cur = next_head; |
|
304 | } else { |
316 | } else { |
- | 317 | /* The current block is the first block on the heap. |
|
- | 318 | We have to make sure that the alignment excess |
|
- | 319 | is large enought to fit a new free block just |
|
- | 320 | before the current block */ |
|
305 | while (excess < STRUCT_OVERHEAD) { |
321 | while (excess < STRUCT_OVERHEAD) { |
306 | aligned += falign; |
322 | aligned += falign; |
307 | excess += falign; |
323 | excess += falign; |
308 | } |
324 | } |
309 | 325 | ||
- | 326 | /* Check for current block size again */ |
|
310 | if (cur->size >= real_size + excess) { |
327 | if (cur->size >= real_size + excess) { |
311 | size_t reduced_size = cur->size - excess; |
328 | size_t reduced_size = cur->size - excess; |
312 | cur = (heap_block_head_t *) (heap_start + excess); |
329 | cur = (heap_block_head_t *) (heap_start + excess); |
313 | 330 | ||
314 | block_init(heap_start, excess, true); |
331 | block_init(heap_start, excess, true); |