[e70e45] | 1 | /******************************************************************* |
---|
| 2 | * File: omAllocSystem.c |
---|
| 3 | * Purpose: implementation of main lowl-level alloc functions |
---|
| 4 | * Author: obachman@mathematik.uni-kl.de (Olaf Bachmann) |
---|
| 5 | * Created: 11/99 |
---|
| 6 | *******************************************************************/ |
---|
| 7 | #ifndef OM_ALLOC_SYSTEM_C |
---|
| 8 | #define OM_ALLOC_SYSTEM_C |
---|
| 9 | |
---|
| 10 | #include <unistd.h> |
---|
[8d0069] | 11 | #include <mylimits.h> |
---|
[5c5c07] | 12 | |
---|
| 13 | |
---|
[599326] | 14 | #include <omalloc/omConfig.h> |
---|
| 15 | #include <omalloc/omDefaultConfig.h> |
---|
| 16 | #include <omalloc/omMalloc.h> |
---|
[f769719] | 17 | #include <omalloc/omalloc.h> |
---|
[5c5c07] | 18 | /* include after omMalloc.h */ |
---|
| 19 | #include <string.h> |
---|
| 20 | |
---|
[e70e45] | 21 | #define OM_MALLOC_FROM_SYSTEM OM_MALLOC_MALLOC |
---|
| 22 | #define OM_REALLOC_FROM_SYSTEM OM_MALLOC_REALLOC |
---|
| 23 | #define OM_FREE_TO_SYSTEM OM_MALLOC_FREE |
---|
| 24 | |
---|
| 25 | /******************************************************************* |
---|
[13fe1b] | 26 | * |
---|
[e70e45] | 27 | * AllocLarge/FreeLarge if malloc can not return sizeof(addr) |
---|
[13fe1b] | 28 | * |
---|
[e70e45] | 29 | *******************************************************************/ |
---|
| 30 | /* allocation of large addr */ |
---|
[13fe1b] | 31 | #if defined(OM_MALLOC_PROVIDES_SIZEOF_ADDR) |
---|
[e70e45] | 32 | #define _omSizeOfLargeAddr(addr) (OM_MALLOC_SIZEOF_ADDR(addr) & (~SIZEOF_OM_ALIGNMENT_1)) |
---|
| 33 | #else |
---|
| 34 | void* omAllocLarge(size_t size) |
---|
| 35 | { |
---|
[13fe1b] | 36 | char* addr; |
---|
[e70e45] | 37 | size = OM_ALIGN_SIZE(size); |
---|
| 38 | addr = omAllocFromSystem(size + SIZEOF_STRICT_ALIGNMENT); |
---|
| 39 | *((size_t*) addr) = size; |
---|
[13fe1b] | 40 | return (void *)(addr + SIZEOF_STRICT_ALIGNMENT); |
---|
[e70e45] | 41 | } |
---|
| 42 | |
---|
| 43 | void* omReallocLarge(void* old_addr, size_t new_size) |
---|
| 44 | { |
---|
[13fe1b] | 45 | char* _old_addr; |
---|
| 46 | char* new_addr; |
---|
| 47 | |
---|
[e70e45] | 48 | omAssume(omIsLargeAddr(old_addr)); |
---|
[13fe1b] | 49 | |
---|
[e70e45] | 50 | new_size = OM_ALIGN_SIZE(new_size); |
---|
[13fe1b] | 51 | _old_addr = (char *)old_addr - SIZEOF_STRICT_ALIGNMENT; |
---|
| 52 | new_addr = omReallocSizeFromSystem(_old_addr, |
---|
| 53 | *((size_t*) _old_addr) + SIZEOF_STRICT_ALIGNMENT, |
---|
[e70e45] | 54 | new_size + SIZEOF_STRICT_ALIGNMENT); |
---|
| 55 | *((size_t*) new_addr) = new_size; |
---|
[13fe1b] | 56 | return (void *)(new_addr + SIZEOF_STRICT_ALIGNMENT); |
---|
[e70e45] | 57 | } |
---|
| 58 | |
---|
| 59 | void omFreeLarge(void* addr) |
---|
| 60 | { |
---|
[13fe1b] | 61 | char* _addr = (char *)addr - SIZEOF_STRICT_ALIGNMENT; |
---|
[e70e45] | 62 | omFreeSizeToSystem(_addr, *((size_t*) _addr) + SIZEOF_STRICT_ALIGNMENT); |
---|
| 63 | } |
---|
| 64 | |
---|
[13fe1b] | 65 | #define _omSizeOfLargeAddr(addr) (*((size_t*) ((char*) addr - SIZEOF_STRICT_ALIGNMENT))) |
---|
[e70e45] | 66 | #endif /* OM_MALLOC_PROVIDES_SIZEOF_ADDR */ |
---|
| 67 | |
---|
| 68 | void* omAlloc0Large(size_t size) |
---|
| 69 | { |
---|
| 70 | void* addr = omAllocLarge(size); |
---|
| 71 | size = omSizeOfLargeAddr(addr); |
---|
| 72 | memset(addr, 0, size); |
---|
| 73 | return addr; |
---|
| 74 | } |
---|
| 75 | |
---|
| 76 | void* omRealloc0Large(void* old_addr, size_t new_size) |
---|
| 77 | { |
---|
| 78 | size_t old_size; |
---|
[13fe1b] | 79 | char* new_addr; |
---|
| 80 | |
---|
[e70e45] | 81 | omAssume(!omIsBinPageAddr(old_addr)); |
---|
| 82 | |
---|
| 83 | old_size = omSizeOfLargeAddr(old_addr); |
---|
[13fe1b] | 84 | |
---|
[e70e45] | 85 | new_addr = omReallocLarge(old_addr, new_size); |
---|
| 86 | new_size = omSizeOfLargeAddr(new_addr); |
---|
| 87 | if (new_size > old_size) |
---|
| 88 | memset(new_addr + old_size, 0, new_size - old_size); |
---|
[13fe1b] | 89 | return (void *)new_addr; |
---|
[e70e45] | 90 | } |
---|
[13fe1b] | 91 | |
---|
[e70e45] | 92 | size_t omSizeOfLargeAddr(void* addr) |
---|
| 93 | { |
---|
[13fe1b] | 94 | return _omSizeOfLargeAddr((char *)addr); |
---|
[e70e45] | 95 | } |
---|
| 96 | |
---|
[13fe1b] | 97 | size_t omSizeOfAddr(const void* addr) |
---|
[e70e45] | 98 | { |
---|
[13fe1b] | 99 | |
---|
[e70e45] | 100 | return (omIsBinPageAddr(addr) ? |
---|
| 101 | #ifdef OM_HAVE_TRACK |
---|
[13fe1b] | 102 | (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr((char *)addr) : omSizeOfBinAddr(addr)) : |
---|
[e70e45] | 103 | #else |
---|
[13fe1b] | 104 | omSizeOfBinAddr(addr) : |
---|
[e70e45] | 105 | #endif |
---|
[13fe1b] | 106 | omSizeOfLargeAddr((char *)addr)); |
---|
[e70e45] | 107 | } |
---|
| 108 | |
---|
| 109 | size_t omSizeWOfAddr(void* addr) |
---|
| 110 | { |
---|
[13fe1b] | 111 | |
---|
[e70e45] | 112 | return (omIsBinPageAddr(addr) ? |
---|
| 113 | #ifdef OM_HAVE_TRACK |
---|
| 114 | (omIsBinAddrTrackAddr(addr) ? omOutSizeOfTrackAddr(addr) >> LOG_SIZEOF_LONG : omSizeWOfBinAddr(addr)) : |
---|
| 115 | #else |
---|
[13fe1b] | 116 | omSizeWOfBinAddr(addr) : |
---|
[e70e45] | 117 | #endif |
---|
| 118 | omSizeOfLargeAddr(addr) >> LOG_SIZEOF_LONG); |
---|
| 119 | } |
---|
| 120 | |
---|
| 121 | /******************************************************************* |
---|
[13fe1b] | 122 | * |
---|
[e70e45] | 123 | * Valloc |
---|
[13fe1b] | 124 | * |
---|
[e70e45] | 125 | *******************************************************************/ |
---|
| 126 | #ifdef OM_HAVE_VALLOC_MMAP |
---|
| 127 | |
---|
[8babe7f] | 128 | #include "omMmap.c" |
---|
| 129 | |
---|
[e70e45] | 130 | #define OM_VALLOC_FROM_SYSTEM omVallocMmap |
---|
| 131 | #define OM_VFREE_TO_SYSTEM omVfreeMmap |
---|
| 132 | |
---|
| 133 | #elif defined(OM_HAVE_VALLOC_MALLOC) |
---|
| 134 | |
---|
| 135 | #define OM_VALLOC_FROM_SYSTEM OM_MALLOC_VALLOC |
---|
| 136 | #define OM_VFREE_TO_SYSTEM OM_MALLOC_VFREE |
---|
| 137 | |
---|
[13fe1b] | 138 | #else |
---|
[e70e45] | 139 | |
---|
| 140 | #define OM_VALLOC_FROM_SYSTEM omEmulateValloc |
---|
| 141 | #define OM_VFREE_TO_SYSTEM omEmulateVfree |
---|
| 142 | |
---|
| 143 | #define OM_ALIGN_PAGE(addr) ( ((long)addr + (SIZEOF_SYSTEM_PAGE -1)) & ~(SIZEOF_SYSTEM_PAGE - 1)) |
---|
| 144 | /* now we implement an emulation */ |
---|
[13fe1b] | 145 | void* omEmulateValloc(size_t size) |
---|
[e70e45] | 146 | { |
---|
| 147 | void* addr; |
---|
| 148 | size_t padding = SIZEOF_VOIDP; |
---|
| 149 | size = OM_ALIGN_SIZE(size); |
---|
| 150 | while (1) |
---|
| 151 | { |
---|
| 152 | addr = OM_MALLOC_FROM_SYSTEM(size + padding); |
---|
| 153 | if (addr == NULL) return NULL; |
---|
| 154 | if ((OM_ALIGN_PAGE(addr) + SIZEOF_VOIDP) - (long) addr <= padding) |
---|
| 155 | { |
---|
| 156 | void* ret_addr = (void*) OM_ALIGN_PAGE(addr); |
---|
| 157 | *((void**) ((void*) ret_addr + size)) = addr; |
---|
| 158 | return ret_addr; |
---|
| 159 | } |
---|
| 160 | else |
---|
| 161 | { |
---|
| 162 | OM_FREE_TO_SYSTEM(addr); |
---|
| 163 | padding = padding << 1; |
---|
| 164 | } |
---|
| 165 | } |
---|
| 166 | } |
---|
| 167 | |
---|
| 168 | void omEmulateVfree(void* addr, size_t size) |
---|
| 169 | { |
---|
| 170 | size = OM_ALIGN_SIZE(size); |
---|
| 171 | OM_FREE_TO_SYSTEM( *((void**) ((void*) addr + size)) ); |
---|
| 172 | } |
---|
| 173 | #endif /* OM_HAVE_VALLOC_MMAP */ |
---|
| 174 | |
---|
| 175 | /******************************************************************* |
---|
[13fe1b] | 176 | * |
---|
[e70e45] | 177 | * System-level Alloc/Free |
---|
[13fe1b] | 178 | * |
---|
[e70e45] | 179 | *******************************************************************/ |
---|
| 180 | void* omAllocFromSystem(size_t size) |
---|
| 181 | { |
---|
| 182 | void* ptr; |
---|
| 183 | |
---|
| 184 | ptr = OM_MALLOC_FROM_SYSTEM(size); |
---|
| 185 | if (ptr == NULL) |
---|
| 186 | { |
---|
| 187 | OM_MEMORY_LOW_HOOK(); |
---|
| 188 | ptr = OM_MALLOC_FROM_SYSTEM(size); |
---|
| 189 | if (ptr == NULL) |
---|
| 190 | { |
---|
| 191 | OM_OUT_OF_MEMORY_HOOK(); |
---|
| 192 | exit(1); |
---|
| 193 | } |
---|
| 194 | } |
---|
| 195 | |
---|
| 196 | #ifndef OM_NDEBUG |
---|
| 197 | if (((unsigned long) ptr) + size > om_MaxAddr) |
---|
| 198 | om_MaxAddr = ((unsigned long) ptr) + size; |
---|
| 199 | if (((unsigned long) ptr) < om_MinAddr) |
---|
| 200 | om_MinAddr = ((unsigned long) ptr); |
---|
[13fe1b] | 201 | #endif |
---|
[e70e45] | 202 | |
---|
| 203 | om_Info.CurrentBytesFromMalloc += size; |
---|
| 204 | if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc) |
---|
| 205 | { |
---|
| 206 | om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc; |
---|
| 207 | #if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM) |
---|
| 208 | if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem) |
---|
| 209 | om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM; |
---|
[13fe1b] | 210 | #endif |
---|
[e70e45] | 211 | #if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK) |
---|
| 212 | if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size; |
---|
[13fe1b] | 213 | if (om_Info.MaxBytesFromMalloc |
---|
[e70e45] | 214 | #ifndef OM_HAVE_VALLOC_MMAP |
---|
[13fe1b] | 215 | + om_Info.CurrentBytesFromValloc |
---|
[e70e45] | 216 | #endif |
---|
| 217 | > om_Info.MaxBytesSbrk) |
---|
| 218 | { |
---|
| 219 | om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit; |
---|
| 220 | } |
---|
| 221 | #endif |
---|
| 222 | } |
---|
| 223 | OM_MALLOC_HOOK(size); |
---|
| 224 | return ptr; |
---|
| 225 | } |
---|
| 226 | |
---|
| 227 | void* omReallocFromSystem(void* addr, size_t newsize) |
---|
| 228 | { |
---|
| 229 | return omReallocSizeFromSystem(addr, omSizeOfAddr(addr), newsize); |
---|
| 230 | } |
---|
| 231 | |
---|
| 232 | void* omReallocSizeFromSystem(void* addr, size_t oldsize, size_t newsize) |
---|
| 233 | { |
---|
| 234 | void* res; |
---|
| 235 | |
---|
| 236 | res = OM_REALLOC_FROM_SYSTEM(addr, newsize); |
---|
| 237 | if (res == NULL) |
---|
| 238 | { |
---|
| 239 | OM_MEMORY_LOW_HOOK(); |
---|
| 240 | /* Can do a realloc again: manpage reads: |
---|
[13fe1b] | 241 | "If realloc() fails the original block is left untouched - |
---|
[e70e45] | 242 | it is not freed or moved." */ |
---|
[13fe1b] | 243 | res = OM_REALLOC_FROM_SYSTEM(addr, newsize); |
---|
[e70e45] | 244 | if (res == NULL) |
---|
| 245 | { |
---|
| 246 | OM_OUT_OF_MEMORY_HOOK(); |
---|
| 247 | /* should never get here */ |
---|
| 248 | omAssume(0); |
---|
| 249 | exit(1); |
---|
| 250 | } |
---|
| 251 | } |
---|
| 252 | |
---|
| 253 | #ifndef OM_NDEBUG |
---|
| 254 | if (((unsigned long) res) + newsize > om_MaxAddr) |
---|
| 255 | om_MaxAddr = ((unsigned long) res) + newsize; |
---|
| 256 | if (((unsigned long) res) < om_MinAddr) |
---|
| 257 | om_MinAddr = ((unsigned long) res); |
---|
[13fe1b] | 258 | #endif |
---|
[e70e45] | 259 | |
---|
| 260 | om_Info.CurrentBytesFromMalloc += (long) newsize - (long) oldsize; |
---|
[13fe1b] | 261 | |
---|
[e70e45] | 262 | |
---|
| 263 | if (om_Info.CurrentBytesFromMalloc > om_Info.MaxBytesFromMalloc) |
---|
| 264 | { |
---|
| 265 | om_Info.MaxBytesFromMalloc = om_Info.CurrentBytesFromMalloc; |
---|
| 266 | #if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM) |
---|
| 267 | if (om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem) |
---|
| 268 | om_Info.MaxBytesSystem = om_Info.CurrentBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM; |
---|
[13fe1b] | 269 | #endif |
---|
[e70e45] | 270 | #if defined(HAVE_SBRK) && !defined(OM_MALLOC_MAX_BYTES_SBRK) |
---|
[13fe1b] | 271 | if (om_Info.MaxBytesFromMalloc |
---|
[e70e45] | 272 | #ifndef OM_HAVE_VALLOC_MMAP |
---|
[13fe1b] | 273 | + om_Info.CurrentBytesFromValloc |
---|
[e70e45] | 274 | #endif |
---|
| 275 | > om_Info.MaxBytesSbrk) |
---|
| 276 | { |
---|
| 277 | om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit; |
---|
| 278 | } |
---|
| 279 | #endif |
---|
| 280 | } |
---|
| 281 | |
---|
| 282 | OM_REALLOC_HOOK(oldsize, newsize); |
---|
| 283 | return res; |
---|
| 284 | } |
---|
| 285 | |
---|
| 286 | void omFreeToSystem(void* addr) |
---|
| 287 | { |
---|
| 288 | omFreeSizeToSystem(addr, omSizeOfAddr(addr)); |
---|
| 289 | } |
---|
[13fe1b] | 290 | |
---|
[e70e45] | 291 | void omFreeSizeToSystem(void* addr, size_t size) |
---|
| 292 | { |
---|
| 293 | OM_FREE_TO_SYSTEM( addr ); |
---|
| 294 | om_Info.CurrentBytesFromMalloc -= size; |
---|
| 295 | OM_FREE_HOOK(size); |
---|
| 296 | } |
---|
| 297 | |
---|
| 298 | void* _omVallocFromSystem(size_t size, int fail) |
---|
| 299 | { |
---|
| 300 | void* page = OM_VALLOC_FROM_SYSTEM(size); |
---|
| 301 | if (page == NULL) |
---|
| 302 | { |
---|
| 303 | OM_MEMORY_LOW_HOOK(); |
---|
| 304 | page = OM_VALLOC_FROM_SYSTEM(size); |
---|
| 305 | if (page == NULL) |
---|
| 306 | { |
---|
| 307 | if (fail) return NULL; |
---|
| 308 | else |
---|
| 309 | { |
---|
| 310 | OM_OUT_OF_MEMORY_HOOK(); |
---|
| 311 | /* should never get here */ |
---|
| 312 | omAssume(0); |
---|
| 313 | exit(1); |
---|
| 314 | } |
---|
| 315 | } |
---|
| 316 | } |
---|
| 317 | |
---|
| 318 | #ifndef OM_NDEBUG |
---|
| 319 | if (((unsigned long) page) + size > om_MaxAddr) |
---|
| 320 | om_MaxAddr = ((unsigned long) page) + size; |
---|
| 321 | if (((unsigned long) page) < om_MinAddr) |
---|
| 322 | om_MinAddr = ((unsigned long) page); |
---|
[13fe1b] | 323 | #endif |
---|
[e70e45] | 324 | |
---|
| 325 | omAssume(omIsAddrPageAligned(page)); |
---|
| 326 | om_Info.CurrentBytesFromValloc += size; |
---|
| 327 | if (om_Info.CurrentBytesFromValloc > om_Info.MaxBytesFromValloc) |
---|
| 328 | { |
---|
| 329 | om_Info.MaxBytesFromValloc = om_Info.CurrentBytesFromValloc; |
---|
| 330 | #if defined(OM_HAVE_VALLOC_MMAP) && defined(OM_MALLOC_MAX_BYTES_SYSTEM) |
---|
| 331 | if (om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM > om_Info.MaxBytesSystem) |
---|
| 332 | om_Info.MaxBytesSystem = om_Info.MaxBytesFromValloc + OM_MALLOC_MAX_BYTES_SYSTEM; |
---|
| 333 | #endif |
---|
| 334 | #if defined(HAVE_SBRK) && !defined(OM_HAVE_VALLOC_MMAP) && !defined(OM_MALLOC_MAX_BYTES_SBRK) |
---|
| 335 | if (! om_SbrkInit) om_SbrkInit = (unsigned long) sbrk(0) - size; |
---|
| 336 | if (om_Info.CurrentBytesFromMalloc + om_Info.CurrentBytesFromValloc > om_Info.MaxBytesSbrk) |
---|
| 337 | { |
---|
| 338 | om_Info.MaxBytesSbrk = (unsigned long) sbrk(0) - om_SbrkInit; |
---|
[13fe1b] | 339 | omAssume(om_Info.MaxBytesSbrk >= om_Info.CurrentBytesFromMalloc |
---|
[e70e45] | 340 | + om_Info.CurrentBytesFromValloc); |
---|
| 341 | } |
---|
| 342 | #endif |
---|
| 343 | } |
---|
| 344 | OM_VALLOC_HOOK(size); |
---|
| 345 | return page; |
---|
| 346 | } |
---|
| 347 | |
---|
| 348 | void omVfreeToSystem(void* page, size_t size) |
---|
| 349 | { |
---|
| 350 | omAssume(omIsAddrPageAligned(page)); |
---|
| 351 | OM_VFREE_TO_SYSTEM(page, size); |
---|
| 352 | om_Info.CurrentBytesFromValloc -= size; |
---|
| 353 | OM_VFREE_HOOK(size); |
---|
| 354 | } |
---|
| 355 | |
---|
| 356 | #endif /* OM_ALLOC_SYSTEM_C */ |
---|