IFPACK Development
Loading...
Searching...
No Matches
Mem_dh.c
1/*@HEADER
2// ***********************************************************************
3//
4// Ifpack: Object-Oriented Algebraic Preconditioner Package
5// Copyright (2002) Sandia Corporation
6//
7// Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8// license for use of this work by or on behalf of the U.S. Government.
9//
10// Redistribution and use in source and binary forms, with or without
11// modification, are permitted provided that the following conditions are
12// met:
13//
14// 1. Redistributions of source code must retain the above copyright
15// notice, this list of conditions and the following disclaimer.
16//
17// 2. Redistributions in binary form must reproduce the above copyright
18// notice, this list of conditions and the following disclaimer in the
19// documentation and/or other materials provided with the distribution.
20//
21// 3. Neither the name of the Corporation nor the names of the
22// contributors may be used to endorse or promote products derived from
23// this software without specific prior written permission.
24//
25// THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
26// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
27// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
28// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
29// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
30// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
31// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
32// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
33// LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
34// NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36//
37// Questions? Contact Michael A. Heroux (maherou@sandia.gov)
38//
39// ***********************************************************************
40//@HEADER
41*/
42
43#include "Parser_dh.h"
44#include "Mem_dh.h"
45
46/* TODO: error checking is not complete; memRecord_dh need to
47 be done in Mem_dhMalloc() and Mem_dhFree()l
48*/
49
50
51 /* a memRecord_dh is pre and post-pended to every
52 * piece of memory obtained by calling MALLOC_DH
53 */
54typedef struct
55{
56 double size;
57 double cookie;
59
60struct _mem_dh
61{
62 double maxMem; /* max allocated at any point in time */
63 double curMem; /* total currently allocated */
64 double totalMem; /* total cumulative malloced */
65 double mallocCount; /* number of times mem_dh->malloc has been called. */
66 double freeCount; /* number of times mem_dh->free has been called. */
67};
68
69
70#undef __FUNC__
71#define __FUNC__ "Mem_dhCreate"
72void
73Mem_dhCreate (Mem_dh * m)
74{
75 START_FUNC_DH
76 struct _mem_dh *tmp =
77 (struct _mem_dh *) PRIVATE_MALLOC (sizeof (struct _mem_dh));
78 CHECK_V_ERROR;
79 *m = tmp;
80 tmp->maxMem = 0.0;
81 tmp->curMem = 0.0;
82 tmp->totalMem = 0.0;
83 tmp->mallocCount = 0.0;
84 tmp->freeCount = 0.0;
85END_FUNC_DH}
86
87
88#undef __FUNC__
89#define __FUNC__ "Mem_dhDestroy"
90void
91Mem_dhDestroy (Mem_dh m)
92{
93 START_FUNC_DH if (Parser_dhHasSwitch (parser_dh, "-eu_mem"))
94 {
95 Mem_dhPrint (m, stdout, false);
96 CHECK_V_ERROR;
97 }
98
99 PRIVATE_FREE (m);
100END_FUNC_DH}
101
102
103#undef __FUNC__
104#define __FUNC__ "Mem_dhMalloc"
105void *
106Mem_dhMalloc (Mem_dh m, size_t size)
107{
108 START_FUNC_DH_2 void *retval;
109 memRecord_dh *tmp;
110 size_t s = size + 2 * sizeof (memRecord_dh);
111 void *address;
112
113 address = PRIVATE_MALLOC (s);
114
115 if (address == NULL)
116 {
117 sprintf (msgBuf_dh,
118 "PRIVATE_MALLOC failed; totalMem = %g; requested additional = %i",
119 m->totalMem, (int) s);
120 SET_ERROR (NULL, msgBuf_dh);
121 }
122
123 retval = (char *) address + sizeof (memRecord_dh);
124
125 /* we prepend and postpend a private record to the
126 * requested chunk of memory; this permits tracking the
127 * sizes of freed memory, along with other rudimentary
128 * error checking. This is modeled after the PETSc code.
129 */
130 tmp = (memRecord_dh *) address;
131 tmp->size = (double) s;
132
133 m->mallocCount += 1;
134 m->totalMem += (double) s;
135 m->curMem += (double) s;
136 m->maxMem = MAX (m->maxMem, m->curMem);
137
138END_FUNC_VAL_2 (retval)}
139
140
141#undef __FUNC__
142#define __FUNC__ "Mem_dhFree"
143void
144Mem_dhFree (Mem_dh m, void *ptr)
145{
146 START_FUNC_DH_2 double size;
147 char *tmp = (char *) ptr;
148 memRecord_dh *rec;
149 tmp -= sizeof (memRecord_dh);
150 rec = (memRecord_dh *) tmp;
151 size = rec->size;
152
153 mem_dh->curMem -= size;
154 mem_dh->freeCount += 1;
155
156 PRIVATE_FREE (tmp);
157END_FUNC_DH_2}
158
159
160#undef __FUNC__
161#define __FUNC__ "Mem_dhPrint"
162void
163Mem_dhPrint (Mem_dh m, FILE * fp, bool allPrint)
164{
165 START_FUNC_DH_2 if (fp == NULL)
166 SET_V_ERROR ("fp == NULL");
167 if (myid_dh == 0 || allPrint)
168 {
169 double tmp;
170 fprintf (fp, "---------------------- Euclid memory report (start)\n");
171 fprintf (fp, "malloc calls = %g\n", m->mallocCount);
172 fprintf (fp, "free calls = %g\n", m->freeCount);
173 fprintf (fp, "curMem = %g Mbytes (should be zero)\n",
174 m->curMem / 1000000);
175 tmp = m->totalMem / 1000000;
176 fprintf (fp, "total allocated = %g Mbytes\n", tmp);
177 fprintf (fp,
178 "max malloc = %g Mbytes (max allocated at any point in time)\n",
179 m->maxMem / 1000000);
180 fprintf (fp, "\n");
181 fprintf (fp, "---------------------- Euclid memory report (end)\n");
182 }
183END_FUNC_DH_2}