summaryrefslogtreecommitdiff
path: root/src/common/malloc.h
blob: 5411d670da8a9192ac5ea93f9d36dcd6b0aa73a8 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
// Copyright (c) Athena Dev Teams - Licensed under GNU GPL
// For more information, see LICENCE in the main folder

#ifndef _MALLOC_H_
#define _MALLOC_H_

// Q: What are the 'a'-variant allocation functions?
// A: They allocate memory from the stack, which is automatically 
//    freed when the invoking function returns.
//    But it's not portable (http://c-faq.com/malloc/alloca.html)
//    and I have doubts our implementation works.
//    -> They should NOT be used, period.

#ifndef __NETBSD__
#if __STDC_VERSION__ < 199901L
#	if __GNUC__ >= 2
#		define __func__ __FUNCTION__
#	else
#		define __func__ ""
#	endif
#endif
#endif
#define ALC_MARK __FILE__, __LINE__, __func__

//////////////////////////////////////////////////////////////////////
// Whether to use Athena's built-in Memory Manager (enabled by default)
// To disable just comment the following line
#if !defined(DMALLOC) && !defined(BCHECK)
	#define USE_MEMMGR
#endif
// Whether to enable Memory Manager's logging
#define LOG_MEMMGR

#ifdef USE_MEMMGR

#	define aMalloc(n)		_mmalloc(n,ALC_MARK)
#	define aMallocA(n)		_mmalloc(n,ALC_MARK)
#	define aCalloc(m,n)		_mcalloc(m,n,ALC_MARK)
#	define aCallocA(m,n)	_mcalloc(m,n,ALC_MARK)
#	define aRealloc(p,n)	_mrealloc(p,n,ALC_MARK)
#	define aStrdup(p)		_mstrdup(p,ALC_MARK)
#	define aFree(p)			_mfree(p,ALC_MARK)

	void* _mmalloc	(size_t size, const char *file, int line, const char *func);
	void* _mcalloc	(size_t num, size_t size, const char *file, int line, const char *func);
	void* _mrealloc	(void *p, size_t size, const char *file, int line, const char *func);
	char* _mstrdup	(const char *p, const char *file, int line, const char *func);
	void  _mfree	(void *p, const char *file, int line, const char *func);

#else

#	define aMalloc(n)		aMalloc_((n),ALC_MARK)
#	define aMallocA(n)		aMallocA_((n),ALC_MARK)
#	define aCalloc(m,n)		aCalloc_((m),(n),ALC_MARK)
#	define aCallocA(m,n)	aCallocA_(m,n,ALC_MARK)
#	define aRealloc(p,n)	aRealloc_(p,n,ALC_MARK)
#	define aStrdup(p)		aStrdup_(p,ALC_MARK)
#	define aFree(p)			aFree_(p,ALC_MARK)

	void* aMalloc_	(size_t size, const char *file, int line, const char *func);
	void* aMallocA_	(size_t size, const char *file, int line, const char *func);
	void* aCalloc_	(size_t num, size_t size, const char *file, int line, const char *func);
	void* aCallocA_	(size_t num, size_t size, const char *file, int line, const char *func);
	void* aRealloc_	(void *p, size_t size, const char *file, int line, const char *func);
	char* aStrdup_	(const char *p, const char *file, int line, const char *func);
	void  aFree_	(void *p, const char *file, int line, const char *func);

#endif

////////////// Memory Managers //////////////////

#ifdef MEMWATCH

#	include "memwatch.h"
#	define MALLOC(n,file,line,func)	mwMalloc((n),(file),(line))
#	define MALLOCA(n,file,line,func)	mwMalloc((n),(file),(line))
#	define CALLOC(m,n,file,line,func)	mwCalloc((m),(n),(file),(line))
#	define CALLOCA(m,n,file,line,func)	mwCalloc((m),(n),(file),(line))
#	define REALLOC(p,n,file,line,func)	mwRealloc((p),(n),(file),(line))
#	define STRDUP(p,file,line,func)	mwStrdup((p),(file),(line))
#	define FREE(p,file,line,func)		mwFree((p),(file),(line))

#elif defined(DMALLOC)

#	include "dmalloc.h"
#	define MALLOC(n,file,line,func)	dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
#	define MALLOCA(n,file,line,func)	dmalloc_malloc((file),(line),(n),DMALLOC_FUNC_MALLOC,0,0)
#	define CALLOC(m,n,file,line,func)	dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
#	define CALLOCA(m,n,file,line,func)	dmalloc_malloc((file),(line),(m)*(n),DMALLOC_FUNC_CALLOC,0,0)
#	define REALLOC(p,n,file,line,func)	dmalloc_realloc((file),(line),(p),(n),DMALLOC_FUNC_REALLOC,0)
#	define STRDUP(p,file,line,func)	strdup(p)
#	define FREE(p,file,line,func)		free(p)

#elif defined(GCOLLECT)

#	include "gc.h"
#	define MALLOC(n,file,line,func)	GC_MALLOC(n)
#	define MALLOCA(n,file,line,func)	GC_MALLOC_ATOMIC(n)
#	define CALLOC(m,n,file,line,func)	_bcalloc((m),(n))
#	define CALLOCA(m,n,file,line,func)	_bcallocA((m),(n))
#	define REALLOC(p,n,file,line,func)	GC_REALLOC((p),(n))
#	define STRDUP(p,file,line,func)	_bstrdup(p)
#	define FREE(p,file,line,func)		GC_FREE(p)

	void * _bcalloc(size_t, size_t);
	void * _bcallocA(size_t, size_t);
	char * _bstrdup(const char *);

/* FIXME Why is this the same as #else? [FlavioJS]
#elif defined(BCHECK)

#	define MALLOC(n,file,line,func)	malloc(n)
#	define MALLOCA(n,file,line,func)	malloc(n)
#	define CALLOC(m,n,file,line,func)	calloc((m),(n))
#	define CALLOCA(m,n,file,line,func)	calloc((m),(n))
#	define REALLOC(p,n,file,line,func)	realloc((p),(n))
#	define STRDUP(p,file,line,func)	strdup(p)
#	define FREE(p,file,line,func)		free(p)
*/
#else

#	define MALLOC(n,file,line,func)	malloc(n)
#	define MALLOCA(n,file,line,func)	malloc(n)
#	define CALLOC(m,n,file,line,func)	calloc((m),(n))
#	define CALLOCA(m,n,file,line,func)	calloc((m),(n))
#	define REALLOC(p,n,file,line,func)	realloc((p),(n))
#	define STRDUP(p,file,line,func)	strdup(p)
#	define FREE(p,file,line,func)		free(p)

#endif

/////////////// Buffer Creation /////////////////
// Full credit for this goes to Shinomori [Ajarn]

#ifdef __GNUC__ // GCC has variable length arrays

	#define CREATE_BUFFER(name, type, size) type name[size]
	#define DELETE_BUFFER(name)

#else // others don't, so we emulate them

	#define CREATE_BUFFER(name, type, size) type *name = (type *) aCalloc (size, sizeof(type))
	#define DELETE_BUFFER(name) aFree(name)

#endif

////////////// Others //////////////////////////
// should be merged with any of above later
#define CREATE(result, type, number) (result) = (type *) aCalloc ((number), sizeof(type))

#define CREATE_A(result, type, number) (result) = (type *) aCallocA ((number), sizeof(type))

#define RECREATE(result, type, number) (result) = (type *) aRealloc ((result), sizeof(type) * (number))

////////////////////////////////////////////////

unsigned int malloc_usage (void);
void malloc_init (void);
void malloc_final (void);

#endif /* _MALLOC_H_ */