nuclear@0: /************************************************************************************ nuclear@0: nuclear@0: Filename : OVR_Allocator.cpp nuclear@0: Content : Installable memory allocator implementation nuclear@0: Created : September 19, 2012 nuclear@0: Notes : nuclear@0: nuclear@0: Copyright : Copyright 2014 Oculus VR, LLC All Rights reserved. nuclear@0: nuclear@0: Licensed under the Oculus VR Rift SDK License Version 3.2 (the "License"); nuclear@0: you may not use the Oculus VR Rift SDK except in compliance with the License, nuclear@0: which is provided at the time of installation or download, or which nuclear@0: otherwise accompanies this software in either electronic or hard copy form. nuclear@0: nuclear@0: You may obtain a copy of the License at nuclear@0: nuclear@0: http://www.oculusvr.com/licenses/LICENSE-3.2 nuclear@0: nuclear@0: Unless required by applicable law or agreed to in writing, the Oculus VR SDK nuclear@0: distributed under the License is distributed on an "AS IS" BASIS, nuclear@0: WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. nuclear@0: See the License for the specific language governing permissions and nuclear@0: limitations under the License. nuclear@0: nuclear@0: ************************************************************************************/ nuclear@0: nuclear@0: #include "OVR_Allocator.h" nuclear@0: #ifdef OVR_OS_MAC nuclear@0: #include nuclear@0: #else nuclear@0: #include nuclear@0: #endif nuclear@0: nuclear@0: #if defined(OVR_OS_MS) nuclear@0: #include nuclear@0: #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) nuclear@0: #include nuclear@0: #include nuclear@0: #endif nuclear@0: nuclear@0: nuclear@0: namespace OVR { nuclear@0: nuclear@0: //----------------------------------------------------------------------------------- nuclear@0: // ***** Allocator nuclear@0: nuclear@0: Allocator* Allocator::pInstance = 0; nuclear@0: nuclear@0: // Default AlignedAlloc implementation will delegate to Alloc/Free after doing rounding. nuclear@0: void* Allocator::AllocAligned(size_t size, size_t align) nuclear@0: { nuclear@0: OVR_ASSERT((align & (align-1)) == 0); nuclear@0: align = (align > sizeof(size_t)) ? align : sizeof(size_t); nuclear@0: size_t p = (size_t)Alloc(size+align); nuclear@0: size_t aligned = 0; nuclear@0: if (p) nuclear@0: { nuclear@0: aligned = (size_t(p) + align-1) & ~(align-1); nuclear@0: if (aligned == p) nuclear@0: aligned += align; nuclear@0: *(((size_t*)aligned)-1) = aligned-p; nuclear@0: } nuclear@0: return (void*)aligned; nuclear@0: } nuclear@0: nuclear@0: void Allocator::FreeAligned(void* p) nuclear@0: { nuclear@0: size_t src = size_t(p) - *(((size_t*)p)-1); nuclear@0: Free((void*)src); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: //------------------------------------------------------------------------ nuclear@0: // ***** Default Allocator nuclear@0: nuclear@0: // This allocator is created and used if no other allocator is installed. nuclear@0: // Default allocator delegates to system malloc. nuclear@0: nuclear@0: void* DefaultAllocator::Alloc(size_t size) nuclear@0: { nuclear@0: return malloc(size); nuclear@0: } nuclear@0: void* DefaultAllocator::AllocDebug(size_t size, const char* file, unsigned line) nuclear@0: { nuclear@0: OVR_UNUSED2(file, line); // should be here for debugopt config nuclear@0: #if defined(OVR_CC_MSVC) && defined(_CRTDBG_MAP_ALLOC) nuclear@0: return _malloc_dbg(size, _NORMAL_BLOCK, file, line); nuclear@0: #else nuclear@0: return malloc(size); nuclear@0: #endif nuclear@0: } nuclear@0: nuclear@0: void* DefaultAllocator::Realloc(void* p, size_t newSize) nuclear@0: { nuclear@0: return realloc(p, newSize); nuclear@0: } nuclear@0: void DefaultAllocator::Free(void *p) nuclear@0: { nuclear@0: return free(p); nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: void* MMapAlloc(size_t size) nuclear@0: { nuclear@0: #if defined(OVR_OS_MS) nuclear@0: return VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); // size is rounded up to a page. // Returned memory is 0-filled. nuclear@0: nuclear@0: #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) nuclear@0: #if !defined(MAP_FAILED) nuclear@0: #define MAP_FAILED ((void*)-1) nuclear@0: #endif nuclear@0: nuclear@0: void* result = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); // Returned memory is 0-filled. nuclear@0: if(result == MAP_FAILED) // mmap returns MAP_FAILED (-1) upon failure. nuclear@0: result = NULL; nuclear@0: return result; nuclear@0: #endif nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: void MMapFree(void* memory, size_t size) nuclear@0: { nuclear@0: #if defined(OVR_OS_MS) nuclear@0: OVR_UNUSED(size); nuclear@0: VirtualFree(memory, 0, MEM_RELEASE); nuclear@0: nuclear@0: #elif defined(OVR_OS_MAC) || defined(OVR_OS_UNIX) nuclear@0: size_t pageSize = getpagesize(); nuclear@0: size = (((size + (pageSize - 1)) / pageSize) * pageSize); nuclear@0: munmap(memory, size); // Must supply the size to munmap. nuclear@0: #endif nuclear@0: } nuclear@0: nuclear@0: nuclear@0: nuclear@0: nuclear@0: } // OVR