1 /******************************************************************* 2 * File: omAllocPrivate.h 3 * Purpose: declaration of "private" (but visible to the outside) 4 * routines for omalloc 5 * Author: obachman (Olaf Bachmann) 6 * Created: 11/99 7 *******************************************************************/ 8 #ifndef OM_ALLOC_PRIVATE_H 9 #define OM_ALLOC_PRIVATE_H 10 #include "omalloc/omAllocSystem.h" 11 12 /******************************************************************* 13 * 14 * Definitions of structures we work with 15 * 16 *******************************************************************/ 17 /* Need to define it here, has to be known to macros */ 18 struct omBinPage_s 19 { 20 long used_blocks; /* number of used blocks of this page */ 21 void* current; /* pointer to current freelist */ 22 omBinPage next; /* next/prev pointer of pages */ 23 omBinPage prev; 24 void* bin_sticky; /* bin this page belongs to with 25 sticky tag of page hidden in ptr */ 26 omBinPageRegion region; /* BinPageRegion of this page */ 27 }; 28 29 /* Change this appropriately, if you change omBinPage */ 30 /* However, make sure that omBinPage is a multiple of SIZEOF_MAX_TYPE */ 31 #define SIZEOF_OM_BIN_PAGE_HEADER (5*SIZEOF_VOIDP + SIZEOF_LONG) 32 #define SIZEOF_OM_BIN_PAGE (SIZEOF_SYSTEM_PAGE - SIZEOF_OM_BIN_PAGE_HEADER) 33 34 /* keep all members of omBin_s a sizeof(long) type, 35 otherwise list operations will fail */ 36 struct omBin_s 37 { 38 omBinPage current_page; /* page of current freelist */ 39 omBinPage last_page; /* pointer to last page of freelist */ 40 omBin next; /* sticky bins of the same size */ 41 size_t sizeW; /* size in words */ 42 long max_blocks; /* if > 0 # blocks in one page, 43 if < 0 # pages for one block */ 44 unsigned long sticky; /* sticky tag */ 45 }; 46 47 struct omSpecBin_s 48 { 49 omSpecBin next; /* pointer to next bin */ 50 omBin bin; /* pointer to bin itself */ 51 long max_blocks; /* max_blocks of bin*/ 52 long ref; /* ref count */ 53 }; 54 55 extern omSpecBin om_SpecBin; 56 extern omBin om_StickyBins; 57 extern omBinPage_t om_ZeroPage[]; 58 extern omBin om_Size2Bin[]; 59 60 /******************************************************************* 61 * 62 * Working with pages/bins 63 * 64 *******************************************************************/ 65 #define omGetTopBinOfPage(page) \ 66 ((omBin) ( ((unsigned long) ((page)->bin_sticky)) & ~((unsigned long)SIZEOF_VOIDP - 1))) 67 #define omGetStickyOfPage(page) \ 68 (((unsigned long) ((page)->bin_sticky)) & ((unsigned long)SIZEOF_VOIDP-1)) 69 #define omSetTopBinOfPage(page, bin) \ 70 (page)->bin_sticky= (void*)((unsigned long)bin + omGetStickyOfPage(page)) 71 #define omSetStickyOfPage(page, sticky) \ 72 (page)->bin_sticky = (void*)(((unsigned long)sticky & ((unsigned long)SIZEOF_VOIDP-1)) + \ 73 (unsigned long)omGetTopBinOfPage(page)) 74 #define omSetTopBinAndStickyOfPage(page, bin, sticky) \ 75 (page)->bin_sticky= (void*)(((unsigned long)sticky & (SIZEOF_VOIDP-1)) \ 76 + (unsigned long)bin) 77 78 #define omGetTopBinOfAddr(addr) \ 79 omGetTopBinOfPage(((omBinPage) omGetPageOfAddr(addr))) 80 #define omGetBinOfAddr(addr) omGetBinOfPage(omGetBinPageOfAddr(addr)) 81 82 #ifndef OM_GENERATE_INC 83 extern omBin_t om_StaticBin[]; 84 extern omBin om_Size2Bin[]; 85 #ifdef OM_ALIGNMENT_NEEDS_WORK 86 extern omBin om_Size2AlignedBin[]; 87 #endif 88 89 /******************************************************************* 90 * 91 * SizeOfAddr 92 * 93 *******************************************************************/ 94 #ifdef OM_INTERNAL_DEBUG 95 size_t omSizeOfBinAddr(void* addr); 96 #else 97 #define omSizeOfBinAddr(addr) _omSizeOfBinAddr(addr) 98 #endif 99 100 #define omSizeWOfBin(bin_ptr) ((bin_ptr)->sizeW) 101 102 #define _omSizeOfBinAddr(addr) ((omSizeWOfBinAddr(addr)) << LOG_SIZEOF_LONG) 103 #define omSizeWOfBinAddr(addr) ((omGetTopBinOfAddr(addr))->sizeW) 104 105 /******************************************************************* 106 * 107 * lowest level alloc/free macros 108 * 109 *******************************************************************/ 110 extern void* omAllocBinFromFullPage(omBin bin); 111 extern void omFreeToPageFault(omBinPage page, void* addr); 112 113 /*******************************************************************/ 114 /* Page */ 115 #define __omTypeAllocFromNonEmptyPage(type, addr, page) \ 116 do \ 117 { \ 118 ((page)->used_blocks)++; \ 119 addr = (type)((page)->current); \ 120 (page)->current = *((void**) (page)->current); \ 121 } \ 122 while (0) 123 124 #define __omFreeToPage(addr, page) \ 125 do \ 126 { \ 127 if ((page)->used_blocks > 0L) \ 128 { \ 129 *((void**) (addr)) = (page)->current; \ 130 ((page)->used_blocks)--; \ 131 (page)->current = (addr); \ 132 } \ 133 else \ 134 { \ 135 omFreeToPageFault(page, addr); \ 136 } \ 137 } \ 138 while (0) 139 140 141 /*******************************************************************/ 142 /* Bin */ 143 #define __omTypeAllocBin(type, addr, bin) \ 144 do \ 145 { \ 146 REGISTER omBinPage __om_page = (bin)->current_page; \ 147 if (__om_page->current != NULL) \ 148 __omTypeAllocFromNonEmptyPage(type, addr, __om_page); \ 149 else \ 150 addr = (type) omAllocBinFromFullPage(bin); \ 151 } \ 152 while (0) 153 154 #define __omTypeAlloc0Bin(type, addr, bin) \ 155 do \ 156 { \ 157 __omTypeAllocBin(type, addr, bin); \ 158 omMemsetW(addr, 0, (bin)->sizeW); \ 159 } \ 160 while (0) 161 162 163 #define __omFreeBinAddr(addr) \ 164 do \ 165 { \ 166 REGISTER void* __om_addr = (void*) (addr); \ 167 REGISTER omBinPage __om_page = omGetBinPageOfAddr(__om_addr); \ 168 __omFreeToPage(__om_addr, __om_page); \ 169 } \ 170 while (0) 171 172 #define __omTypeReallocBin(old_addr, old_bin, new_type, new_addr, new_bin) \ 173 do \ 174 { \ 175 if (old_bin != new_bin) \ 176 { \ 177 size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr)); \ 178 __omTypeAllocBin(new_type, new_addr, new_bin); \ 179 omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW)); \ 180 __omFreeBinAddr(old_addr); \ 181 } \ 182 else \ 183 { \ 184 new_addr = (new_type) old_addr; \ 185 } \ 186 } \ 187 while (0) 188 189 190 #define __omTypeRealloc0Bin(old_addr, old_bin, new_type, new_addr, new_bin) \ 191 do \ 192 { \ 193 if (old_bin != new_bin) \ 194 { \ 195 size_t old_sizeW = (omIsNormalBinPageAddr(old_addr) ? old_bin->sizeW : omSizeWOfAddr(old_addr)); \ 196 __omTypeAllocBin(new_type, new_addr, new_bin); \ 197 omMemcpyW(new_addr, old_addr, (new_bin->sizeW > old_sizeW ? old_sizeW : new_bin->sizeW)); \ 198 if (new_bin->sizeW > old_sizeW) \ 199 omMemsetW((void**)new_addr + old_sizeW, 0, new_bin->sizeW - old_sizeW); \ 200 __omFreeBinAddr(old_addr); \ 201 } \ 202 else \ 203 { \ 204 new_addr = (new_type) old_addr; \ 205 } \ 206 } \ 207 while (0) 208 209 /*******************************************************************/ 210 /* Size */ 211 #define omSmallSize2Bin(size) om_Size2Bin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT] 212 213 #define __omTypeAlloc(type, addr, size) \ 214 do \ 215 { \ 216 size_t __size = size; \ 217 if (__size <= OM_MAX_BLOCK_SIZE) \ 218 { \ 219 omBin __om_bin = omSmallSize2Bin(__size); \ 220 __omTypeAllocBin(type, addr, __om_bin); \ 221 } \ 222 else \ 223 { \ 224 addr = (type) omAllocLarge(__size); \ 225 } \ 226 } \ 227 while(0) 228 229 #define __omTypeAlloc0(type, addr, size) \ 230 do \ 231 { \ 232 size_t __size = size; \ 233 if (__size <= OM_MAX_BLOCK_SIZE) \ 234 { \ 235 omBin __om_bin = omSmallSize2Bin(__size); \ 236 __omTypeAlloc0Bin(type, addr, __om_bin); \ 237 } \ 238 else \ 239 { \ 240 addr = (type) omAlloc0Large(__size); \ 241 } \ 242 } \ 243 while (0) 244 245 #ifdef OM_ALIGNMENT_NEEDS_WORK 246 #define omSmallSize2AlignedBin(size) om_Size2AlignedBin[((size) -1)>>LOG_SIZEOF_OM_ALIGNMENT] 247 248 #define __omTypeAllocAligned(type, addr, size) \ 249 do \ 250 { \ 251 size_t __size = size; \ 252 if (__size <= OM_MAX_BLOCK_SIZE) \ 253 { \ 254 omBin __om_bin = omSmallSize2AlignedBin(__size); \ 255 __omTypeAllocBin(type, addr, __om_bin); \ 256 } \ 257 else \ 258 { \ 259 addr = (type) omAllocLarge(__size); \ 260 } \ 261 } \ 262 while(0) 263 264 #define __omTypeAlloc0Aligned(type, addr, size) \ 265 do \ 266 { \ 267 size_t __size = size; \ 268 if (__size <= OM_MAX_BLOCK_SIZE) \ 269 { \ 270 omBin __om_bin = omSmallSize2AlignedBin(__size); \ 271 __omTypeAlloc0Bin(type, addr, __om_bin); \ 272 } \ 273 else \ 274 { \ 275 addr = (type) omAlloc0Large(__size); \ 276 } \ 277 } \ 278 while (0) 279 #else 280 #define __omTypeAllocAligned __omTypeAlloc 281 #define __omTypeAlloc0Aligned __omTypeAlloc0 282 #endif /* OM_ALIGNMENT_NEEDS_WORK */ 283 284 #define __omFreeSize(addr, size) \ 285 do \ 286 { \ 287 if ((size <= OM_MAX_BLOCK_SIZE) || omIsBinPageAddr(addr)) \ 288 { \ 289 __omFreeBinAddr(addr); \ 290 } \ 291 else \ 292 { \ 293 omFreeLarge(addr); \ 294 } \ 295 } \ 296 while (0) 297 298 #define __omFree(addr) \ 299 do \ 300 { \ 301 if (omIsBinPageAddr(addr)) \ 302 { \ 303 __omFreeBinAddr(addr); \ 304 } \ 305 else \ 306 { \ 307 omFreeLarge(addr); \ 308 } \ 309 } \ 310 while (0) 311 312 void* omDoRealloc(void* old_addr, size_t new_size, int flags); 313 314 #define ___omTypeRealloc(old_addr, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags) \ 315 do \ 316 { \ 317 size_t __new_size = new_size; \ 318 if (__new_size <= OM_MAX_BLOCK_SIZE && omIsBinPageAddr(old_addr)) \ 319 { \ 320 omBin __old_bin = omGetBinOfAddr(old_addr); \ 321 omBin __new_bin = SIZE_2_BIN(__new_size); \ 322 REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin); \ 323 } \ 324 else \ 325 { \ 326 new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags); \ 327 } \ 328 } \ 329 while (0) 330 331 #define ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, SIZE_2_BIN, REALLOC_BIN, flags) \ 332 do \ 333 { \ 334 size_t __new_size = new_size; \ 335 if (__new_size <= OM_MAX_BLOCK_SIZE && old_size <= OM_MAX_BLOCK_SIZE) \ 336 { \ 337 omBin __old_bin = omGetBinOfAddr(old_addr); \ 338 omBin __new_bin = SIZE_2_BIN(__new_size); \ 339 REALLOC_BIN(old_addr, __old_bin, new_type, new_addr, __new_bin); \ 340 } \ 341 else \ 342 { \ 343 new_addr = (new_type) omDoRealloc(old_addr, __new_size, flags); \ 344 } \ 345 } \ 346 while (0) 347 348 #define __omTypeRealloc(old_addr, new_type, new_addr, new_size) \ 349 ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0) 350 #define __omTypeRealloc0(old_addr, new_type, new_addr, new_size) \ 351 ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1) 352 #define __omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size) \ 353 ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeReallocBin, 0) 354 #define __omTypeRealloc0Size(old_addr, old_size, new_type, new_addr, new_size) \ 355 ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2Bin, __omTypeRealloc0Bin, 1) 356 357 #ifdef OM_ALIGNMENT_NEEDS_WORK 358 #define __omTypeReallocAligned(old_addr, new_type, new_addr, new_size) \ 359 ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2) 360 #define __omTypeRealloc0Aligned(old_addr, new_type, new_addr, new_size) \ 361 ___omTypeRealloc(old_addr, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3) 362 #define __omTypeReallocAlignedSize(old_addr, old_size, new_type, new_addr, new_size) \ 363 ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeReallocBin, 2) 364 #define __omTypeRealloc0AlignedSize(old_addr, old_size, new_type, new_addr, new_size) \ 365 ___omTypeReallocSize(old_addr, old_size, new_type, new_addr, new_size, omSmallSize2AlignedBin, __omTypeRealloc0Bin, 3) 366 #else 367 #define __omTypeReallocAligned __omTypeRealloc 368 #define __omTypeRealloc0Aligned __omTypeRealloc0 369 #define __omTypeReallocAlignedSize __omTypeReallocSize 370 #define __omTypeRealloc0AlignedSize __omTypeRealloc0Size 371 #endif 372 373 #endif /* OM_GENERATE_INC */ 374 #endif /* OM_ALLOC_PRIVATE_H */ 375