The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/libsa/malloc.c

Version: -  FREEBSD  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-2  -  FREEBSD-11-1  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-4  -  FREEBSD-10-3  -  FREEBSD-10-2  -  FREEBSD-10-1  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-3  -  FREEBSD-9-2  -  FREEBSD-9-1  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-4  -  FREEBSD-8-3  -  FREEBSD-8-2  -  FREEBSD-8-1  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-4  -  FREEBSD-7-3  -  FREEBSD-7-2  -  FREEBSD-7-1  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-4  -  FREEBSD-6-3  -  FREEBSD-6-2  -  FREEBSD-6-1  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-5  -  FREEBSD-5-4  -  FREEBSD-5-3  -  FREEBSD-5-2  -  FREEBSD-5-1  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  linux-2.6  -  linux-2.4.22  -  MK83  -  MK84  -  PLAN9  -  DFBSD  -  NETBSD  -  NETBSD5  -  NETBSD4  -  NETBSD3  -  NETBSD20  -  OPENBSD  -  xnu-517  -  xnu-792  -  xnu-792.6.70  -  xnu-1228  -  xnu-1456.1.26  -  xnu-1699.24.8  -  xnu-2050.18.24  -  OPENSOLARIS  -  minix-3-1-1 
SearchContext: -  none  -  3  -  10 

    1 /*
    2  * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
    3  *
    4  * @APPLE_LICENSE_HEADER_START@
    5  * 
    6  * The contents of this file constitute Original Code as defined in and
    7  * are subject to the Apple Public Source License Version 1.1 (the
    8  * "License").  You may not use this file except in compliance with the
    9  * License.  Please obtain a copy of the License at
   10  * http://www.apple.com/publicsource and read it before using this file.
   11  * 
   12  * This Original Code and all software distributed under the License are
   13  * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
   14  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
   15  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
   16  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
   17  * License for the specific language governing rights and limitations
   18  * under the License.
   19  * 
   20  * @APPLE_LICENSE_HEADER_END@
   21  */
   22 #include <string.h>
   23 
   24 #include <mach/mach_types.h>
   25 
   26 #include <kern/kern_types.h>
   27 #include <kern/queue.h>
   28 #include <kern/kalloc.h>
   29 #include <kern/lock.h>
   30 #include <kern/assert.h> 
   31 
   32 #include <vm/vm_kern.h>
   33 
   34 #include "libsa/malloc.h"
   35 
   36 extern void panic(const char *string, ...);
   37 
   38 /*********************************************************************
   39 * Structure for a client memory block. Contains linked-list pointers,
   40 * a size field giving the TOTAL size of the block, including this
   41 * header, and the address of the client's block. The client block
   42 * field is guaranteed to lie on a 16-byte boundary.
   43 *********************************************************************/
   44 typedef struct malloc_block {
   45 
   46         struct malloc_block     *malFwd;
   47         struct malloc_block     *malBwd;
   48         void                    *malActl;
   49         unsigned int            malSize;
   50 } malloc_block;
   51 
   52 static malloc_block malAnchor = {&malAnchor, &malAnchor, 0, 0};
   53 
   54 static int malInited = 0;
   55 static mutex_t *malloc_lock;
   56 
   57 __private_extern__
   58 void * malloc(size_t size) {
   59 
   60     unsigned int nsize;
   61     unsigned int nmem, rmem;
   62     malloc_block *amem;
   63  
   64     assert(malInited);
   65 
   66         nsize = size + sizeof(malloc_block) + 15;       /* Make sure we get enough to fit */
   67 
   68         nmem = (unsigned int)kalloc(nsize);                     /* Get some */
   69         if(!nmem) {                                                                     /* Got any? */
   70                 panic("malloc: no memory for a %08X sized request\n", nsize);
   71         }
   72         
   73         rmem = (nmem + 15) & -16;                                       /* Round to 16 byte boundary */
   74         amem = (malloc_block *)rmem;                            /* Point to the block */
   75         amem->malActl = nmem;                                   /* Set the actual address */
   76         amem->malSize = nsize;                                          /* Size */
   77         
   78         mutex_lock(malloc_lock);
   79         
   80         amem->malFwd = malAnchor.malFwd;                        /* Move anchor to our forward */
   81         amem->malBwd = &malAnchor;                                      /* We point back to anchor */
   82         malAnchor.malFwd->malBwd = amem;                        /* The old forward's back points to us */
   83         malAnchor.malFwd = amem;                                        /* Now we point the anchor to us */
   84         
   85         mutex_unlock(malloc_lock);                              /* Unlock now */
   86         
   87         return (void *)(rmem + 16);                                     /* Return the block */
   88 
   89 } /* malloc() */
   90 
   91 
   92 /*********************************************************************
   93 * free()
   94 *
   95 *********************************************************************/
   96 __private_extern__
   97 void free(void * address) {
   98 
   99 
  100     malloc_block *amem, *fore, *aft;
  101     
  102     if(!(unsigned int)address) return;                  /* Leave if they try to free nothing */
  103     
  104     
  105     amem = (malloc_block *)((unsigned int)address - sizeof(malloc_block));      /* Point to the header */
  106 
  107         mutex_lock(malloc_lock);
  108 
  109         fore = amem->malFwd;                                            /* Get the guy in front */
  110         aft  = amem->malBwd;                                            /* And the guy behind */
  111         fore->malBwd = aft;                                                     /* The next guy's previous is now my previous */
  112         aft->malFwd = fore;                                                     /* The previous guy's forward is now mine */    
  113 
  114         mutex_unlock(malloc_lock);                              /* Unlock now */
  115    
  116         kfree(amem->malActl, amem->malSize);            /* Toss it */
  117 
  118         return; 
  119 
  120 } /* free() */
  121 
  122 /*********************************************************************
  123 * malloc_reset()
  124 *
  125 * Allocate the mutual exclusion lock that protect malloc's data.
  126 *********************************************************************/
  127 __private_extern__ void
  128 malloc_init(void)
  129 {
  130     malloc_lock = mutex_alloc(0);
  131     malInited = 1;
  132 }
  133 
  134 
  135 /*********************************************************************
  136 * malloc_reset()
  137 *
  138 * Walks through the list of VM-allocated regions, destroying them
  139 * all. Any subsequent access by clients to allocated data will cause
  140 * a segmentation fault.
  141 *********************************************************************/
  142 __private_extern__
  143 void malloc_reset(void) {
  144  
  145     malloc_block *amem, *bmem;
  146 
  147         mutex_lock(malloc_lock);
  148         
  149         amem = malAnchor.malFwd;                                /* Get the first one */
  150         
  151         while(amem != &malAnchor) {                             /* Go until we hit the anchor */
  152         
  153                 bmem = amem->malFwd;                            /* Next one */
  154                 kfree(amem->malActl, amem->malSize);            /* Toss it */
  155                 amem = bmem;                                    /* Skip to it */
  156         
  157         } 
  158 
  159         malAnchor.malFwd = (struct malloc_block *) 0x666;       /* Cause a fault if we try again */
  160         malAnchor.malBwd = (struct malloc_block *) 0x666;       /* Cause a fault if we try again */
  161         
  162         mutex_unlock(malloc_lock);                              /* Unlock now */
  163 
  164         mutex_free(malloc_lock);
  165     return;
  166 
  167 } /* malloc_reset() */
  168 
  169 
  170 /*********************************************************************
  171 * realloc()
  172 *
  173 * This function simply allocates a new block and copies the existing
  174 * data into it. Nothing too clever here, as cleanup and efficient
  175 * memory usage are not important in this allocator package.
  176 *********************************************************************/
  177 __private_extern__
  178 void * realloc(void * address, size_t new_client_size) {
  179     void * new_address;
  180     malloc_block *amem;
  181 
  182         amem = (malloc_block *)((unsigned int)address - sizeof(malloc_block));  /* Point to allocation block */
  183         
  184         new_address = malloc(new_client_size);          /* get a new one */
  185         if(!new_address) {                                                      /* Did we get it? */
  186                 panic("realloc: can not reallocate one of %08X size\n", new_client_size);
  187         }
  188         
  189     memcpy(new_address, address, amem->malSize - sizeof(malloc_block)); /* Copy the old in */
  190     
  191     free(address);                                                              /* Toss the old one */
  192         
  193     return new_address;
  194 
  195 } /* realloc() */
  196 
  197 

Cache object: a14a832224322e24d2287f2123e93185


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.