Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/c/generic/malloc.c

    r3292623 r63f8966  
    4343#include <bitops.h>
    4444#include <mem.h>
    45 #include <futex.h>
    4645#include <adt/gcdlcm.h>
    4746
     
    7675#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
    7776
     77
    7878/** Header of a heap block
    7979 *
     
    104104extern char _heap;
    105105
    106 /** Futex for thread-safe heap manipulation */
    107 static futex_t malloc_futex = FUTEX_INITIALIZER;
    108 
    109106/** Address of heap start */
    110107static void *heap_start = 0;
     
    122119 *
    123120 * Fills in the structures related to a heap block.
    124  * Should be called only inside the critical section.
    125121 *
    126122 * @param addr Address of the block.
     
    148144 * Verifies that the structures related to a heap block still contain
    149145 * the magic constants. This helps detect heap corruption early on.
    150  * Should be called only inside the critical section.
    151146 *
    152147 * @param addr Address of the block.
     
    166161}
    167162
    168 /** Increase the heap area size
    169  *
    170  * Should be called only inside the critical section.
    171  *
    172  * @param size Number of bytes to grow the heap by.
    173  *
    174  */
    175163static bool grow_heap(size_t size)
    176164{
     
    201189}
    202190
    203 /** Decrease the heap area
    204  *
    205  * Should be called only inside the critical section.
    206  *
    207  * @param size Number of bytes to shrink the heap by.
    208  *
    209  */
    210191static void shrink_heap(void)
    211192{
     
    215196/** Initialize the heap allocator
    216197 *
    217  * Find how much physical memory we have and create
     198 * Finds how much physical memory we have and creates
    218199 * the heap management structures that mark the whole
    219200 * physical memory as a single free block.
     
    222203void __heap_init(void)
    223204{
    224         futex_down(&malloc_futex);
    225        
    226205        if (as_area_create((void *) &_heap, PAGE_SIZE,
    227206            AS_AREA_WRITE | AS_AREA_READ)) {
     
    234213                block_init(heap_start, heap_end - heap_start, true);
    235214        }
    236        
    237         futex_up(&malloc_futex);
    238 }
    239 
    240 /** Get maximum heap address
    241  *
    242  */
     215}
     216
    243217uintptr_t get_max_heap_addr(void)
    244218{
    245         futex_down(&malloc_futex);
    246        
    247219        if (max_heap_size == (size_t) -1)
    248220                max_heap_size =
    249221                    max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
    250222       
    251         uintptr_t max_heap_addr = (uintptr_t) heap_start + max_heap_size;
    252        
    253         futex_up(&malloc_futex);
    254        
    255         return max_heap_addr;
    256 }
    257 
    258 /** Split heap block and mark it as used.
    259  *
    260  * Should be called only inside the critical section.
    261  *
    262  * @param cur  Heap block to split.
    263  * @param size Number of bytes to split and mark from the beginning
    264  *             of the block.
    265  *
    266  */
     223        return ((uintptr_t) heap_start + max_heap_size);
     224}
     225
    267226static void split_mark(heap_block_head_t *cur, const size_t size)
    268227{
     
    284243
    285244/** Allocate a memory block
    286  *
    287  * Should be called only inside the critical section.
    288245 *
    289246 * @param size  The size of the block to allocate.
     
    399356}
    400357
    401 /** Allocate memory by number of elements
    402  *
    403  * @param nmemb Number of members to allocate.
    404  * @param size  Size of one member in bytes.
    405  *
    406  * @return Allocated memory or NULL.
    407  *
    408  */
    409358void *calloc(const size_t nmemb, const size_t size)
    410359{
     
    412361        if (block == NULL)
    413362                return NULL;
    414        
     363
    415364        memset(block, 0, nmemb * size);
    416365        return block;
    417366}
    418367
    419 /** Allocate memory
    420  *
    421  * @param size Number of bytes to allocate.
    422  *
    423  * @return Allocated memory or NULL.
    424  *
    425  */
    426368void *malloc(const size_t size)
    427369{
    428         futex_down(&malloc_futex);
    429         void *block = malloc_internal(size, BASE_ALIGN);
    430         futex_up(&malloc_futex);
    431        
    432         return block;
    433 }
    434 
    435 /** Allocate memory with specified alignment
    436  *
    437  * @param align Alignment in byes.
    438  * @param size  Number of bytes to allocate.
    439  *
    440  * @return Allocated memory or NULL.
    441  *
    442  */
     370        return malloc_internal(size, BASE_ALIGN);
     371}
     372
    443373void *memalign(const size_t align, const size_t size)
    444374{
     
    449379            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    450380       
    451         futex_down(&malloc_futex);
    452         void *block = malloc_internal(size, palign);
    453         futex_up(&malloc_futex);
    454        
    455         return block;
    456 }
    457 
    458 /** Reallocate memory block
    459  *
    460  * @param addr Already allocated memory or NULL.
    461  * @param size New size of the memory block.
    462  *
    463  * @return Reallocated memory or NULL.
    464  *
    465  */
     381        return malloc_internal(size, palign);
     382}
     383
    466384void *realloc(const void *addr, const size_t size)
    467385{
    468386        if (addr == NULL)
    469387                return malloc(size);
    470        
    471         futex_down(&malloc_futex);
    472388       
    473389        /* Calculate the position of the header. */
     
    482398       
    483399        void *ptr = NULL;
    484         bool reloc = false;
    485400        size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
    486401        size_t orig_size = head->size;
     
    500415        } else {
    501416                /* Look at the next block. If it is free and the size is
    502                    sufficient then merge the two. Otherwise just allocate
    503                    a new block, copy the original data into it and
    504                    free the original block. */
     417                   sufficient then merge the two. */
    505418                heap_block_head_t *next_head =
    506419                    (heap_block_head_t *) (((void *) head) + head->size);
     
    514427                       
    515428                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    516                 } else
    517                         reloc = true;
    518         }
    519        
    520         futex_up(&malloc_futex);
    521        
    522         if (reloc) {
    523                 ptr = malloc(size);
    524                 if (ptr != NULL) {
    525                         memcpy(ptr, addr, NET_SIZE(orig_size));
    526                         free(addr);
     429                } else {
     430                        ptr = malloc(size);
     431                        if (ptr != NULL) {
     432                                memcpy(ptr, addr, NET_SIZE(orig_size));
     433                                free(addr);
     434                        }
    527435                }
    528436        }
     
    534442 *
    535443 * @param addr The address of the block.
    536  *
    537444 */
    538445void free(const void *addr)
    539446{
    540         futex_down(&malloc_futex);
    541        
    542447        /* Calculate the position of the header. */
    543448        heap_block_head_t *head
     
    578483       
    579484        shrink_heap();
    580        
    581         futex_up(&malloc_futex);
    582485}
    583486
Note: See TracChangeset for help on using the changeset viewer.