Annotation of qemu/roms/SLOF/lib/libc/stdlib/malloc.c, revision 1.1

1.1     ! root        1: /******************************************************************************
        !             2:  * Copyright (c) 2004, 2008 IBM Corporation
        !             3:  * All rights reserved.
        !             4:  * This program and the accompanying materials
        !             5:  * are made available under the terms of the BSD License
        !             6:  * which accompanies this distribution, and is available at
        !             7:  * http://www.opensource.org/licenses/bsd-license.php
        !             8:  *
        !             9:  * Contributors:
        !            10:  *     IBM Corporation - initial implementation
        !            11:  *****************************************************************************/
        !            12: 
        !            13: 
        !            14: #include "stddef.h"
        !            15: #include "stdlib.h"
        !            16: #include "unistd.h"
        !            17: #include "malloc_defs.h"
        !            18: 
        !            19: 
        !            20: static int clean(void);
        !            21: 
        !            22: 
        !            23: /* act points to the end of the initialized heap and the start of uninitialized heap */
        !            24: static char *act;
        !            25: 
        !            26: /* Pointers to start and end of heap: */
        !            27: static char *heap_start, *heap_end;
        !            28: 
        !            29: 
        !            30: /*
        !            31:  * Standard malloc function
        !            32:  */
        !            33: void *
        !            34: malloc(size_t size)
        !            35: {
        !            36:        char *header;
        !            37:        void *data;
        !            38:        size_t blksize;         /* size of memory block including the chunk */
        !            39: 
        !            40:        blksize = size + sizeof(struct chunk);
        !            41: 
        !            42:        /* has malloc been called for the first time? */
        !            43:        if (act == 0) {
        !            44:                size_t initsize;
        !            45:                /* add some space so we have a good initial playground */
        !            46:                initsize = (blksize + 0x1000) & ~0x0fff;
        !            47:                /* get initial memory region with sbrk() */
        !            48:                heap_start = sbrk(initsize);
        !            49:                if (heap_start == (void*)-1)
        !            50:                        return NULL;
        !            51:                heap_end = heap_start + initsize;
        !            52:                act = heap_start;
        !            53:        }
        !            54: 
        !            55:        header = act;
        !            56:        data = act + sizeof(struct chunk);
        !            57: 
        !            58:        /* Check if there is space left in the uninitialized part of the heap */
        !            59:        if (act + blksize > heap_end) {
        !            60:                //search at begin of heap
        !            61:                header = heap_start;
        !            62: 
        !            63:                while ((((struct chunk *) header)->inuse != 0
        !            64:                        || ((struct chunk *) header)->length < size)
        !            65:                       && header < act) {
        !            66:                        header = header + sizeof(struct chunk)
        !            67:                                 + ((struct chunk *) header)->length;
        !            68:                }
        !            69: 
        !            70:                // check if heap is full
        !            71:                if (header >= act) {
        !            72:                        if (clean()) {
        !            73:                                // merging of free blocks succeeded, so try again
        !            74:                                return malloc(size);
        !            75:                        } else if (sbrk(blksize) == heap_end) {
        !            76:                                // succeeded to get more memory, so try again
        !            77:                                heap_end += blksize;
        !            78:                                return malloc(size);
        !            79:                        } else {
        !            80:                                // No more memory available
        !            81:                                return 0;
        !            82:                        }
        !            83:                }
        !            84: 
        !            85:                // Check if we need to split this memory block into two
        !            86:                if (((struct chunk *) header)->length > blksize) {
        !            87:                        //available memory is too big
        !            88:                        int alt;
        !            89: 
        !            90:                        alt = ((struct chunk *) header)->length;
        !            91:                        ((struct chunk *) header)->inuse = 1;
        !            92:                        ((struct chunk *) header)->length = size;
        !            93:                        data = header + sizeof(struct chunk);
        !            94: 
        !            95:                        //mark the rest of the heap
        !            96:                        header = data + size;
        !            97:                        ((struct chunk *) header)->inuse = 0;
        !            98:                        ((struct chunk *) header)->length =
        !            99:                            alt - blksize;
        !           100:                } else {
        !           101:                        //new memory matched exactly in available memory
        !           102:                        ((struct chunk *) header)->inuse = 1;
        !           103:                        data = header + sizeof(struct chunk);
        !           104:                }
        !           105: 
        !           106:        } else {
        !           107: 
        !           108:                ((struct chunk *) header)->inuse = 1;
        !           109:                ((struct chunk *) header)->length = size;
        !           110: 
        !           111:                act += blksize;
        !           112:        }
        !           113: 
        !           114:        return data;
        !           115: }
        !           116: 
        !           117: 
        !           118: /*
        !           119:  * Merge free memory blocks in initialized heap if possible
        !           120:  */
        !           121: static int
        !           122: clean(void)
        !           123: {
        !           124:        char *header;
        !           125:        char *firstfree = 0;
        !           126:        char check = 0;
        !           127: 
        !           128:        header = heap_start;
        !           129:        //if (act == 0)         // This should never happen
        !           130:        //      act = heap_end;
        !           131: 
        !           132:        while (header < act) {
        !           133: 
        !           134:                if (((struct chunk *) header)->inuse == 0) {
        !           135:                        if (firstfree == 0) {
        !           136:                                /* First free block in a row, only save address */
        !           137:                                firstfree = header;
        !           138: 
        !           139:                        } else {
        !           140:                                /* more than one free block in a row, merge them! */
        !           141:                                ((struct chunk *) firstfree)->length +=
        !           142:                                    ((struct chunk *) header)->length +
        !           143:                                    sizeof(struct chunk);
        !           144:                                check = 1;
        !           145:                        }
        !           146:                } else {
        !           147:                        firstfree = 0;
        !           148: 
        !           149:                }
        !           150: 
        !           151:                header = header + sizeof(struct chunk)
        !           152:                         + ((struct chunk *) header)->length;
        !           153: 
        !           154:        }
        !           155: 
        !           156:        return check;
        !           157: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.