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); |