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 #endif 3102d170cfSs.makeev_local 3202d170cfSs.makeev_local 3302d170cfSs.makeev_local 3402d170cfSs.makeev_local 3502d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 3602d170cfSs.makeev_local 3702d170cfSs.makeev_local inline void ThrowException() 3802d170cfSs.makeev_local { 3902d170cfSs.makeev_local __debugbreak(); 4002d170cfSs.makeev_local } 4102d170cfSs.makeev_local 42e70b6ec6Ss.makeev_local #elif MT_PLATFORM_POSIX 4302d170cfSs.makeev_local 4402d170cfSs.makeev_local #include<signal.h> 4502d170cfSs.makeev_local inline void ThrowException() 4602d170cfSs.makeev_local { 4702d170cfSs.makeev_local raise(SIGTRAP); 4802d170cfSs.makeev_local // force access violation error 4902d170cfSs.makeev_local char* pBadAddr = (char*)0x0; 5002d170cfSs.makeev_local *pBadAddr = 0; 5102d170cfSs.makeev_local } 5202d170cfSs.makeev_local 53e70b6ec6Ss.makeev_local #elif MT_PLATFORM_OSX 54e70b6ec6Ss.makeev_local 55e70b6ec6Ss.makeev_local inline void ThrowException() 56e70b6ec6Ss.makeev_local { 57e70b6ec6Ss.makeev_local __builtin_trap(); 58e70b6ec6Ss.makeev_local } 59e70b6ec6Ss.makeev_local 6002d170cfSs.makeev_local #else 6102d170cfSs.makeev_local 6202d170cfSs.makeev_local #error Platform is not supported! 6302d170cfSs.makeev_local 6402d170cfSs.makeev_local #endif 6502d170cfSs.makeev_local 6602d170cfSs.makeev_local 6702d170cfSs.makeev_local 6802d170cfSs.makeev_local namespace MT 6902d170cfSs.makeev_local { 7002d170cfSs.makeev_local 7102d170cfSs.makeev_local void* Memory::Alloc(size_t size, size_t align) 7202d170cfSs.makeev_local { 7302d170cfSs.makeev_local void* p = nullptr; 7402d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 7502d170cfSs.makeev_local p = _mm_malloc(size, align); 7602d170cfSs.makeev_local #else 77b4633345SSergey Makeev if (posix_memalign(&p, size, align) != 0) 78b4633345SSergey Makeev { 79b4633345SSergey Makeev p = nullptr; 80b4633345SSergey Makeev } 8102d170cfSs.makeev_local #endif 8202d170cfSs.makeev_local MT_ASSERT(p, "Can't allocate memory"); 8302d170cfSs.makeev_local return p; 8402d170cfSs.makeev_local } 8502d170cfSs.makeev_local 8602d170cfSs.makeev_local void Memory::Free(void* p) 8702d170cfSs.makeev_local { 8802d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 8902d170cfSs.makeev_local _mm_free(p); 9002d170cfSs.makeev_local #else 9102d170cfSs.makeev_local free(p); 9202d170cfSs.makeev_local #endif 9302d170cfSs.makeev_local } 9402d170cfSs.makeev_local 9502d170cfSs.makeev_local Memory::StackDesc Memory::AllocStack(size_t size) 9602d170cfSs.makeev_local { 9702d170cfSs.makeev_local StackDesc desc; 9802d170cfSs.makeev_local 9902d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 10002d170cfSs.makeev_local 10102d170cfSs.makeev_local MW_SYSTEM_INFO systemInfo; 10202d170cfSs.makeev_local GetSystemInfo(&systemInfo); 10302d170cfSs.makeev_local 10402d170cfSs.makeev_local int pageSize = (int)systemInfo.dwPageSize; 10502d170cfSs.makeev_local int pagesCount = (int)size / pageSize; 10602d170cfSs.makeev_local 10702d170cfSs.makeev_local //need additional page for stack guard 10802d170cfSs.makeev_local if ((size % pageSize) > 0) 10902d170cfSs.makeev_local { 11002d170cfSs.makeev_local pagesCount++; 11102d170cfSs.makeev_local } 11202d170cfSs.makeev_local 11302d170cfSs.makeev_local //protected guard page 11402d170cfSs.makeev_local pagesCount++; 11502d170cfSs.makeev_local 11602d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 11702d170cfSs.makeev_local desc.stackMemory = (char*)VirtualAlloc(NULL, desc.stackMemoryBytesCount, MW_MEM_COMMIT, MW_PAGE_READWRITE); 11802d170cfSs.makeev_local MT_ASSERT(desc.stackMemory != NULL, "Can't allocate memory"); 11902d170cfSs.makeev_local 12002d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 12102d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 12202d170cfSs.makeev_local 12302d170cfSs.makeev_local MW_DWORD oldProtect = 0; 12402d170cfSs.makeev_local MW_BOOL res = VirtualProtect(desc.stackMemory, pageSize, MW_PAGE_NOACCESS, &oldProtect); 12502d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 12602d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't protect memory"); 12702d170cfSs.makeev_local 12802d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 12902d170cfSs.makeev_local 130*bc48b7efSSergey Makeev int pageSize = (int)sysconf(_SC_PAGE_SIZE); 131*bc48b7efSSergey Makeev int pagesCount = (int)(size / pageSize); 13202d170cfSs.makeev_local 13302d170cfSs.makeev_local //need additional page for stack tail 13402d170cfSs.makeev_local if ((size % pageSize) > 0) 13502d170cfSs.makeev_local { 13602d170cfSs.makeev_local pagesCount++; 13702d170cfSs.makeev_local } 13802d170cfSs.makeev_local 13902d170cfSs.makeev_local //protected guard page 14002d170cfSs.makeev_local pagesCount++; 14102d170cfSs.makeev_local 14202d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 14302d170cfSs.makeev_local desc.stackMemory = (char*)mmap(NULL, desc.stackMemoryBytesCount, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); 14402d170cfSs.makeev_local 14502d170cfSs.makeev_local MT_ASSERT((void *)desc.stackMemory != (void *)-1, "Can't allocate memory"); 14602d170cfSs.makeev_local 14702d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 14802d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 14902d170cfSs.makeev_local 15002d170cfSs.makeev_local int res = mprotect(desc.stackMemory, pageSize, PROT_NONE); 15102d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 15202d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't protect memory"); 15302d170cfSs.makeev_local #else 15402d170cfSs.makeev_local #error Platform is not supported! 15502d170cfSs.makeev_local #endif 15602d170cfSs.makeev_local 15702d170cfSs.makeev_local return desc; 15802d170cfSs.makeev_local } 15902d170cfSs.makeev_local 16002d170cfSs.makeev_local void Memory::FreeStack(const Memory::StackDesc & desc) 16102d170cfSs.makeev_local { 16202d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 16302d170cfSs.makeev_local 16402d170cfSs.makeev_local int res = VirtualFree(desc.stackMemory, 0, MW_MEM_RELEASE); 16502d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 16602d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't free memory"); 16702d170cfSs.makeev_local 16802d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 16902d170cfSs.makeev_local 17002d170cfSs.makeev_local int res = munmap(desc.stackMemory, desc.stackMemoryBytesCount); 17102d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 17202d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't free memory"); 17302d170cfSs.makeev_local #else 17402d170cfSs.makeev_local #error Platform is not supported! 17502d170cfSs.makeev_local #endif 17602d170cfSs.makeev_local } 17702d170cfSs.makeev_local 17802d170cfSs.makeev_local void Diagnostic::ReportAssert(const char* condition, const char* description, const char* sourceFile, int sourceLine) 17902d170cfSs.makeev_local { 18002d170cfSs.makeev_local printf("Assertion failed : %s. File %s, line %d. Condition %s\n", description, sourceFile, sourceLine, condition); 18102d170cfSs.makeev_local ThrowException(); 18202d170cfSs.makeev_local } 18302d170cfSs.makeev_local 18402d170cfSs.makeev_local 18502d170cfSs.makeev_local 18602d170cfSs.makeev_local 18702d170cfSs.makeev_local } 188