1*02d170cfSs.makeev_local // The MIT License (MIT) 2*02d170cfSs.makeev_local // 3*02d170cfSs.makeev_local // Copyright (c) 2015 Sergey Makeev, Vadim Slyusarev 4*02d170cfSs.makeev_local // 5*02d170cfSs.makeev_local // Permission is hereby granted, free of charge, to any person obtaining a copy 6*02d170cfSs.makeev_local // of this software and associated documentation files (the "Software"), to deal 7*02d170cfSs.makeev_local // in the Software without restriction, including without limitation the rights 8*02d170cfSs.makeev_local // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9*02d170cfSs.makeev_local // copies of the Software, and to permit persons to whom the Software is 10*02d170cfSs.makeev_local // furnished to do so, subject to the following conditions: 11*02d170cfSs.makeev_local // 12*02d170cfSs.makeev_local // The above copyright notice and this permission notice shall be included in 13*02d170cfSs.makeev_local // all copies or substantial portions of the Software. 14*02d170cfSs.makeev_local // 15*02d170cfSs.makeev_local // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16*02d170cfSs.makeev_local // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17*02d170cfSs.makeev_local // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18*02d170cfSs.makeev_local // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19*02d170cfSs.makeev_local // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20*02d170cfSs.makeev_local // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21*02d170cfSs.makeev_local // THE SOFTWARE. 22*02d170cfSs.makeev_local #include <MTConfig.h> 23*02d170cfSs.makeev_local #include <MTAppInterop.h> 24*02d170cfSs.makeev_local #include <MTTools.h> 25*02d170cfSs.makeev_local 26*02d170cfSs.makeev_local #include <stdio.h> 27*02d170cfSs.makeev_local 28*02d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 29*02d170cfSs.makeev_local #include <xmmintrin.h> 30*02d170cfSs.makeev_local #else 31*02d170cfSs.makeev_local #include <malloc.h> 32*02d170cfSs.makeev_local #endif 33*02d170cfSs.makeev_local 34*02d170cfSs.makeev_local 35*02d170cfSs.makeev_local 36*02d170cfSs.makeev_local 37*02d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 38*02d170cfSs.makeev_local 39*02d170cfSs.makeev_local inline void ThrowException() 40*02d170cfSs.makeev_local { 41*02d170cfSs.makeev_local __debugbreak(); 42*02d170cfSs.makeev_local } 43*02d170cfSs.makeev_local 44*02d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 45*02d170cfSs.makeev_local 46*02d170cfSs.makeev_local #include<signal.h> 47*02d170cfSs.makeev_local inline void ThrowException() 48*02d170cfSs.makeev_local { 49*02d170cfSs.makeev_local raise(SIGTRAP); 50*02d170cfSs.makeev_local // force access violation error 51*02d170cfSs.makeev_local char* pBadAddr = (char*)0x0; 52*02d170cfSs.makeev_local *pBadAddr = 0; 53*02d170cfSs.makeev_local } 54*02d170cfSs.makeev_local 55*02d170cfSs.makeev_local #else 56*02d170cfSs.makeev_local 57*02d170cfSs.makeev_local #error Platform is not supported! 58*02d170cfSs.makeev_local 59*02d170cfSs.makeev_local #endif 60*02d170cfSs.makeev_local 61*02d170cfSs.makeev_local 62*02d170cfSs.makeev_local 63*02d170cfSs.makeev_local namespace MT 64*02d170cfSs.makeev_local { 65*02d170cfSs.makeev_local 66*02d170cfSs.makeev_local void* Memory::Alloc(size_t size, size_t align) 67*02d170cfSs.makeev_local { 68*02d170cfSs.makeev_local void* p = nullptr; 69*02d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 70*02d170cfSs.makeev_local p = _mm_malloc(size, align); 71*02d170cfSs.makeev_local #else 72*02d170cfSs.makeev_local p = memalign(size, align); 73*02d170cfSs.makeev_local #endif 74*02d170cfSs.makeev_local MT_ASSERT(p, "Can't allocate memory"); 75*02d170cfSs.makeev_local return p; 76*02d170cfSs.makeev_local } 77*02d170cfSs.makeev_local 78*02d170cfSs.makeev_local void Memory::Free(void* p) 79*02d170cfSs.makeev_local { 80*02d170cfSs.makeev_local #if MT_SSE_INTRINSICS_SUPPORTED 81*02d170cfSs.makeev_local _mm_free(p); 82*02d170cfSs.makeev_local #else 83*02d170cfSs.makeev_local free(p); 84*02d170cfSs.makeev_local #endif 85*02d170cfSs.makeev_local } 86*02d170cfSs.makeev_local 87*02d170cfSs.makeev_local Memory::StackDesc Memory::AllocStack(size_t size) 88*02d170cfSs.makeev_local { 89*02d170cfSs.makeev_local StackDesc desc; 90*02d170cfSs.makeev_local 91*02d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 92*02d170cfSs.makeev_local 93*02d170cfSs.makeev_local MW_SYSTEM_INFO systemInfo; 94*02d170cfSs.makeev_local GetSystemInfo(&systemInfo); 95*02d170cfSs.makeev_local 96*02d170cfSs.makeev_local int pageSize = (int)systemInfo.dwPageSize; 97*02d170cfSs.makeev_local int pagesCount = (int)size / pageSize; 98*02d170cfSs.makeev_local 99*02d170cfSs.makeev_local //need additional page for stack guard 100*02d170cfSs.makeev_local if ((size % pageSize) > 0) 101*02d170cfSs.makeev_local { 102*02d170cfSs.makeev_local pagesCount++; 103*02d170cfSs.makeev_local } 104*02d170cfSs.makeev_local 105*02d170cfSs.makeev_local //protected guard page 106*02d170cfSs.makeev_local pagesCount++; 107*02d170cfSs.makeev_local 108*02d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 109*02d170cfSs.makeev_local desc.stackMemory = (char*)VirtualAlloc(NULL, desc.stackMemoryBytesCount, MW_MEM_COMMIT, MW_PAGE_READWRITE); 110*02d170cfSs.makeev_local MT_ASSERT(desc.stackMemory != NULL, "Can't allocate memory"); 111*02d170cfSs.makeev_local 112*02d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 113*02d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 114*02d170cfSs.makeev_local 115*02d170cfSs.makeev_local MW_DWORD oldProtect = 0; 116*02d170cfSs.makeev_local MW_BOOL res = VirtualProtect(desc.stackMemory, pageSize, MW_PAGE_NOACCESS, &oldProtect); 117*02d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 118*02d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't protect memory"); 119*02d170cfSs.makeev_local 120*02d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 121*02d170cfSs.makeev_local 122*02d170cfSs.makeev_local int pageSize = sysconf(_SC_PAGE_SIZE); 123*02d170cfSs.makeev_local int pagesCount = size / pageSize; 124*02d170cfSs.makeev_local 125*02d170cfSs.makeev_local //need additional page for stack tail 126*02d170cfSs.makeev_local if ((size % pageSize) > 0) 127*02d170cfSs.makeev_local { 128*02d170cfSs.makeev_local pagesCount++; 129*02d170cfSs.makeev_local } 130*02d170cfSs.makeev_local 131*02d170cfSs.makeev_local //protected guard page 132*02d170cfSs.makeev_local pagesCount++; 133*02d170cfSs.makeev_local 134*02d170cfSs.makeev_local desc.stackMemoryBytesCount = pagesCount * pageSize; 135*02d170cfSs.makeev_local desc.stackMemory = (char*)mmap(NULL, desc.stackMemoryBytesCount, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS | MAP_STACK, -1, 0); 136*02d170cfSs.makeev_local 137*02d170cfSs.makeev_local MT_ASSERT((void *)desc.stackMemory != (void *)-1, "Can't allocate memory"); 138*02d170cfSs.makeev_local 139*02d170cfSs.makeev_local desc.stackBottom = desc.stackMemory + pageSize; 140*02d170cfSs.makeev_local desc.stackTop = desc.stackMemory + desc.stackMemoryBytesCount; 141*02d170cfSs.makeev_local 142*02d170cfSs.makeev_local int res = mprotect(desc.stackMemory, pageSize, PROT_NONE); 143*02d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 144*02d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't protect memory"); 145*02d170cfSs.makeev_local #else 146*02d170cfSs.makeev_local #error Platform is not supported! 147*02d170cfSs.makeev_local #endif 148*02d170cfSs.makeev_local 149*02d170cfSs.makeev_local return desc; 150*02d170cfSs.makeev_local } 151*02d170cfSs.makeev_local 152*02d170cfSs.makeev_local void Memory::FreeStack(const Memory::StackDesc & desc) 153*02d170cfSs.makeev_local { 154*02d170cfSs.makeev_local #if MT_PLATFORM_WINDOWS 155*02d170cfSs.makeev_local 156*02d170cfSs.makeev_local int res = VirtualFree(desc.stackMemory, 0, MW_MEM_RELEASE); 157*02d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 158*02d170cfSs.makeev_local MT_ASSERT(res != 0, "Can't free memory"); 159*02d170cfSs.makeev_local 160*02d170cfSs.makeev_local #elif MT_PLATFORM_POSIX || MT_PLATFORM_OSX 161*02d170cfSs.makeev_local 162*02d170cfSs.makeev_local int res = munmap(desc.stackMemory, desc.stackMemoryBytesCount); 163*02d170cfSs.makeev_local MT_USED_IN_ASSERT(res); 164*02d170cfSs.makeev_local MT_ASSERT(res == 0, "Can't free memory"); 165*02d170cfSs.makeev_local #else 166*02d170cfSs.makeev_local #error Platform is not supported! 167*02d170cfSs.makeev_local #endif 168*02d170cfSs.makeev_local } 169*02d170cfSs.makeev_local 170*02d170cfSs.makeev_local void Diagnostic::ReportAssert(const char* condition, const char* description, const char* sourceFile, int sourceLine) 171*02d170cfSs.makeev_local { 172*02d170cfSs.makeev_local printf("Assertion failed : %s. File %s, line %d. Condition %s\n", description, sourceFile, sourceLine, condition); 173*02d170cfSs.makeev_local ThrowException(); 174*02d170cfSs.makeev_local } 175*02d170cfSs.makeev_local 176*02d170cfSs.makeev_local 177*02d170cfSs.makeev_local 178*02d170cfSs.makeev_local 179*02d170cfSs.makeev_local } 180