Subversion Repositories HelenOS

Rev

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