00001 /* @(#)root/clib:$Id: mmprivate.h 31251 2009-11-17 20:00:28Z rdm $ */ 00002 00003 /************************************************************************* 00004 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. * 00005 * All rights reserved. * 00006 * * 00007 * For the licensing terms see $ROOTSYS/LICENSE. * 00008 * For the list of contributors see $ROOTSYS/README/CREDITS. * 00009 *************************************************************************/ 00010 00011 /* Declarations for `mmalloc' and friends. 00012 Copyright 1990, 1991, 1992 Free Software Foundation 00013 00014 Written May 1989 by Mike Haertel. 00015 Heavily modified Mar 1992 by Fred Fish. (fnf@cygnus.com) 00016 00017 The GNU C Library is free software; you can redistribute it and/or 00018 modify it under the terms of the GNU Library General Public License as 00019 published by the Free Software Foundation; either version 2 of the 00020 License, or (at your option) any later version. 00021 00022 The GNU C Library is distributed in the hope that it will be useful, 00023 but WITHOUT ANY WARRANTY; without even the implied warranty of 00024 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00025 Library General Public License for more details. 00026 00027 You should have received a copy of the GNU Library General Public 00028 License along with the GNU C Library; see the file COPYING.LIB. If 00029 not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, 00030 Boston, MA 02111-1307, USA. 00031 00032 The author may be reached (Email) at the address mike@ai.mit.edu, 00033 or (US mail) as Mike Haertel c/o Free Software Foundation. */ 00034 00035 00036 #ifndef __MMPRIVATE_H 00037 #define __MMPRIVATE_H 1 00038 00039 #include "mmalloc.h" 00040 00041 #ifdef R__HAVE_LIMITS_H 00042 # include <limits.h> 00043 #else 00044 # ifndef CHAR_BIT 00045 # define CHAR_BIT 8 00046 # endif 00047 #endif 00048 00049 #ifdef R__HAVE_STDDEF_H 00050 # include <stddef.h> 00051 #else 00052 # include <sys/types.h> /* hope for the best -- ANSI C is your friend */ 00053 #endif 00054 00055 #ifdef R__HAVE_UNISTD_H 00056 # include <unistd.h> 00057 #endif 00058 #ifdef R__HAVE_STDLIB_H 00059 # include <stdlib.h> 00060 #endif 00061 00062 #ifndef MIN 00063 # define MIN(A, B) ((A) < (B) ? (A) : (B)) 00064 #endif 00065 00066 #define MMALLOC_MAGIC "mmalloc" /* Mapped file magic number */ 00067 #define MMALLOC_MAGIC_SIZE 8 /* Size of magic number buf */ 00068 #define MMALLOC_VERSION 1 /* Current mmalloc version */ 00069 #define MMALLOC_KEYS 16 /* Keys for application use */ 00070 00071 /* The allocator divides the heap into blocks of fixed size; large 00072 requests receive one or more whole blocks, and small requests 00073 receive a fragment of a block. Fragment sizes are powers of two, 00074 and all fragments of a block are the same size. When all the 00075 fragments in a block have been freed, the block itself is freed. */ 00076 00077 #define INT_BIT (CHAR_BIT * sizeof(int)) 00078 #define BLOCKLOG (INT_BIT > 16 ? 12 : 9) 00079 #define BLOCKSIZE ((unsigned int) 1 << BLOCKLOG) 00080 #define BLOCKIFY(SIZE) (((SIZE) + BLOCKSIZE - 1) / BLOCKSIZE) 00081 00082 /* The difference between two pointers is a signed int. On machines where 00083 the data addresses have the high bit set, we need to ensure that the 00084 difference becomes an unsigned int when we are using the address as an 00085 integral value. In addition, when using with the '%' operator, the 00086 sign of the result is machine dependent for negative values, so force 00087 it to be treated as an unsigned int. */ 00088 00089 #define ADDR2UINT(addr) ((unsigned int) ((char *) (addr) - (char *) NULL)) 00090 #define RESIDUAL(addr,bsize) ((unsigned int) (ADDR2UINT (addr) % (bsize))) 00091 00092 /* Determine the amount of memory spanned by the initial heap table 00093 (not an absolute limit). */ 00094 00095 #define HEAP (INT_BIT > 16 ? 4194304 : 65536) 00096 00097 /* Number of contiguous free blocks allowed to build up at the end of 00098 memory before they will be returned to the system. */ 00099 00100 #define FINAL_FREE_BLOCKS 8 00101 00102 /* Where to start searching the free list when looking for new memory. 00103 The two possible values are 0 and heapindex. Starting at 0 seems 00104 to reduce total memory usage, while starting at heapindex seems to 00105 run faster. */ 00106 00107 #define MALLOC_SEARCH_START mdp -> heapindex 00108 00109 /* Address to block number and vice versa. */ 00110 00111 #define BLOCK(A) (((char *) (A) - mdp -> heapbase) / BLOCKSIZE + 1) 00112 00113 #define ADDRESS(B) ((PTR) (((B) - 1) * BLOCKSIZE + mdp -> heapbase)) 00114 00115 /* Data structure giving per-block information. */ 00116 00117 typedef union 00118 { 00119 /* Heap information for a busy block. */ 00120 struct 00121 { 00122 /* Zero for a large block, or positive giving the 00123 logarithm to the base two of the fragment size. */ 00124 int type; 00125 union 00126 { 00127 struct 00128 { 00129 size_t nfree; /* Free fragments in a fragmented block. */ 00130 size_t first; /* First free fragment of the block. */ 00131 } frag; 00132 /* Size (in blocks) of a large cluster. */ 00133 size_t size; 00134 } info; 00135 } busy; 00136 /* Heap information for a free block (that may be the first of 00137 a free cluster). */ 00138 struct 00139 { 00140 size_t size; /* Size (in blocks) of a free cluster. */ 00141 size_t next; /* Index of next free cluster. */ 00142 size_t prev; /* Index of previous free cluster. */ 00143 } free; 00144 } mmalloc_info; 00145 00146 /* List of blocks allocated with `mmemalign' (or `mvalloc'). */ 00147 00148 struct alignlist 00149 { 00150 struct alignlist *next; 00151 PTR aligned; /* The address that mmemaligned returned. */ 00152 PTR exact; /* The address that malloc returned. */ 00153 }; 00154 00155 /* Doubly linked lists of free fragments. */ 00156 00157 struct mmlist 00158 { 00159 struct mmlist *next; 00160 struct mmlist *prev; 00161 }; 00162 00163 /* Statistics available to the user. 00164 FIXME: By design, the internals of the malloc package are no longer 00165 exported to the user via an include file, so access to this data needs 00166 to be via some other mechanism, such as mmstat_<something> where the 00167 return value is the <something> the user is interested in. */ 00168 00169 struct mstats 00170 { 00171 size_t bytes_total; /* Total size of the heap. */ 00172 size_t chunks_used; /* Chunks allocated by the user. */ 00173 size_t bytes_used; /* Byte total of user-allocated chunks. */ 00174 size_t chunks_free; /* Chunks in the free list. */ 00175 size_t bytes_free; /* Byte total of chunks in the free list. */ 00176 }; 00177 00178 /* Internal structure that defines the format of the malloc-descriptor. 00179 This gets written to the base address of the region that mmalloc is 00180 managing, and thus also becomes the file header for the mapped file, 00181 if such a file exists. */ 00182 00183 struct mdesc 00184 { 00185 /* The "magic number" for an mmalloc file. */ 00186 00187 char magic[MMALLOC_MAGIC_SIZE]; 00188 00189 /* The size in bytes of this structure, used as a sanity check when reusing 00190 a previously created mapped file. */ 00191 00192 unsigned int headersize; 00193 00194 /* The version number of the mmalloc package that created this file. */ 00195 00196 unsigned char version; 00197 00198 /* Some flag bits to keep track of various internal things. */ 00199 00200 unsigned int flags; 00201 00202 /* If a system call made by the mmalloc package fails, the errno is 00203 preserved for future examination. */ 00204 00205 int saved_errno; 00206 00207 /* Pointer to the function that is used to get more core, or return core 00208 to the system, for requests using this malloc descriptor. For memory 00209 mapped regions, this is the mmap() based routine. There may also be 00210 a single malloc descriptor that points to an sbrk() based routine 00211 for systems without mmap() or for applications that call the mmalloc() 00212 package with a NULL malloc descriptor. 00213 00214 FIXME: For mapped regions shared by more than one process, this 00215 needs to be maintained on a per-process basis. */ 00216 00217 PTR (*morecore) PARAMS ((struct mdesc *, int)); 00218 00219 /* Pointer to the function that causes an abort when the memory checking 00220 features are activated. By default this is set to abort(), but can 00221 be set to another function by the application using mmalloc(). 00222 00223 FIXME: For mapped regions shared by more than one process, this 00224 needs to be maintained on a per-process basis. */ 00225 00226 void (*abortfunc) PARAMS ((void)); 00227 00228 /* Debugging hook for free. 00229 00230 FIXME: For mapped regions shared by more than one process, this 00231 needs to be maintained on a per-process basis. */ 00232 00233 void (*mfree_hook) PARAMS ((PTR, PTR)); 00234 00235 /* Debugging hook for `malloc'. 00236 00237 FIXME: For mapped regions shared by more than one process, this 00238 needs to be maintained on a per-process basis. */ 00239 00240 PTR (*mmalloc_hook) PARAMS ((PTR, size_t)); 00241 00242 /* Debugging hook for realloc. 00243 00244 FIXME: For mapped regions shared by more than one process, this 00245 needs to be maintained on a per-process basis. */ 00246 00247 PTR (*mrealloc_hook) PARAMS ((PTR, PTR, size_t)); 00248 00249 /* Number of info entries. */ 00250 00251 size_t heapsize; 00252 00253 /* Pointer to first block of the heap (base of the first block). */ 00254 00255 char *heapbase; 00256 00257 /* Current search index for the heap table. */ 00258 /* Search index in the info table. */ 00259 00260 size_t heapindex; 00261 00262 /* Limit of valid info table indices. */ 00263 00264 size_t heaplimit; 00265 00266 /* Block information table. 00267 Allocated with malign/__mmalloc_free (not mmalloc/mfree). */ 00268 /* Table indexed by block number giving per-block information. */ 00269 00270 mmalloc_info *heapinfo; 00271 00272 /* Instrumentation. */ 00273 00274 struct mstats heapstats; 00275 00276 /* Free list headers for each fragment size. */ 00277 /* Free lists for each fragment size. */ 00278 00279 struct mmlist fraghead[BLOCKLOG]; 00280 00281 /* List of blocks allocated by memalign. */ 00282 00283 struct alignlist *aligned_blocks; 00284 00285 /* The base address of the memory region for this malloc heap. This 00286 is the location where the bookkeeping data for mmap and for malloc 00287 begins. */ 00288 00289 char *base; 00290 00291 /* The current location in the memory region for this malloc heap which 00292 represents the end of memory in use. */ 00293 00294 char *breakval; 00295 00296 /* The end of the current memory region for this malloc heap. This is 00297 the first location past the end of mapped memory. */ 00298 00299 char *top; 00300 00301 /* Offset between base (as stored by the writer) and address where 00302 mapped by the reader. */ 00303 00304 long offset; 00305 00306 /* Open file descriptor for the file to which this malloc heap is mapped. 00307 This will always be a valid file descriptor, since /dev/zero is used 00308 by default if no open file is supplied by the client. Also note that 00309 it may change each time the region is mapped and unmapped. */ 00310 00311 #ifndef WIN32 00312 int fd; 00313 #else 00314 HANDLE fd; 00315 #endif 00316 00317 /* An array of keys to data within the mapped region, for use by the 00318 application. */ 00319 00320 PTR keys[MMALLOC_KEYS]; 00321 00322 }; 00323 00324 /* Bits to look at in the malloc descriptor flags word */ 00325 00326 #define MMALLOC_DEVZERO (1 << 0) /* Have mapped to /dev/zero */ 00327 #define MMALLOC_INITIALIZED (1 << 1) /* Initialized mmalloc */ 00328 #define MMALLOC_MMCHECK_USED (1 << 2) /* mmcheck() called already */ 00329 00330 /* Internal version of `mfree' used in `morecore'. */ 00331 00332 extern void __mmalloc_free PARAMS ((struct mdesc *, PTR)); 00333 00334 /* Hooks for debugging versions. */ 00335 00336 extern void (*__mfree_hook) PARAMS ((PTR, PTR)); 00337 extern PTR (*__mmalloc_hook) PARAMS ((PTR, size_t)); 00338 extern PTR (*__mrealloc_hook) PARAMS ((PTR, PTR, size_t)); 00339 00340 /* A default malloc descriptor for the single sbrk() managed region. */ 00341 00342 extern struct mdesc *__mmalloc_default_mdp; 00343 00344 00345 /* Grow or shrink a contiguous mapped region using mmap(). 00346 Works much like sbrk() */ 00347 00348 #if defined(R__HAVE_MMAP) 00349 00350 extern PTR __mmalloc_mmap_morecore PARAMS ((struct mdesc *, int)); 00351 00352 #endif 00353 00354 /* Remap a mmalloc region that was previously mapped. */ 00355 00356 extern PTR __mmalloc_remap_core PARAMS ((struct mdesc *)); 00357 00358 /* Macro to convert from a user supplied malloc descriptor to pointer to the 00359 internal malloc descriptor. If the user supplied descriptor is NULL, then 00360 use the default internal version, initializing it if necessary. Otherwise 00361 just cast the user supplied version (which is void *) to the proper type 00362 (struct mdesc *). */ 00363 00364 #ifndef NO_SBRK_MALLOC 00365 00366 /* Initialize the first use of the default malloc descriptor, which uses 00367 an sbrk() region. */ 00368 00369 extern struct mdesc *__mmalloc_sbrk_init PARAMS ((void)); 00370 00371 #define MD_TO_MDP(md) \ 00372 ((md) == NULL \ 00373 ? (__mmalloc_default_mdp == NULL \ 00374 ? __mmalloc_sbrk_init () \ 00375 : __mmalloc_default_mdp) \ 00376 : (struct mdesc *) (md)) 00377 00378 #else 00379 00380 #define MD_TO_MDP(md) ((struct mdesc *) (md)) 00381 00382 #endif 00383 00384 #endif /* __MMPRIVATE_H */