Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/elmergrid/src/metis-5.1.0/GKlib/mcore.c
3206 views
1
/*!
2
\file
3
\brief Functions dealing with creating and allocating mcores
4
5
\date Started 5/30/11
6
\author George
7
\author Copyright 1997-2011, Regents of the University of Minnesota
8
\version $Id: mcore.c 13953 2013-03-30 16:20:07Z karypis $
9
*/
10
11
#include <GKlib.h>
12
13
14
/*************************************************************************/
15
/*! This function creates an mcore
16
*/
17
/*************************************************************************/
18
gk_mcore_t *gk_mcoreCreate(size_t coresize)
19
{
20
gk_mcore_t *mcore;
21
22
mcore = (gk_mcore_t *)gk_malloc(sizeof(gk_mcore_t), "gk_mcoreCreate: mcore");
23
memset(mcore, 0, sizeof(gk_mcore_t));
24
25
mcore->coresize = coresize;
26
mcore->corecpos = 0;
27
28
mcore->core = (coresize == 0 ? NULL : gk_malloc(mcore->coresize, "gk_mcoreCreate: core"));
29
30
/* allocate the memory for keeping track of malloc ops */
31
mcore->nmops = 2048;
32
mcore->cmop = 0;
33
mcore->mops = (gk_mop_t *)gk_malloc(mcore->nmops*sizeof(gk_mop_t), "gk_mcoreCreate: mcore->mops");
34
35
return mcore;
36
}
37
38
39
/*************************************************************************/
40
/*! This function creates an mcore. This version is used for gkmcore.
41
*/
42
/*************************************************************************/
43
gk_mcore_t *gk_gkmcoreCreate()
44
{
45
gk_mcore_t *mcore;
46
47
if ((mcore = (gk_mcore_t *)malloc(sizeof(gk_mcore_t))) == NULL)
48
return NULL;
49
memset(mcore, 0, sizeof(gk_mcore_t));
50
51
/* allocate the memory for keeping track of malloc ops */
52
mcore->nmops = 2048;
53
mcore->cmop = 0;
54
if ((mcore->mops = (gk_mop_t *)malloc(mcore->nmops*sizeof(gk_mop_t))) == NULL) {
55
free(mcore);
56
return NULL;
57
}
58
59
return mcore;
60
}
61
62
63
/*************************************************************************/
64
/*! This function destroys an mcore.
65
*/
66
/*************************************************************************/
67
void gk_mcoreDestroy(gk_mcore_t **r_mcore, int showstats)
68
{
69
gk_mcore_t *mcore = *r_mcore;
70
71
if (mcore == NULL)
72
return;
73
74
if (showstats)
75
printf("\n gk_mcore statistics\n"
76
" coresize: %12zu nmops: %12zu cmop: %6zu\n"
77
" num_callocs: %12zu num_hallocs: %12zu\n"
78
" size_callocs: %12zu size_hallocs: %12zu\n"
79
" cur_callocs: %12zu cur_hallocs: %12zu\n"
80
" max_callocs: %12zu max_hallocs: %12zu\n",
81
mcore->coresize, mcore->nmops, mcore->cmop,
82
mcore->num_callocs, mcore->num_hallocs,
83
mcore->size_callocs, mcore->size_hallocs,
84
mcore->cur_callocs, mcore->cur_hallocs,
85
mcore->max_callocs, mcore->max_hallocs);
86
87
if (mcore->cur_callocs != 0 || mcore->cur_hallocs != 0 || mcore->cmop != 0) {
88
printf("***Warning: mcore memory was not fully freed when destroyed.\n"
89
" cur_callocs: %6zu cur_hallocs: %6zu cmop: %6zu\n",
90
mcore->cur_callocs, mcore->cur_hallocs, mcore->cmop);
91
}
92
93
gk_free((void **)&mcore->core, &mcore->mops, &mcore, LTERM);
94
95
*r_mcore = NULL;
96
}
97
98
99
/*************************************************************************/
100
/*! This function destroys an mcore. This version is for gkmcore.
101
*/
102
/*************************************************************************/
103
void gk_gkmcoreDestroy(gk_mcore_t **r_mcore, int showstats)
104
{
105
gk_mcore_t *mcore = *r_mcore;
106
107
if (mcore == NULL)
108
return;
109
110
if (showstats)
111
printf("\n gk_mcore statistics\n"
112
" nmops: %12zu cmop: %6zu\n"
113
" num_hallocs: %12zu\n"
114
" size_hallocs: %12zu\n"
115
" cur_hallocs: %12zu\n"
116
" max_hallocs: %12zu\n",
117
mcore->nmops, mcore->cmop,
118
mcore->num_hallocs,
119
mcore->size_hallocs,
120
mcore->cur_hallocs,
121
mcore->max_hallocs);
122
123
if (mcore->cur_hallocs != 0 || mcore->cmop != 0) {
124
printf("***Warning: mcore memory was not fully freed when destroyed.\n"
125
" cur_hallocs: %6zu cmop: %6zu\n",
126
mcore->cur_hallocs, mcore->cmop);
127
}
128
129
free(mcore->mops);
130
free(mcore);
131
132
*r_mcore = NULL;
133
}
134
135
136
/*************************************************************************/
137
/*! This function allocate space from the core/heap
138
*/
139
/*************************************************************************/
140
void *gk_mcoreMalloc(gk_mcore_t *mcore, size_t nbytes)
141
{
142
void *ptr;
143
144
/* pad to make pointers 8-byte aligned */
145
nbytes += (nbytes%8 == 0 ? 0 : 8 - nbytes%8);
146
147
if (mcore->corecpos + nbytes < mcore->coresize) {
148
/* service this request from the core */
149
ptr = ((char *)mcore->core)+mcore->corecpos;
150
mcore->corecpos += nbytes;
151
152
gk_mcoreAdd(mcore, GK_MOPT_CORE, nbytes, ptr);
153
}
154
else {
155
/* service this request from the heap */
156
ptr = gk_malloc(nbytes, "gk_mcoremalloc: ptr");
157
158
gk_mcoreAdd(mcore, GK_MOPT_HEAP, nbytes, ptr);
159
}
160
161
/*
162
printf("MCMALLOC: %zu %d %8zu\n", mcore->cmop-1,
163
mcore->mops[mcore->cmop-1].type, mcore->mops[mcore->cmop-1].nbytes);
164
*/
165
166
return ptr;
167
}
168
169
170
/*************************************************************************/
171
/*! This function sets a marker in the stack of malloc ops to be used
172
subsequently for freeing purposes
173
*/
174
/*************************************************************************/
175
void gk_mcorePush(gk_mcore_t *mcore)
176
{
177
gk_mcoreAdd(mcore, GK_MOPT_MARK, 0, NULL);
178
/* printf("MCPPUSH: %zu\n", mcore->cmop-1); */
179
}
180
181
182
/*************************************************************************/
183
/*! This function sets a marker in the stack of malloc ops to be used
184
subsequently for freeing purposes. This is the gkmcore version.
185
*/
186
/*************************************************************************/
187
void gk_gkmcorePush(gk_mcore_t *mcore)
188
{
189
gk_gkmcoreAdd(mcore, GK_MOPT_MARK, 0, NULL);
190
/* printf("MCPPUSH: %zu\n", mcore->cmop-1); */
191
}
192
193
194
/*************************************************************************/
195
/*! This function frees all mops since the last push
196
*/
197
/*************************************************************************/
198
void gk_mcorePop(gk_mcore_t *mcore)
199
{
200
while (mcore->cmop > 0) {
201
mcore->cmop--;
202
switch (mcore->mops[mcore->cmop].type) {
203
case GK_MOPT_MARK: /* push marker */
204
goto DONE;
205
break;
206
207
case GK_MOPT_CORE: /* core free */
208
if (mcore->corecpos < mcore->mops[mcore->cmop].nbytes)
209
errexit("Internal Error: wspace's core is about to be over-freed [%zu, %zu, %zd]\n",
210
mcore->coresize, mcore->corecpos, mcore->mops[mcore->cmop].nbytes);
211
212
mcore->corecpos -= mcore->mops[mcore->cmop].nbytes;
213
mcore->cur_callocs -= mcore->mops[mcore->cmop].nbytes;
214
break;
215
216
case GK_MOPT_HEAP: /* heap free */
217
gk_free((void **)&mcore->mops[mcore->cmop].ptr, LTERM);
218
mcore->cur_hallocs -= mcore->mops[mcore->cmop].nbytes;
219
break;
220
221
default:
222
gk_errexit(SIGMEM, "Unknown mop type of %d\n", mcore->mops[mcore->cmop].type);
223
}
224
}
225
226
DONE:
227
;
228
/*printf("MCPPOP: %zu\n", mcore->cmop); */
229
}
230
231
232
/*************************************************************************/
233
/*! This function frees all mops since the last push. This version is
234
for poping the gkmcore and it uses free instead of gk_free.
235
*/
236
/*************************************************************************/
237
void gk_gkmcorePop(gk_mcore_t *mcore)
238
{
239
while (mcore->cmop > 0) {
240
mcore->cmop--;
241
switch (mcore->mops[mcore->cmop].type) {
242
case GK_MOPT_MARK: /* push marker */
243
goto DONE;
244
break;
245
246
case GK_MOPT_HEAP: /* heap free */
247
free(mcore->mops[mcore->cmop].ptr);
248
mcore->cur_hallocs -= mcore->mops[mcore->cmop].nbytes;
249
break;
250
251
default:
252
gk_errexit(SIGMEM, "Unknown mop type of %d\n", mcore->mops[mcore->cmop].type);
253
}
254
}
255
256
DONE:
257
;
258
}
259
260
261
/*************************************************************************/
262
/*! Adds a memory allocation at the end of the list.
263
*/
264
/*************************************************************************/
265
void gk_mcoreAdd(gk_mcore_t *mcore, int type, size_t nbytes, void *ptr)
266
{
267
if (mcore->cmop == mcore->nmops) {
268
mcore->nmops *= 2;
269
mcore->mops = realloc(mcore->mops, mcore->nmops*sizeof(gk_mop_t));
270
if (mcore->mops == NULL)
271
gk_errexit(SIGMEM, "***Memory allocation for gkmcore failed.\n");
272
}
273
274
mcore->mops[mcore->cmop].type = type;
275
mcore->mops[mcore->cmop].nbytes = nbytes;
276
mcore->mops[mcore->cmop].ptr = ptr;
277
mcore->cmop++;
278
279
switch (type) {
280
case GK_MOPT_MARK:
281
break;
282
283
case GK_MOPT_CORE:
284
mcore->num_callocs++;
285
mcore->size_callocs += nbytes;
286
mcore->cur_callocs += nbytes;
287
if (mcore->max_callocs < mcore->cur_callocs)
288
mcore->max_callocs = mcore->cur_callocs;
289
break;
290
291
case GK_MOPT_HEAP:
292
mcore->num_hallocs++;
293
mcore->size_hallocs += nbytes;
294
mcore->cur_hallocs += nbytes;
295
if (mcore->max_hallocs < mcore->cur_hallocs)
296
mcore->max_hallocs = mcore->cur_hallocs;
297
break;
298
default:
299
gk_errexit(SIGMEM, "Incorrect mcore type operation.\n");
300
}
301
}
302
303
304
/*************************************************************************/
305
/*! Adds a memory allocation at the end of the list. This is the gkmcore
306
version.
307
*/
308
/*************************************************************************/
309
void gk_gkmcoreAdd(gk_mcore_t *mcore, int type, size_t nbytes, void *ptr)
310
{
311
if (mcore->cmop == mcore->nmops) {
312
mcore->nmops *= 2;
313
mcore->mops = realloc(mcore->mops, mcore->nmops*sizeof(gk_mop_t));
314
if (mcore->mops == NULL)
315
gk_errexit(SIGMEM, "***Memory allocation for gkmcore failed.\n");
316
}
317
318
mcore->mops[mcore->cmop].type = type;
319
mcore->mops[mcore->cmop].nbytes = nbytes;
320
mcore->mops[mcore->cmop].ptr = ptr;
321
mcore->cmop++;
322
323
switch (type) {
324
case GK_MOPT_MARK:
325
break;
326
327
case GK_MOPT_HEAP:
328
mcore->num_hallocs++;
329
mcore->size_hallocs += nbytes;
330
mcore->cur_hallocs += nbytes;
331
if (mcore->max_hallocs < mcore->cur_hallocs)
332
mcore->max_hallocs = mcore->cur_hallocs;
333
break;
334
default:
335
gk_errexit(SIGMEM, "Incorrect mcore type operation.\n");
336
}
337
}
338
339
340
/*************************************************************************/
341
/*! This function deletes the mop associated with the supplied pointer.
342
The mop has to be a heap allocation, otherwise it fails violently.
343
*/
344
/*************************************************************************/
345
void gk_mcoreDel(gk_mcore_t *mcore, void *ptr)
346
{
347
int i;
348
349
for (i=mcore->cmop-1; i>=0; i--) {
350
if (mcore->mops[i].type == GK_MOPT_MARK)
351
gk_errexit(SIGMEM, "Could not find pointer %p in mcore\n", ptr);
352
353
if (mcore->mops[i].ptr == ptr) {
354
if (mcore->mops[i].type != GK_MOPT_HEAP)
355
gk_errexit(SIGMEM, "Trying to delete a non-HEAP mop.\n");
356
357
mcore->cur_hallocs -= mcore->mops[i].nbytes;
358
mcore->mops[i] = mcore->mops[--mcore->cmop];
359
return;
360
}
361
}
362
363
gk_errexit(SIGMEM, "mcoreDel should never have been here!\n");
364
}
365
366
367
/*************************************************************************/
368
/*! This function deletes the mop associated with the supplied pointer.
369
The mop has to be a heap allocation, otherwise it fails violently.
370
This is the gkmcore version.
371
*/
372
/*************************************************************************/
373
void gk_gkmcoreDel(gk_mcore_t *mcore, void *ptr)
374
{
375
int i;
376
377
for (i=mcore->cmop-1; i>=0; i--) {
378
if (mcore->mops[i].type == GK_MOPT_MARK)
379
gk_errexit(SIGMEM, "Could not find pointer %p in mcore\n", ptr);
380
381
if (mcore->mops[i].ptr == ptr) {
382
if (mcore->mops[i].type != GK_MOPT_HEAP)
383
gk_errexit(SIGMEM, "Trying to delete a non-HEAP mop.\n");
384
385
mcore->cur_hallocs -= mcore->mops[i].nbytes;
386
mcore->mops[i] = mcore->mops[--mcore->cmop];
387
return;
388
}
389
}
390
391
gk_errexit(SIGMEM, "gkmcoreDel should never have been here!\n");
392
}
393
394
395