Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/memory.c
3206 views
1
/*!
2
\file memory.c
3
\brief This file contains various allocation routines
4
5
The allocation routines included are for 1D and 2D arrays of the
6
most datatypes that GKlib support. Many of these routines are
7
defined with the help of the macros in gk_memory.h. These macros
8
can be used to define other memory allocation routines.
9
10
\date Started 4/3/2007
11
\author George
12
\version\verbatim $Id: memory.c 10783 2011-09-21 23:19:56Z karypis $ \endverbatim
13
*/
14
15
16
#include <GKlib.h>
17
18
/* This is for the global mcore that tracks all heap allocations */
19
static __thread gk_mcore_t *gkmcore = NULL;
20
21
22
/*************************************************************************/
23
/*! Define the set of memory allocation routines for each data type */
24
/**************************************************************************/
25
GK_MKALLOC(gk_c, char)
26
GK_MKALLOC(gk_i, int)
27
GK_MKALLOC(gk_i32, int32_t)
28
GK_MKALLOC(gk_i64, int64_t)
29
GK_MKALLOC(gk_z, ssize_t)
30
GK_MKALLOC(gk_f, float)
31
GK_MKALLOC(gk_d, double)
32
GK_MKALLOC(gk_idx, gk_idx_t)
33
34
GK_MKALLOC(gk_ckv, gk_ckv_t)
35
GK_MKALLOC(gk_ikv, gk_ikv_t)
36
GK_MKALLOC(gk_i32kv, gk_i32kv_t)
37
GK_MKALLOC(gk_i64kv, gk_i64kv_t)
38
GK_MKALLOC(gk_zkv, gk_zkv_t)
39
GK_MKALLOC(gk_fkv, gk_fkv_t)
40
GK_MKALLOC(gk_dkv, gk_dkv_t)
41
GK_MKALLOC(gk_skv, gk_skv_t)
42
GK_MKALLOC(gk_idxkv, gk_idxkv_t)
43
44
45
46
47
48
49
/*************************************************************************/
50
/*! This function allocates a two-dimensional matrix.
51
*/
52
/*************************************************************************/
53
void gk_AllocMatrix(void ***r_matrix, size_t elmlen, size_t ndim1, size_t ndim2)
54
{
55
gk_idx_t i, j;
56
void **matrix;
57
58
*r_matrix = NULL;
59
60
if ((matrix = (void **)gk_malloc(ndim1*sizeof(void *), "gk_AllocMatrix: matrix")) == NULL)
61
return;
62
63
for (i=0; i<ndim1; i++) {
64
if ((matrix[i] = (void *)gk_malloc(ndim2*elmlen, "gk_AllocMatrix: matrix[i]")) == NULL) {
65
for (j=0; j<i; j++)
66
gk_free((void **)&matrix[j], LTERM);
67
return;
68
}
69
}
70
71
*r_matrix = matrix;
72
}
73
74
75
/*************************************************************************/
76
/*! This function frees a two-dimensional matrix.
77
*/
78
/*************************************************************************/
79
void gk_FreeMatrix(void ***r_matrix, size_t ndim1, size_t ndim2)
80
{
81
gk_idx_t i;
82
void **matrix;
83
84
if ((matrix = *r_matrix) == NULL)
85
return;
86
87
for (i=0; i<ndim1; i++)
88
gk_free((void **)&matrix[i], LTERM);
89
90
gk_free((void **)r_matrix, LTERM);
91
92
}
93
94
95
/*************************************************************************/
96
/*! This function initializes tracking of heap allocations.
97
*/
98
/*************************************************************************/
99
int gk_malloc_init()
100
{
101
if (gkmcore == NULL)
102
gkmcore = gk_gkmcoreCreate();
103
104
if (gkmcore == NULL)
105
return 0;
106
107
gk_gkmcorePush(gkmcore);
108
109
return 1;
110
}
111
112
113
/*************************************************************************/
114
/*! This function frees the memory that has been allocated since the
115
last call to gk_malloc_init().
116
*/
117
/*************************************************************************/
118
void gk_malloc_cleanup(int showstats)
119
{
120
if (gkmcore != NULL) {
121
gk_gkmcorePop(gkmcore);
122
if (gkmcore->cmop == 0) {
123
gk_gkmcoreDestroy(&gkmcore, showstats);
124
gkmcore = NULL;
125
}
126
}
127
}
128
129
130
/*************************************************************************/
131
/*! This function is my wrapper around malloc that provides the following
132
enhancements over malloc:
133
* It always allocates one byte of memory, even if 0 bytes are requested.
134
This is to ensure that checks of returned values do not lead to NULL
135
due to 0 bytes requested.
136
* It zeros-out the memory that is allocated. This is for a quick init
137
of the underlying datastructures.
138
*/
139
/**************************************************************************/
140
void *gk_malloc(size_t nbytes, char *msg)
141
{
142
void *ptr=NULL;
143
144
if (nbytes == 0)
145
nbytes++; /* Force mallocs to actually allocate some memory */
146
147
ptr = (void *)malloc(nbytes);
148
149
if (ptr == NULL) {
150
fprintf(stderr, " Current memory used: %10zu bytes\n", gk_GetCurMemoryUsed());
151
fprintf(stderr, " Maximum memory used: %10zu bytes\n", gk_GetMaxMemoryUsed());
152
gk_errexit(SIGMEM, "***Memory allocation failed for %s. Requested size: %zu bytes",
153
msg, nbytes);
154
return NULL;
155
}
156
157
/* add this memory allocation */
158
if (gkmcore != NULL) gk_gkmcoreAdd(gkmcore, GK_MOPT_HEAP, nbytes, ptr);
159
160
/* zero-out the allocated space */
161
#ifndef NDEBUG
162
memset(ptr, 0, nbytes);
163
#endif
164
165
return ptr;
166
}
167
168
169
/*************************************************************************
170
* This function is my wrapper around realloc
171
**************************************************************************/
172
void *gk_realloc(void *oldptr, size_t nbytes, char *msg)
173
{
174
void *ptr=NULL;
175
176
if (nbytes == 0)
177
nbytes++; /* Force mallocs to actually allocate some memory */
178
179
/* remove this memory de-allocation */
180
if (gkmcore != NULL && oldptr != NULL) gk_gkmcoreDel(gkmcore, oldptr);
181
182
ptr = (void *)realloc(oldptr, nbytes);
183
184
if (ptr == NULL) {
185
fprintf(stderr, " Maximum memory used: %10zu bytes\n", gk_GetMaxMemoryUsed());
186
fprintf(stderr, " Current memory used: %10zu bytes\n", gk_GetCurMemoryUsed());
187
gk_errexit(SIGMEM, "***Memory realloc failed for %s. " "Requested size: %zu bytes",
188
msg, nbytes);
189
return NULL;
190
}
191
192
/* add this memory allocation */
193
if (gkmcore != NULL) gk_gkmcoreAdd(gkmcore, GK_MOPT_HEAP, nbytes, ptr);
194
195
return ptr;
196
}
197
198
199
/*************************************************************************
200
* This function is my wrapper around free, allows multiple pointers
201
**************************************************************************/
202
void gk_free(void **ptr1,...)
203
{
204
va_list plist;
205
void **ptr;
206
207
if (*ptr1 != NULL) {
208
free(*ptr1);
209
210
/* remove this memory de-allocation */
211
if (gkmcore != NULL) gk_gkmcoreDel(gkmcore, *ptr1);
212
}
213
*ptr1 = NULL;
214
215
va_start(plist, ptr1);
216
while ((ptr = va_arg(plist, void **)) != LTERM) {
217
if (*ptr != NULL) {
218
free(*ptr);
219
220
/* remove this memory de-allocation */
221
if (gkmcore != NULL) gk_gkmcoreDel(gkmcore, *ptr);
222
}
223
*ptr = NULL;
224
}
225
va_end(plist);
226
}
227
228
229
/*************************************************************************
230
* This function returns the current ammount of dynamically allocated
231
* memory that is used by the system
232
**************************************************************************/
233
size_t gk_GetCurMemoryUsed()
234
{
235
if (gkmcore == NULL)
236
return 0;
237
else
238
return gkmcore->cur_hallocs;
239
}
240
241
242
/*************************************************************************
243
* This function returns the maximum ammount of dynamically allocated
244
* memory that was used by the system
245
**************************************************************************/
246
size_t gk_GetMaxMemoryUsed()
247
{
248
if (gkmcore == NULL)
249
return 0;
250
else
251
return gkmcore->max_hallocs;
252
}
253
254