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