Changeset c47e1a8 in mainline for uspace/lib/c/generic/malloc.c


Ignore:
Timestamp:
2010-05-21T07:50:04Z (16 years ago)
Author:
Lenka Trochtova <trochtova.lenka@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
d51ee2b
Parents:
cf8cc36 (diff), 15b592b (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the (diff) links above to see all the changes relative to each parent.
Message:

merge mainline changes (rev. 451)

File:
1 moved

Legend:

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

    rcf8cc36 rc47e1a8  
    4343#include <bitops.h>
    4444#include <mem.h>
     45#include <futex.h>
    4546#include <adt/gcdlcm.h>
    4647
     
    7576#define NET_SIZE(size)  ((size) - STRUCT_OVERHEAD)
    7677
    77 
    7878/** Header of a heap block
    7979 *
     
    104104extern char _heap;
    105105
     106/** Futex for thread-safe heap manipulation */
     107static futex_t malloc_futex = FUTEX_INITIALIZER;
     108
    106109/** Address of heap start */
    107110static void *heap_start = 0;
     
    119122 *
    120123 * Fills in the structures related to a heap block.
     124 * Should be called only inside the critical section.
    121125 *
    122126 * @param addr Address of the block.
     
    144148 * Verifies that the structures related to a heap block still contain
    145149 * the magic constants. This helps detect heap corruption early on.
     150 * Should be called only inside the critical section.
    146151 *
    147152 * @param addr Address of the block.
     
    161166}
    162167
     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 */
    163175static bool grow_heap(size_t size)
    164176{
    165177        if (size == 0)
     178                return false;
     179
     180        if ((heap_start + size < heap_start) || (heap_end + size < heap_end))
    166181                return false;
    167182       
     
    186201}
    187202
     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 */
    188210static void shrink_heap(void)
    189211{
     
    193215/** Initialize the heap allocator
    194216 *
    195  * Finds how much physical memory we have and creates
     217 * Find how much physical memory we have and create
    196218 * the heap management structures that mark the whole
    197219 * physical memory as a single free block.
     
    200222void __heap_init(void)
    201223{
     224        futex_down(&malloc_futex);
     225       
    202226        if (as_area_create((void *) &_heap, PAGE_SIZE,
    203227            AS_AREA_WRITE | AS_AREA_READ)) {
     
    210234                block_init(heap_start, heap_end - heap_start, true);
    211235        }
    212 }
    213 
     236       
     237        futex_up(&malloc_futex);
     238}
     239
     240/** Get maximum heap address
     241 *
     242 */
    214243uintptr_t get_max_heap_addr(void)
    215244{
     245        futex_down(&malloc_futex);
     246       
    216247        if (max_heap_size == (size_t) -1)
    217248                max_heap_size =
    218249                    max((size_t) (heap_end - heap_start), MAX_HEAP_SIZE);
    219250       
    220         return ((uintptr_t) heap_start + max_heap_size);
    221 }
    222 
     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 */
    223267static void split_mark(heap_block_head_t *cur, const size_t size)
    224268{
     
    240284
    241285/** Allocate a memory block
     286 *
     287 * Should be called only inside the critical section.
    242288 *
    243289 * @param size  The size of the block to allocate.
     
    353399}
    354400
     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 */
    355409void *calloc(const size_t nmemb, const size_t size)
    356410{
     
    358412        if (block == NULL)
    359413                return NULL;
    360 
     414       
    361415        memset(block, 0, nmemb * size);
    362416        return block;
    363417}
    364418
     419/** Allocate memory
     420 *
     421 * @param size Number of bytes to allocate.
     422 *
     423 * @return Allocated memory or NULL.
     424 *
     425 */
    365426void *malloc(const size_t size)
    366427{
    367         return malloc_internal(size, BASE_ALIGN);
    368 }
    369 
     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 */
    370443void *memalign(const size_t align, const size_t size)
    371444{
     
    376449            1 << (fnzb(max(sizeof(void *), align) - 1) + 1);
    377450       
    378         return malloc_internal(size, palign);
    379 }
    380 
     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 */
    381466void *realloc(const void *addr, const size_t size)
    382467{
    383468        if (addr == NULL)
    384469                return malloc(size);
     470       
     471        futex_down(&malloc_futex);
    385472       
    386473        /* Calculate the position of the header. */
     
    395482       
    396483        void *ptr = NULL;
     484        bool reloc = false;
    397485        size_t real_size = GROSS_SIZE(ALIGN_UP(size, BASE_ALIGN));
    398486        size_t orig_size = head->size;
     
    412500        } else {
    413501                /* Look at the next block. If it is free and the size is
    414                    sufficient then merge the two. */
     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. */
    415505                heap_block_head_t *next_head =
    416506                    (heap_block_head_t *) (((void *) head) + head->size);
     
    424514                       
    425515                        ptr = ((void *) head) + sizeof(heap_block_head_t);
    426                 } else {
    427                         ptr = malloc(size);
    428                         if (ptr != NULL) {
    429                                 memcpy(ptr, addr, NET_SIZE(orig_size));
    430                                 free(addr);
    431                         }
     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);
    432527                }
    433528        }
     
    439534 *
    440535 * @param addr The address of the block.
     536 *
    441537 */
    442538void free(const void *addr)
    443539{
     540        futex_down(&malloc_futex);
     541       
    444542        /* Calculate the position of the header. */
    445543        heap_block_head_t *head
     
    480578       
    481579        shrink_heap();
     580       
     581        futex_up(&malloc_futex);
    482582}
    483583
Note: See TracChangeset for help on using the changeset viewer.