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/lib/libsa/alloc.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 /*      $NetBSD: alloc.c,v 1.17 2003/08/07 16:32:25 agc Exp $   */
    2 
    3 /*
    4  * Copyright (c) 1993
    5  *      The Regents of the University of California.  All rights reserved.
    6  *
    7  * This code is derived from software contributed to Berkeley by
    8  * The Mach Operating System project at Carnegie-Mellon University.
    9  *
   10  * Redistribution and use in source and binary forms, with or without
   11  * modification, are permitted provided that the following conditions
   12  * are met:
   13  * 1. Redistributions of source code must retain the above copyright
   14  *    notice, this list of conditions and the following disclaimer.
   15  * 2. Redistributions in binary form must reproduce the above copyright
   16  *    notice, this list of conditions and the following disclaimer in the
   17  *    documentation and/or other materials provided with the distribution.
   18  * 3. Neither the name of the University nor the names of its contributors
   19  *    may be used to endorse or promote products derived from this software
   20  *    without specific prior written permission.
   21  *
   22  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   25  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   32  * SUCH DAMAGE.
   33  *
   34  *      @(#)alloc.c     8.1 (Berkeley) 6/11/93
   35  *  
   36  *
   37  * Copyright (c) 1997 Christopher G. Demetriou.  All rights reserved.
   38  * Copyright (c) 1996
   39  *      Matthias Drochner.  All rights reserved.
   40  *
   41  * This code is derived from software contributed to Berkeley by
   42  * The Mach Operating System project at Carnegie-Mellon University.
   43  *
   44  * Redistribution and use in source and binary forms, with or without
   45  * modification, are permitted provided that the following conditions
   46  * are met:
   47  * 1. Redistributions of source code must retain the above copyright
   48  *    notice, this list of conditions and the following disclaimer.
   49  * 2. Redistributions in binary form must reproduce the above copyright
   50  *    notice, this list of conditions and the following disclaimer in the
   51  *    documentation and/or other materials provided with the distribution.
   52  * 3. All advertising materials mentioning features or use of this software
   53  *    must display the following acknowledgement:
   54  *      This product includes software developed by the University of
   55  *      California, Berkeley and its contributors.
   56  * 4. Neither the name of the University nor the names of its contributors
   57  *    may be used to endorse or promote products derived from this software
   58  *    without specific prior written permission.
   59  *
   60  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   61  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   62  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   63  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   64  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   65  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   66  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   67  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   68  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   69  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   70  * SUCH DAMAGE.
   71  *
   72  *      @(#)alloc.c     8.1 (Berkeley) 6/11/93
   73  *  
   74  *
   75  * Copyright (c) 1989, 1990, 1991 Carnegie Mellon University
   76  * All Rights Reserved.
   77  *
   78  * Author: Alessandro Forin
   79  * 
   80  * Permission to use, copy, modify and distribute this software and its
   81  * documentation is hereby granted, provided that both the copyright
   82  * notice and this permission notice appear in all copies of the
   83  * software, derivative works or modified versions, and any portions
   84  * thereof, and that both notices appear in supporting documentation.
   85  * 
   86  * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
   87  * CONDITION.  CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
   88  * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
   89  * 
   90  * Carnegie Mellon requests users of this software to return to
   91  * 
   92  *  Software Distribution Coordinator  or  Software.Distribution@CS.CMU.EDU
   93  *  School of Computer Science
   94  *  Carnegie Mellon University
   95  *  Pittsburgh PA 15213-3890
   96  * 
   97  * any improvements or extensions that they make and grant Carnegie the
   98  * rights to redistribute these changes.
   99  */
  100 
  101 /*
  102  * Dynamic memory allocator.
  103  *
  104  * Compile options:
  105  *
  106  *      ALLOC_TRACE     enable tracing of allocations/deallocations
  107 
  108  *      ALLOC_FIRST_FIT use a first-fit allocation algorithm, rather than
  109  *                      the default best-fit algorithm.
  110  *
  111  *      HEAP_LIMIT      heap limit address (defaults to "no limit").
  112  *
  113  *      HEAP_START      start address of heap (defaults to '&end').
  114  *
  115  *      DEBUG           enable debugging sanity checks.
  116  */
  117 
  118 #include <sys/param.h>
  119 #include "stand.h"
  120 
  121 /*
  122  * Each block actually has ALIGN(unsigned) + ALIGN(size) bytes allocated
  123  * to it, as follows:
  124  *
  125  * 0 ... (sizeof(unsigned) - 1)
  126  *      allocated or unallocated: holds size of user-data part of block.
  127  *
  128  * sizeof(unsigned) ... (ALIGN(sizeof(unsigned)) - 1)
  129  *      allocated: unused
  130  *      unallocated: depends on packing of struct fl
  131  *
  132  * ALIGN(sizeof(unsigned)) ... (ALIGN(sizeof(unsigned)) + ALIGN(data size) - 1)
  133  *      allocated: user data
  134  *      unallocated: depends on packing of struct fl
  135  *
  136  * 'next' is only used when the block is unallocated (i.e. on the free list).
  137  * However, note that ALIGN(sizeof(unsigned)) + ALIGN(data size) must
  138  * be at least 'sizeof(struct fl)', so that blocks can be used as structures
  139  * when on the free list.
  140  */
  141 struct fl {
  142         unsigned        size;
  143         struct fl       *next;
  144 } *freelist;
  145 
  146 #ifdef HEAP_VARIABLE
  147 static char *top, *heapstart, *heaplimit;
  148 void setheap(void *start, void *limit)
  149 {
  150     heapstart = top = start;
  151     heaplimit = limit;
  152 }
  153 #define HEAP_START heapstart
  154 #define HEAP_LIMIT heaplimit
  155 #else /* !HEAP_VARIABLE */
  156 #ifndef HEAP_START
  157 extern char end[];
  158 #define HEAP_START end
  159 #endif
  160 static char *top = (char*)HEAP_START;
  161 #endif /* HEAP_VARIABLE */
  162 
  163 void *
  164 alloc(u_int size)
  165 {
  166         struct fl **f = &freelist, **bestf = NULL;
  167 #ifndef ALLOC_FIRST_FIT
  168         unsigned bestsize = 0xffffffff; /* greater than any real size */
  169 #endif
  170         char *help;
  171         int failed;
  172 
  173 #ifdef ALLOC_TRACE
  174         printf("alloc(%u)", size);
  175 #endif
  176 
  177 #ifdef ALLOC_FIRST_FIT
  178         while (*f != (struct fl *)0 && (*f)->size < size)
  179                 f = &((*f)->next);
  180         bestf = f;
  181         failed = (*bestf == (struct fl *)0);
  182 #else
  183         /* scan freelist */
  184         while (*f) {
  185                 if ((*f)->size >= size) {
  186                         if ((*f)->size == size) /* exact match */
  187                                 goto found;
  188 
  189                         if ((*f)->size < bestsize) {
  190                                 /* keep best fit */
  191                                 bestf = f;
  192                                 bestsize = (*f)->size;
  193                         }
  194                 }
  195                 f = &((*f)->next);
  196         }
  197 
  198         /* no match in freelist if bestsize unchanged */
  199         failed = (bestsize == 0xffffffff);
  200 #endif
  201 
  202         if (failed) { /* nothing found */
  203                 /*
  204                  * allocate from heap, keep chunk len in
  205                  * first word
  206                  */
  207                 help = top;
  208 
  209                 /* make _sure_ the region can hold a struct fl. */
  210                 if (size < ALIGN(sizeof (struct fl *)))
  211                         size = ALIGN(sizeof (struct fl *));
  212                 top += ALIGN(sizeof(unsigned)) + ALIGN(size);
  213 #ifdef HEAP_LIMIT
  214                 if (top > (char*)HEAP_LIMIT)
  215                         panic("heap full (0x%lx+%u)", help, size);
  216 #endif
  217                 *(unsigned *)help = ALIGN(size);
  218 #ifdef ALLOC_TRACE
  219                 printf("=%lx\n", (u_long)help + ALIGN(sizeof(unsigned)));
  220 #endif
  221                 return(help + ALIGN(sizeof(unsigned)));
  222         }
  223 
  224         /* we take the best fit */
  225         f = bestf;
  226 
  227 #ifndef ALLOC_FIRST_FIT
  228 found:
  229 #endif
  230         /* remove from freelist */
  231         help = (char*)*f;
  232         *f = (*f)->next;
  233 #ifdef ALLOC_TRACE
  234         printf("=%lx (origsize %u)\n", (u_long)help + ALIGN(sizeof(unsigned)),
  235             *(unsigned *)help);
  236 #endif
  237         return(help + ALIGN(sizeof(unsigned)));
  238 }
  239 
  240 void
  241 free(void *ptr, u_int size)
  242 {
  243         struct fl *f =
  244             (struct fl *)((char*)ptr - ALIGN(sizeof(unsigned)));
  245 #ifdef ALLOC_TRACE
  246         printf("free(%lx, %u) (origsize %u)\n", (u_long)ptr, size, f->size);
  247 #endif
  248 #ifdef DEBUG
  249         if (size > f->size)
  250                 printf("free %u bytes @%lx, should be <=%u\n",
  251                     size, (u_long)ptr, f->size);
  252 
  253         if (ptr < (void *)HEAP_START)
  254                 printf("free: %lx before start of heap.\n", (u_long)ptr);
  255 
  256 #ifdef HEAP_LIMIT
  257         if (ptr > (void *)HEAP_LIMIT)
  258                 printf("free: %lx beyond end of heap.\n", (u_long)ptr);
  259 #endif
  260 #endif /* DEBUG */
  261         /* put into freelist */
  262         f->next = freelist;
  263         freelist = f;
  264 }

Cache object: 551dc3ff95ae346aa924f8559a11708e


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