1 /*-------------------------------------------------------------------------
2  * drawElements Base Portability Library
3  * -------------------------------------
4  *
5  * Copyright 2014 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  *//*!
20  * \file
21  * \brief Memory management.
22  *//*--------------------------------------------------------------------*/
23 
24 #include "deMemory.h"
25 #include "deInt32.h"
26 
27 #include <stdio.h>
28 #include <assert.h>
29 #include <stdlib.h>
30 #include <string.h>
31 
32 #if defined(DE_VALGRIND_BUILD)
33 #	include <valgrind/valgrind.h>
34 #	if defined(HAVE_VALGRIND_MEMCHECK_H)
35 #		include <valgrind/memcheck.h>
36 #	endif
37 #endif
38 
39 DE_BEGIN_EXTERN_C
40 
41 /*--------------------------------------------------------------------*//*!
42  * \brief Allocate a chunk of memory.
43  * \param numBytes	Number of bytes to allocate.
44  * \return Pointer to the allocated memory (or null on failure).
45  *//*--------------------------------------------------------------------*/
deMalloc(int numBytes)46 void* deMalloc (int numBytes)
47 {
48 	void* ptr;
49 
50 	DE_ASSERT(numBytes > 0);
51 
52 	ptr = malloc((size_t)numBytes);
53 
54 #if defined(DE_DEBUG)
55 	/* Trash memory in debug builds (if under Valgrind, don't make it think we're initializing data here). */
56 
57 	if (ptr)
58 		memset(ptr, 0xcd, numBytes);
59 
60 #if defined(DE_VALGRIND_BUILD) && defined(HAVE_VALGRIND_MEMCHECK_H)
61 	if (ptr && RUNNING_ON_VALGRIND)
62 	{
63 		VALGRIND_MAKE_MEM_UNDEFINED(ptr, numBytes);
64 	}
65 #endif
66 #endif
67 
68 	return ptr;
69 }
70 
71 /*--------------------------------------------------------------------*//*!
72  * \brief Allocate a chunk of memory and initialize it to zero.
73  * \param numBytes	Number of bytes to allocate.
74  * \return Pointer to the allocated memory (or null on failure).
75  *//*--------------------------------------------------------------------*/
deCalloc(int numBytes)76 void* deCalloc (int numBytes)
77 {
78 	void* ptr = deMalloc(numBytes);
79 	if (ptr)
80 		deMemset(ptr, 0, numBytes);
81 	return ptr;
82 }
83 
deAlignedMalloc(int numBytes,int alignBytes)84 void* deAlignedMalloc (int numBytes, int alignBytes)
85 {
86 	int			ptrSize		= sizeof(void*);
87 	deUintptr	origPtr		= (deUintptr)deMalloc(numBytes + ptrSize + alignBytes);
88 	if (origPtr)
89 	{
90 		deUintptr	alignedPtr	= (deUintptr)deAlignPtr((void*)(origPtr + ptrSize), alignBytes);
91 		deUintptr	ptrPtr		= (alignedPtr - ptrSize);
92 		DE_ASSERT(deInRange32(alignBytes, 0, 256) && deIsPowerOfTwo32(alignBytes));
93 		*(deUintptr*)ptrPtr = origPtr;
94 		return (void*)alignedPtr;
95 	}
96 	else
97 		return DE_NULL;
98 }
99 
100 /*--------------------------------------------------------------------*//*!
101  * \brief Reallocate a chunk of memory.
102  * \param ptr		Pointer to previously allocated memory block
103  * \param numBytes	New size in bytes
104  * \return Pointer to the reallocated (and possibly moved) memory block
105  *//*--------------------------------------------------------------------*/
deRealloc(void * ptr,int numBytes)106 void* deRealloc (void* ptr, int numBytes)
107 {
108 	return realloc(ptr, (size_t)numBytes);
109 }
110 
111 /*--------------------------------------------------------------------*//*!
112  * \brief Free a chunk of memory.
113  * \param ptr	Pointer to memory to free.
114  *//*--------------------------------------------------------------------*/
deFree(void * ptr)115 void deFree (void* ptr)
116 {
117 	free(ptr);
118 }
119 
deAlignedFree(void * ptr)120 void deAlignedFree (void* ptr)
121 {
122 	if (ptr)
123 	{
124 		int			ptrSize		= sizeof(void*);
125 		deUintptr	ptrPtr		= (deUintptr)ptr - ptrSize;
126 		deUintptr	origPtr		= *(deUintptr*)ptrPtr;
127 		DE_ASSERT(ptrPtr - origPtr < 256);
128 		deFree((void*)origPtr);
129 	}
130 }
131 
deStrdup(const char * str)132 char* deStrdup (const char* str)
133 {
134 #if (DE_COMPILER == DE_COMPILER_MSC)
135 	return _strdup(str);
136 #elif (DE_OS == DE_OS_OSX) || (DE_OS == DE_OS_IOS)
137 	/* For some reason Steve doesn't like stdrup(). */
138 	size_t	len		= strlen(str);
139 	char*	copy	= malloc(len+1);
140 	memcpy(copy, str, len);
141 	copy[len] = 0;
142 	return copy;
143 #else
144 	return strdup(str);
145 #endif
146 }
147 
148 DE_END_EXTERN_C
149