1 /*	MikMod sound library
2 	(c) 1998, 1999 Miodrag Vallat and others - see file AUTHORS for
3 	complete list.
4 
5 	This library is free software; you can redistribute it and/or modify
6 	it under the terms of the GNU Library General Public License as
7 	published by the Free Software Foundation; either version 2 of
8 	the License, or (at your option) any later version.
9 
10 	This program is distributed in the hope that it will be useful,
11 	but WITHOUT ANY WARRANTY; without even the implied warranty of
12 	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13 	GNU Library General Public License for more details.
14 
15 	You should have received a copy of the GNU Library General Public
16 	License along with this library; if not, write to the Free Software
17 	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
18 	02111-1307, USA.
19 */
20 
21 /*==============================================================================
22 
23   $Id$
24 
25   Dynamic memory routines
26 
27 ==============================================================================*/
28 
29 #ifdef HAVE_CONFIG_H
30 #include "config.h"
31 #endif
32 
33 #ifdef HAVE_POSIX_MEMALIGN
34 #define _XOPEN_SOURCE 600 /* for posix_memalign */
35 #endif
36 
37 #include "string.h"
38 #include "mikmod_internals.h"
39 
40 #if defined(HAVE_SSE2) || defined(HAVE_ALTIVEC)
41 #undef WIN32_ALIGNED_MALLOC
42 #if defined(_WIN32) && !defined(_WIN32_WCE)
43 # if defined(_WIN64) /* OK with MSVC and MinGW */
44 #  define WIN32_ALIGNED_MALLOC
45 # elif defined(_MSC_VER) && (_MSC_VER >= 1300)
46 #  define WIN32_ALIGNED_MALLOC
47 # elif defined(__MINGW32__)
48   /* no guarantees that msvcrt.dll will have it */
49 # endif
50 #endif
51 
52 #define PTRSIZE (sizeof(void*))
53 
54 /* return a 16 byte aligned address */
MikMod_amalloc(size_t size)55 void* MikMod_amalloc(size_t size)
56 {
57 	void *d;
58 #if defined(HAVE_POSIX_MEMALIGN)
59 	if (!posix_memalign(&d, 16, size)) {
60 		memset(d, 0, size);
61 		return d;
62 	}
63 #elif defined(WIN32_ALIGNED_MALLOC)
64 	d = _aligned_malloc(size, 16);
65 	if (d) {
66 		ZeroMemory(d, size);
67 		return d;
68 	}
69 #else
70 	size_t s = (size)? ((size + (PTRSIZE-1)) & ~(PTRSIZE-1)) : PTRSIZE;
71 	s += PTRSIZE + 16;
72 	d = calloc(1, s);
73 	if (d) {
74 		char *pptr = (char *)d + PTRSIZE;
75 		size_t err = ((size_t)pptr) & 15;
76 		char *fptr = pptr + (16 - err);
77 		*(size_t*)(fptr - PTRSIZE) = (size_t)d;
78 		return fptr;
79 	}
80 #endif
81 
82 	_mm_errno = MMERR_OUT_OF_MEMORY;
83 	if(_mm_errorhandler) _mm_errorhandler();
84 	return NULL;
85 }
86 
MikMod_afree(void * data)87 void MikMod_afree(void *data)
88 {
89 	if (!data) return;
90 #if defined(HAVE_POSIX_MEMALIGN)
91 	free(data);
92 #elif defined(WIN32_ALIGNED_MALLOC)
93 	_aligned_free(data);
94 #else
95 	free((void *) *(size_t*)((unsigned char *)data - PTRSIZE));
96 #endif
97 }
98 #endif /* (HAVE_SSE2) || (HAVE_ALTIVEC) */
99 
MikMod_realloc(void * data,size_t size)100 void* MikMod_realloc(void *data, size_t size)
101 {
102 	if (data) return realloc(data, size);
103 	return calloc(1, size);
104 }
105 
106 /* Same as malloc, but sets error variable _mm_error when fails */
MikMod_malloc(size_t size)107 void* MikMod_malloc(size_t size)
108 {
109 	return MikMod_calloc(1, size);
110 }
111 
112 /* Same as calloc, but sets error variable _mm_error when fails */
MikMod_calloc(size_t nitems,size_t size)113 void* MikMod_calloc(size_t nitems, size_t size)
114 {
115 	void *d = calloc(nitems, size);
116 	if (d) return d;
117 
118 	_mm_errno = MMERR_OUT_OF_MEMORY;
119 	if(_mm_errorhandler) _mm_errorhandler();
120 	return NULL;
121 }
122 
MikMod_free(void * data)123 void MikMod_free(void *data)
124 {
125 	if (data) free(data);
126 }
127 
128 /* like strdup(), but the result must be freed using MikMod_free() */
MikMod_strdup(const CHAR * s)129 CHAR *MikMod_strdup(const CHAR *s)
130 {
131 	size_t l;
132 	CHAR *d;
133 
134 	if (!s) return NULL;
135 
136 	l = strlen(s) + 1;
137 	d = (CHAR *) MikMod_calloc(1, l * sizeof(CHAR));
138 	if (d) strcpy(d, s);
139 	return d;
140 }
141 
142 /* ex:set ts=4: */
143