| 310 | |
| 311 | #if !defined(_MSC_VER) && !defined(_freebsd_) && defined(_64_) |
| 312 | static char* AllocWithMMapLinuxImpl(uintptr_t sz, EMMapMode mode) { |
| 313 | char* volatile* areaPtr; |
| 314 | char* areaStart; |
| 315 | uintptr_t areaFinish; |
| 316 | |
| 317 | int mapProt = PROT_READ | PROT_WRITE; |
| 318 | int mapFlags = MAP_PRIVATE | MAP_ANON; |
| 319 | |
| 320 | if (mode == MM_HUGE) { |
| 321 | areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointerHuge); |
| 322 | areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START + N_MAX_WORKSET_SIZE); |
| 323 | areaFinish = N_HUGE_AREA_FINISH; |
| 324 | } else { |
| 325 | areaPtr = reinterpret_cast<char* volatile*>(&linuxAllocPointer); |
| 326 | areaStart = reinterpret_cast<char*>(LINUX_MMAP_AREA_START); |
| 327 | areaFinish = N_MAX_WORKSET_SIZE; |
| 328 | |
| 329 | if (MapHugeTLB) { |
| 330 | mapFlags |= MAP_HUGETLB; |
| 331 | } |
| 332 | } |
| 333 | |
| 334 | bool wrapped = false; |
| 335 | for (;;) { |
| 336 | char* prevAllocPtr = *areaPtr; |
| 337 | char* nextAllocPtr = prevAllocPtr + sz; |
| 338 | if (uintptr_t(nextAllocPtr - (char*)nullptr) >= areaFinish) { |
| 339 | if (Y_UNLIKELY(wrapped)) { |
| 340 | NMalloc::AbortFromCorruptedAllocator("virtual memory is over fragmented"); |
| 341 | } |
| 342 | // wrap after all area is used |
| 343 | DoCas(areaPtr, areaStart, prevAllocPtr); |
| 344 | wrapped = true; |
| 345 | continue; |
| 346 | } |
| 347 | |
| 348 | if (DoCas(areaPtr, nextAllocPtr, prevAllocPtr) != prevAllocPtr) |
| 349 | continue; |
| 350 | |
| 351 | char* largeBlock = (char*)mmap(prevAllocPtr, sz, mapProt, mapFlags, -1, 0); |
| 352 | VerifyMmapResult(largeBlock); |
| 353 | if (largeBlock == prevAllocPtr) |
| 354 | return largeBlock; |
| 355 | if (largeBlock) |
| 356 | munmap(largeBlock, sz); |
| 357 | |
| 358 | if (sz < 0x80000) { |
| 359 | // skip utilized area with big steps |
| 360 | DoCas(areaPtr, nextAllocPtr + 0x10 * 0x10000, nextAllocPtr); |
| 361 | } |
| 362 | } |
| 363 | } |
| 364 | #endif |
| 365 | |
| 366 | static char* AllocWithMMap(uintptr_t sz, EMMapMode mode) { |
no test coverage detected