blob: 93ae3255c3b9048a6d026e5a098419eee65a281f [file] [log] [blame]
/*-------------------------------------------------------------------------
* drawElements Base Portability Library
* -------------------------------------
*
* Copyright 2014 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*//*!
* \file
* \brief Memory management.
*//*--------------------------------------------------------------------*/
#include "deMemory.h"
#include "deInt32.h"
#include <stdio.h>
#include <assert.h>
#include <stdlib.h>
#include <string.h>
#if defined(DE_VALGRIND_BUILD)
# include <valgrind/valgrind.h>
# if defined(HAVE_VALGRIND_MEMCHECK_H)
# include <valgrind/memcheck.h>
# endif
#endif
DE_BEGIN_EXTERN_C
/*--------------------------------------------------------------------*//*!
* \brief Allocate a chunk of memory.
* \param numBytes Number of bytes to allocate.
* \return Pointer to the allocated memory (or null on failure).
*//*--------------------------------------------------------------------*/
void* deMalloc (int numBytes)
{
void* ptr;
DE_ASSERT(numBytes > 0);
ptr = malloc((size_t)numBytes);
#if defined(DE_DEBUG)
/* Trash memory in debug builds (if under Valgrind, don't make it think we're initializing data here). */
if (ptr)
memset(ptr, 0xcd, numBytes);
#if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
if (ptr && RUNNING_ON_VALGRIND)
{
VALGRIND_MAKE_MEM_UNDEFINED(ptr, numBytes);
}
#endif
#endif
return ptr;
}
/*--------------------------------------------------------------------*//*!
* \brief Allocate a chunk of memory and initialize it to zero.
* \param numBytes Number of bytes to allocate.
* \return Pointer to the allocated memory (or null on failure).
*//*--------------------------------------------------------------------*/
void* deCalloc (int numBytes)
{
void* ptr = deMalloc(numBytes);
if (ptr)
deMemset(ptr, 0, numBytes);
return ptr;
}
void* deAlignedMalloc (int numBytes, int alignBytes)
{
int ptrSize = sizeof(void*);
deUintptr origPtr = (deUintptr)deMalloc(numBytes + ptrSize + alignBytes);
if (origPtr)
{
deUintptr alignedPtr = (deUintptr)deAlignPtr((void*)(origPtr + ptrSize), alignBytes);
deUintptr ptrPtr = (alignedPtr - ptrSize);
DE_ASSERT(deInRange32(alignBytes, 0, 256) && deIsPowerOfTwo32(alignBytes));
*(deUintptr*)ptrPtr = origPtr;
return (void*)alignedPtr;
}
else
return DE_NULL;
}
/*--------------------------------------------------------------------*//*!
* \brief Reallocate a chunk of memory.
* \param ptr Pointer to previously allocated memory block
* \param numBytes New size in bytes
* \return Pointer to the reallocated (and possibly moved) memory block
*//*--------------------------------------------------------------------*/
void* deRealloc (void* ptr, int numBytes)
{
return realloc(ptr, (size_t)numBytes);
}
/*--------------------------------------------------------------------*//*!
* \brief Free a chunk of memory.
* \param ptr Pointer to memory to free.
*//*--------------------------------------------------------------------*/
void deFree (void* ptr)
{
free(ptr);
}
void deAlignedFree (void* ptr)
{
if (ptr)
{
int ptrSize = sizeof(void*);
deUintptr ptrPtr = (deUintptr)ptr - ptrSize;
deUintptr origPtr = *(deUintptr*)ptrPtr;
DE_ASSERT(ptrPtr - origPtr < 256);
deFree((void*)origPtr);
}
}
char* deStrdup (const char* str)
{
#if (DE_COMPILER == DE_COMPILER_MSC)
return _strdup(str);
#elif (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS)
/* For some reason Steve doesn't like stdrup(). */
size_t len = strlen(str);
char* copy = malloc(len+1);
memcpy(copy, str, len);
copy[len] = 0;
return copy;
#else
return strdup(str);
#endif
}
DE_END_EXTERN_C