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
ThrowException()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>
ThrowException()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
ThrowException()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
Alloc(size_t size,size_t align)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
Free(void * p)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
AllocStack(size_t size)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
104*77b1d01eSDmitry Tsarevich size_t pageSize = systemInfo.dwPageSize;
105*77b1d01eSDmitry Tsarevich size_t pagesCount = 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
130bc48b7efSSergey Makeev int pageSize = (int)sysconf(_SC_PAGE_SIZE);
131bc48b7efSSergey 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
FreeStack(const Memory::StackDesc & desc)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
ReportAssert(const char * condition,const char * description,const char * sourceFile,int sourceLine)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