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-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

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

Cache object: 58e329f003a0eab62f1f9cec21e1e51c


[ 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.