Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
ElmerCSC
GitHub Repository: ElmerCSC/elmerfem
Path: blob/devel/ElmerGUI/netgen/libsrc/general/moveablemem.cpp
3206 views
1
#include <iostream>
2
#include <iomanip>
3
4
#include <myadt.hpp>
5
using namespace std;
6
namespace netgen
7
{
8
9
NgMutex mem_mutex;
10
11
size_t BaseMoveableMem::totalsize = 0; // 500000000;
12
size_t BaseMoveableMem::used = 0;
13
char * BaseMoveableMem::largeblock = 0;
14
15
BaseMoveableMem * BaseMoveableMem::first = 0;
16
BaseMoveableMem * BaseMoveableMem::last = 0;
17
18
19
BaseMoveableMem :: BaseMoveableMem (size_t s)
20
{
21
// cout << "Construct object begin" << endl;
22
// Print ();
23
24
prev = last;
25
next = 0;
26
27
if (last) last->next = this;
28
last = this;
29
if (!first) first = this;
30
31
size = 0;
32
33
if (prev)
34
pos = prev->pos + prev->size;
35
else
36
pos = 0;
37
38
ptr = 0;
39
name = NULL;
40
41
if (s) Alloc(s);
42
}
43
44
BaseMoveableMem :: ~BaseMoveableMem () throw()
45
{
46
Free();
47
48
if (next) next->prev = prev;
49
else last = prev;
50
if (prev) prev->next = next;
51
else first = next;
52
53
if(name != NULL)
54
{
55
delete [] name;
56
name = NULL;
57
}
58
}
59
60
void BaseMoveableMem :: SetName (const char * aname)
61
{
62
if(name != NULL)
63
{
64
delete [] name;
65
name = NULL;
66
}
67
if (aname)
68
{
69
name = new char[strlen(aname)+1];
70
strcpy (name, aname);
71
}
72
}
73
74
75
void BaseMoveableMem :: Alloc (size_t s)
76
{
77
if (totalsize == 0)
78
{
79
size = s;
80
//ptr = (char*) malloc(s);
81
ptr = new char[s];
82
83
if (!ptr)
84
{
85
cerr << "BaseynamicMem, cannot allocate " << s << " bytes" << endl;
86
Print ();
87
throw ("BaseDynamicMem::Alloc: out of memory");
88
}
89
90
return;
91
}
92
93
94
used += s - size;
95
96
size_t r = s % 8;
97
if (r) s += 8-r;
98
if (prev)
99
pos = prev->pos + prev->size;
100
else
101
pos = 0;
102
size = s;
103
104
if (next)
105
{
106
NgLock lock(mem_mutex);
107
lock.Lock();
108
try
109
{
110
next->MoveTo (pos+size);
111
}
112
catch (NgException e)
113
{
114
lock.UnLock();
115
throw NgException ("MoveableMem overflow");
116
}
117
lock.UnLock();
118
}
119
120
if (size)
121
{
122
if (!largeblock)
123
{
124
cout << "moveable memory: allocate large block of "
125
<< totalsize / 1048576 << " MB" << endl;
126
// largeblock = new char[totalsize];
127
// largeblock = (char*)malloc (totalsize);
128
largeblock = new char[totalsize];
129
}
130
ptr = largeblock+pos;
131
132
if (pos + size > totalsize)
133
throw NgException ("MoveableMem overflow");
134
}
135
else
136
ptr = 0;
137
}
138
139
void BaseMoveableMem :: ReAlloc (size_t s)
140
{
141
if (totalsize == 0)
142
{
143
if (size == s) return;
144
145
char * old = ptr;
146
ptr = new char[s];
147
148
if (!ptr)
149
{
150
cerr << "BaseynamicMem, cannot Reallocate " << s << " bytes" << endl;
151
Print ();
152
throw ("BaseDynamicMem::Alloc: out of memory");
153
}
154
155
156
157
memmove (ptr, old, (s < size) ? s : size);
158
//free (old);
159
delete [] old;
160
size = s;
161
return;
162
}
163
164
Alloc (s);
165
}
166
167
void BaseMoveableMem :: MoveTo (size_t newpos)
168
{
169
// cout << "move block, oldpos = " << pos << "; newpos = " << newpos
170
// << ", size = " << size << endl;
171
static size_t move = 0;
172
173
if (newpos + size > totalsize)
174
throw NgException ("MoveableMem overflow");
175
if (newpos > pos)
176
{
177
if (next) next->MoveTo (newpos+size);
178
memmove (largeblock+newpos, largeblock+pos, size);
179
move += size;
180
}
181
else if (newpos < pos)
182
{
183
// cout << "move down: " << size << endl;
184
memmove (largeblock+newpos, largeblock+pos, size);
185
if (next) next->MoveTo (newpos+size);
186
move += size;
187
}
188
pos = newpos;
189
ptr = largeblock+pos;
190
// cout << "total move: " << move << endl;
191
}
192
193
void BaseMoveableMem :: Free () throw()
194
{
195
if (totalsize == 0)
196
{
197
//free (ptr);
198
delete [] ptr;
199
ptr = 0;
200
return;
201
}
202
203
/*
204
cout << "free block, pos = " << pos << "size = " << size << endl;
205
cout << "before: " << endl;
206
Print();
207
*/
208
used -= size;
209
if (next)
210
{
211
NgLock lock(mem_mutex);
212
lock.Lock();
213
next->MoveTo (pos);
214
lock.UnLock();
215
}
216
217
size = 0;
218
ptr = 0;
219
// pos = 0;
220
}
221
222
void BaseMoveableMem :: Swap (BaseMoveableMem & m2) throw()
223
{
224
size_t hi;
225
// BaseMoveableMem * hp;
226
char * cp;
227
hi = size; size = m2.size; m2.size = hi;
228
hi = pos; pos = m2.pos; m2.pos = hi;
229
/*
230
hp = prev; prev = m2.prev; m2.prev = hp;
231
hp = next; next = m2.next; m2.next = hp;
232
*/
233
cp = ptr; ptr = m2.ptr; m2.ptr = cp;
234
cp = name; name = m2.name; m2.name = cp;
235
}
236
237
238
void BaseMoveableMem :: Print ()
239
{
240
cout << "****************** Moveable Mem Report ****************" << endl;
241
BaseMoveableMem * p = first;
242
long int mem = 0;
243
int cnt = 0;
244
while (p)
245
{
246
mem += long(p->size);
247
cnt++;
248
249
cout << setw(10) << p->size << " Bytes";
250
cout << ", pos = " << p->pos;
251
cout << ", addr = " << (void*)p->ptr;
252
if (p->name)
253
cout << " in block " << p->name;
254
cout << endl;
255
256
p = p->next;
257
}
258
259
if (mem > 100000000)
260
cout << "memory in moveable arena: " << mem/1048576 << " MB" << endl;
261
else if (mem > 100000)
262
cout << "memory in moveable arena: " << mem/1024 << " kB" << endl;
263
else
264
cout << "memory in moveable arena: " << mem << " Bytes" << endl;
265
cout << "number of blocks: " << cnt << endl;
266
267
cout << " used = " << used << endl;
268
// cout << "******************************************************" << endl;
269
}
270
271
}
272
273