102d170cfSs.makeev_local // The MIT License (MIT) 202d170cfSs.makeev_local // 302d170cfSs.makeev_local // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 402d170cfSs.makeev_local // 502d170cfSs.makeev_local // Permission is hereby granted, free of charge, to any person obtaining a copy 602d170cfSs.makeev_local // of this software and associated documentation files (the "Software"), to deal 702d170cfSs.makeev_local // in the Software without restriction, including without limitation the rights 802d170cfSs.makeev_local // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 902d170cfSs.makeev_local // copies of the Software, and to permit persons to whom the Software is 1002d170cfSs.makeev_local // furnished to do so, subject to the following conditions: 1102d170cfSs.makeev_local // 1202d170cfSs.makeev_local // The above copyright notice and this permission notice shall be included in 1302d170cfSs.makeev_local // all copies or substantial portions of the Software. 1402d170cfSs.makeev_local // 1502d170cfSs.makeev_local // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 1602d170cfSs.makeev_local // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 1702d170cfSs.makeev_local // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 1802d170cfSs.makeev_local // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 1902d170cfSs.makeev_local // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 2002d170cfSs.makeev_local // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 2102d170cfSs.makeev_local // THE SOFTWARE. 2202d170cfSs.makeev_local #include <MTConfig.h> 2302d170cfSs.makeev_local #include <MTAppInterop.h> 2402d170cfSs.makeev_local #include <MTTools.h> 2502d170cfSs.makeev_local 2602d170cfSs.makeev_local #include <stdio.h> 2702d170cfSs.makeev_local 2802d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 2902d170cfSs.makeev_local #include <xmmintrin.h> 3002d170cfSs.makeev_local #else 3102d170cfSs.makeev_local #include <malloc.h> 3202d170cfSs.makeev_local #endif 3302d170cfSs.makeev_local 3402d170cfSs.makeev_local 3502d170cfSs.makeev_local 3602d170cfSs.makeev_local 3702d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 3802d170cfSs.makeev_local 3902d170cfSs.makeev_local inline void ThrowException() 4002d170cfSs.makeev_local { 4102d170cfSs.makeev_local __debugbreak(); 4202d170cfSs.makeev_local } 4302d170cfSs.makeev_local 44*e70b6ec6Ss.makeev_local #elif MT_PLATFORM_POSIX 4502d170cfSs.makeev_local 4602d170cfSs.makeev_local #include<signal.h> 4702d170cfSs.makeev_local inline void ThrowException() 4802d170cfSs.makeev_local { 4902d170cfSs.makeev_local raise(SIGTRAP); 5002d170cfSs.makeev_local // force access violation error 5102d170cfSs.makeev_local char* pBadAddr = (char*)0x0; 5202d170cfSs.makeev_local *pBadAddr = 0; 5302d170cfSs.makeev_local } 5402d170cfSs.makeev_local 55*e70b6ec6Ss.makeev_local #elif MT_PLATFORM_OSX 56*e70b6ec6Ss.makeev_local 57*e70b6ec6Ss.makeev_local inline void ThrowException() 58*e70b6ec6Ss.makeev_local { 59*e70b6ec6Ss.makeev_local __builtin_trap(); 60*e70b6ec6Ss.makeev_local } 61*e70b6ec6Ss.makeev_local 6202d170cfSs.makeev_local #else 6302d170cfSs.makeev_local 6402d170cfSs.makeev_local #error Platform is not supported! 6502d170cfSs.makeev_local 6602d170cfSs.makeev_local #endif 6702d170cfSs.makeev_local 6802d170cfSs.makeev_local 6902d170cfSs.makeev_local 7002d170cfSs.makeev_local namespace MT 7102d170cfSs.makeev_local { 7202d170cfSs.makeev_local 7302d170cfSs.makeev_local void* Memory::Alloc(size_t size, size_t align) 7402d170cfSs.makeev_local { 7502d170cfSs.makeev_local void* p = nullptr; 7602d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 7702d170cfSs.makeev_local p = _mm_malloc(size, align); 7802d170cfSs.makeev_local #else 7902d170cfSs.makeev_local p = memalign(size, align); 8002d170cfSs.makeev_local #endif 8102d170cfSs.makeev_local MT_ASSERT(p, "Can't allocate memory"); 8202d170cfSs.makeev_local return p; 8302d170cfSs.makeev_local } 8402d170cfSs.makeev_local 8502d170cfSs.makeev_local void Memory::Free(void* p) 8602d170cfSs.makeev_local { 8702d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 8802d170cfSs.makeev_local _mm_free(p); 8902d170cfSs.makeev_local #else 9002d170cfSs.makeev_local free(p); 9102d170cfSs.makeev_local #endif 9202d170cfSs.makeev_local } 9302d170cfSs.makeev_local 9402d170cfSs.makeev_local Memory::StackDesc Memory::AllocStack(size_t size) 9502d170cfSs.makeev_local { 9602d170cfSs.makeev_local StackDesc desc; 9702d170cfSs.makeev_local 9802d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 9902d170cfSs.makeev_local 10002d170cfSs.makeev_local MW_SYSTEM_INFO systemInfo; 10102d170cfSs.makeev_local GetSystemInfo(&systemInfo); 10202d170cfSs.makeev_local 10302d170cfSs.makeev_local int pageSize = (int)systemInfo.dwPageSize; 10402d170cfSs.makeev_local int pagesCount = (int)size / pageSize; 10502d170cfSs.makeev_local 10602d170cfSs.makeev_local //need additional page for stack guard 10702d170cfSs.makeev_local if ((size % pageSize) > 0) 10802d170cfSs.makeev_local { 10902d170cfSs.makeev_local pagesCount++; 11002d170cfSs.makeev_local } 11102d170cfSs.makeev_local 11202d170cfSs.makeev_local //protected guard page 11302d170cfSs.makeev_local pagesCount++; 11402d170cfSs.makeev_local 11502d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 11602d170cfSs.makeev_local desc.stackMemory = (char*)VirtualAlloc(NULL, desc.stackMemoryBytesCount, MW_MEM_COMMIT, MW_PAGE_READWRITE); 11702d170cfSs.makeev_local MT_ASSERT(desc.stackMemory != NULL, "Can't allocate memory"); 11802d170cfSs.makeev_local 11902d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 12002d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 12102d170cfSs.makeev_local 12202d170cfSs.makeev_local MW_DWORD oldProtect = 0; 12302d170cfSs.makeev_local MW_BOOL res = VirtualProtect(desc.stackMemory, pageSize, MW_PAGE_NOACCESS, &oldProtect); 12402d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 12502d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't protect memory"); 12602d170cfSs.makeev_local 12702d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 12802d170cfSs.makeev_local 12902d170cfSs.makeev_local int pageSize = sysconf(_SC_PAGE_SIZE); 13002d170cfSs.makeev_local int pagesCount = size / pageSize; 13102d170cfSs.makeev_local 13202d170cfSs.makeev_local //need additional page for stack tail 13302d170cfSs.makeev_local if ((size % pageSize) > 0) 13402d170cfSs.makeev_local { 13502d170cfSs.makeev_local pagesCount++; 13602d170cfSs.makeev_local } 13702d170cfSs.makeev_local 13802d170cfSs.makeev_local //protected guard page 13902d170cfSs.makeev_local pagesCount++; 14002d170cfSs.makeev_local 14102d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 14202d170cfSs.makeev_local desc.stackMemory = (char*)mmap(NULL, desc.stackMemoryBytesCount, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); 14302d170cfSs.makeev_local 14402d170cfSs.makeev_local MT_ASSERT((void *)desc.stackMemory != (void *)-1, "Can't allocate memory"); 14502d170cfSs.makeev_local 14602d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 14702d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 14802d170cfSs.makeev_local 14902d170cfSs.makeev_local int res = mprotect(desc.stackMemory, pageSize, PROT_NONE); 15002d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 15102d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't protect memory"); 15202d170cfSs.makeev_local #else 15302d170cfSs.makeev_local #error Platform is not supported! 15402d170cfSs.makeev_local #endif 15502d170cfSs.makeev_local 15602d170cfSs.makeev_local return desc; 15702d170cfSs.makeev_local } 15802d170cfSs.makeev_local 15902d170cfSs.makeev_local void Memory::FreeStack(const Memory::StackDesc & desc) 16002d170cfSs.makeev_local { 16102d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 16202d170cfSs.makeev_local 16302d170cfSs.makeev_local int res = VirtualFree(desc.stackMemory, 0, MW_MEM_RELEASE); 16402d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 16502d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't free memory"); 16602d170cfSs.makeev_local 16702d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 16802d170cfSs.makeev_local 16902d170cfSs.makeev_local int res = munmap(desc.stackMemory, desc.stackMemoryBytesCount); 17002d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 17102d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't free memory"); 17202d170cfSs.makeev_local #else 17302d170cfSs.makeev_local #error Platform is not supported! 17402d170cfSs.makeev_local #endif 17502d170cfSs.makeev_local } 17602d170cfSs.makeev_local 17702d170cfSs.makeev_local void Diagnostic::ReportAssert(const char* condition, const char* description, const char* sourceFile, int sourceLine) 17802d170cfSs.makeev_local { 17902d170cfSs.makeev_local printf("Assertion failed : %s. File %s, line %d. Condition %s\n", description, sourceFile, sourceLine, condition); 18002d170cfSs.makeev_local ThrowException(); 18102d170cfSs.makeev_local } 18202d170cfSs.makeev_local 18302d170cfSs.makeev_local 18402d170cfSs.makeev_local 18502d170cfSs.makeev_local 18602d170cfSs.makeev_local } 187