1 /* 2 $Id: malloc-private.h,v 1.4 2006/03/31 12:56:52 wg Exp $ 3 Private header file for ptmalloc3, created by Wolfram Gloger 4 and released to the public domain, as explained at 5 http://creativecommons.org/licenses/publicdomain. 6 */ 7 8 /* The following file is replicated from malloc.c */ 9 10 #ifndef MALLOC_PRIVATE_H 11 #define MALLOC_PRIVATE_H 12 13 #ifndef MALLOC_ALIGNMENT 14 # define MALLOC_ALIGNMENT ((size_t)8U) 15 #endif 16 #ifndef USE_LOCKS 17 # define USE_LOCKS 0 18 #endif 19 20 /* The bit mask value corresponding to MALLOC_ALIGNMENT */ 21 #define CHUNK_ALIGN_MASK (MALLOC_ALIGNMENT - SIZE_T_ONE) 22 23 /* the number of bytes to offset an address to align it */ 24 #define align_offset(A)\ 25 ((((size_t)(A) & CHUNK_ALIGN_MASK) == 0)? 0 :\ 26 ((MALLOC_ALIGNMENT - ((size_t)(A) & CHUNK_ALIGN_MASK)) & CHUNK_ALIGN_MASK)) 27 28 #if !defined(MAP_ANONYMOUS) && defined(MAP_ANON) 29 #define MAP_ANONYMOUS MAP_ANON 30 #endif /* MAP_ANON */ 31 #ifdef MAP_ANONYMOUS 32 #define MMAP_FLAGS (MAP_PRIVATE|MAP_ANONYMOUS) 33 #define CALL_MMAP(s) mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, -1, 0) 34 #else /* MAP_ANONYMOUS */ 35 /* 36 Nearly all versions of mmap support MAP_ANONYMOUS, so the following 37 is unlikely to be needed, but is supplied just in case. 38 */ 39 #include <fcntl.h> /* for O_RDWR */ 40 #define MMAP_FLAGS (MAP_PRIVATE) 41 static int dev_zero_fd = -1; /* Cached file descriptor for /dev/zero. */ 42 #define CALL_MMAP(s) ((dev_zero_fd < 0) ? \ 43 (dev_zero_fd = open("/dev/zero", O_RDWR), \ 44 mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, dev_zero_fd, 0)) : \ 45 mmap(0, (s), PROT_READ|PROT_WRITE, MMAP_FLAGS, dev_zero_fd, 0)) 46 #endif /* MAP_ANONYMOUS */ 47 #define CALL_MUNMAP(a, s) munmap((a), (s)) 48 49 struct malloc_chunk { 50 size_t prev_foot; /* Size of previous chunk (if free). */ 51 size_t head; /* Size and inuse bits. */ 52 struct malloc_chunk* fd; /* double links -- used only if free. */ 53 struct malloc_chunk* bk; 54 }; 55 56 typedef struct malloc_chunk mchunk; 57 typedef struct malloc_chunk* mchunkptr; 58 59 typedef unsigned int binmap_t; 60 typedef unsigned int flag_t; 61 62 struct malloc_tree_chunk; 63 typedef struct malloc_tree_chunk* tbinptr; 64 65 struct malloc_segment { 66 char* base; /* base address */ 67 size_t size; /* allocated size */ 68 struct malloc_segment* next; /* ptr to next segment */ 69 flag_t sflags; /* mmap and extern flag */ 70 }; 71 72 typedef struct malloc_segment msegment; 73 74 #define NSMALLBINS (32U) 75 #define NTREEBINS (32U) 76 77 struct malloc_state { 78 binmap_t smallmap; 79 binmap_t treemap; 80 size_t dvsize; 81 size_t topsize; 82 char* least_addr; 83 mchunkptr dv; 84 mchunkptr top; 85 size_t trim_check; 86 size_t release_checks; 87 size_t magic; 88 mchunkptr smallbins[(NSMALLBINS+1)*2]; 89 tbinptr treebins[NTREEBINS]; 90 size_t footprint; 91 size_t max_footprint; 92 flag_t mflags; 93 #if USE_LOCKS 94 MLOCK_T mutex; 95 #endif /* USE_LOCKS */ 96 msegment seg; 97 void* extp; 98 size_t exts; 99 }; 100 101 /* 102 TOP_FOOT_SIZE is padding at the end of a segment, including space 103 that may be needed to place segment records and fenceposts when new 104 noncontiguous segments are added. 105 */ 106 #define TOP_FOOT_SIZE\ 107 (align_offset(chunk2mem(0))+pad_request(sizeof(struct malloc_segment))+MIN_CHUNK_SIZE) 108 109 /* ------------------- Chunks sizes and alignments ----------------------- */ 110 111 #define MCHUNK_SIZE (sizeof(mchunk)) 112 113 #define CHUNK_OVERHEAD (SIZE_T_SIZE) 114 115 /* MMapped chunks need a second word of overhead ... */ 116 #define MMAP_CHUNK_OVERHEAD (TWO_SIZE_T_SIZES) 117 /* ... and additional padding for fake next-chunk at foot */ 118 #define MMAP_FOOT_PAD (FOUR_SIZE_T_SIZES) 119 120 /* The smallest size we can malloc is an aligned minimal chunk */ 121 #define MIN_CHUNK_SIZE\ 122 ((MCHUNK_SIZE + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 123 124 /* conversion from malloc headers to user pointers, and back */ 125 #define chunk2mem(p) ((void*)((char*)(p) + TWO_SIZE_T_SIZES)) 126 #define mem2chunk(mem) ((mchunkptr)((char*)(mem) - TWO_SIZE_T_SIZES)) 127 /* chunk associated with aligned address A */ 128 #define align_as_chunk(A) (mchunkptr)((A) + align_offset(chunk2mem(A))) 129 130 /* pad request bytes into a usable size */ 131 #define pad_request(req) \ 132 (((req) + CHUNK_OVERHEAD + CHUNK_ALIGN_MASK) & ~CHUNK_ALIGN_MASK) 133 134 /* The byte and bit size of a size_t */ 135 #define SIZE_T_SIZE (sizeof(size_t)) 136 #define SIZE_T_BITSIZE (sizeof(size_t) << 3) 137 138 /* Some constants coerced to size_t */ 139 /* Annoying but necessary to avoid errors on some platforms */ 140 #define SIZE_T_ZERO ((size_t)0) 141 #define SIZE_T_ONE ((size_t)1) 142 #define SIZE_T_TWO ((size_t)2) 143 #define SIZE_T_FOUR ((size_t)4) 144 #define TWO_SIZE_T_SIZES (SIZE_T_SIZE<<1) 145 #define FOUR_SIZE_T_SIZES (SIZE_T_SIZE<<2) 146 #define SIX_SIZE_T_SIZES (FOUR_SIZE_T_SIZES+TWO_SIZE_T_SIZES) 147 #define HALF_MAX_SIZE_T (MAX_SIZE_T / 2U) 148 149 #define IS_MMAPPED_BIT (SIZE_T_ONE) 150 #define PINUSE_BIT (SIZE_T_ONE) 151 #define CINUSE_BIT (SIZE_T_TWO) 152 #define FLAG_BITS (PINUSE_BIT|CINUSE_BIT|SIZE_T_FOUR) 153 154 /* head field is or'ed with NON_MAIN_ARENA if the chunk was obtained 155 from a non-main arena. This is only set immediately before handing 156 the chunk to the user, if necessary. */ 157 #define NON_MAIN_ARENA (SIZE_T_FOUR) 158 159 #define cinuse(p) ((p)->head & CINUSE_BIT) 160 #define pinuse(p) ((p)->head & PINUSE_BIT) 161 #define chunksize(p) ((p)->head & ~(FLAG_BITS)) 162 163 #define is_mmapped(p)\ 164 (!((p)->head & PINUSE_BIT) && ((p)->prev_foot & IS_MMAPPED_BIT)) 165 166 /* Get the internal overhead associated with chunk p */ 167 #define overhead_for(p)\ 168 (is_mmapped(p)? MMAP_CHUNK_OVERHEAD : CHUNK_OVERHEAD) 169 170 #endif /* MALLOC_PRIVATE_H */ 171