49 #include <grass/iostream/mm.h>
51 #define MM_DEBUG if(0)
56 MM_register::MM_register() {
60 cerr <<
"MM_register(): Only 1 instance of MM_register should exist.\n";
64 assert(instances == 1);
67 register_new = MM_IGNORE_MEMORY_EXCEEDED;
73 MM_register::~MM_register(
void) {
76 cerr <<
"MM_register(): Only 1 instance of MM_register should exist.\n";
80 assert(instances == 1);
86 void MM_register::print() {
88 size_t availMB = (remaining >> 20);
90 cout <<
"available memory: " << availMB <<
"MB "
91 <<
"(" << remaining <<
"B)"
94 cout <<
"available memory: " << remaining <<
"B, exceeding: "
95 << used - user_limit <<
"B"
103 MM_err MM_register::set_memory_limit (
size_t new_limit) {
105 assert( new_limit > 0);
106 if (used > new_limit) {
108 switch (register_new) {
109 case MM_ABORT_ON_MEMORY_EXCEEDED:
110 cerr <<
" MM_register::set_memory_limit to " << new_limit
111 <<
", used " << used <<
". allocation exceeds new limit.\n";
117 case MM_WARN_ON_MEMORY_EXCEEDED:
118 cerr <<
" MM_register::set_memory_limit to " << new_limit
119 <<
", used " << used <<
". allocation exceeds new limit.\n";
122 case MM_IGNORE_MEMORY_EXCEEDED:
125 user_limit = new_limit;
127 return MM_ERROR_NO_ERROR;
130 assert(used <= new_limit);
132 if (new_limit < user_limit) {
133 remaining -= user_limit - new_limit;
135 remaining += new_limit - user_limit;
137 user_limit = new_limit;
138 return MM_ERROR_NO_ERROR;
145 void MM_register::warn_memory_limit() {
146 register_new = MM_WARN_ON_MEMORY_EXCEEDED;
152 void MM_register::enforce_memory_limit() {
153 register_new = MM_ABORT_ON_MEMORY_EXCEEDED;
155 if (used > user_limit) {
156 cerr <<
" MM_register::enforce_memory_limit: limit=" << user_limit
157 <<
", used=" << used <<
". allocation exceeds limit.\n";
166 void MM_register::ignore_memory_limit() {
167 register_new = MM_IGNORE_MEMORY_EXCEEDED;
173 MM_mode MM_register::get_limit_mode() {
179 void MM_register::print_limit_mode() {
180 cout <<
"Memory manager registering memory in ";
181 switch (register_new) {
182 case MM_ABORT_ON_MEMORY_EXCEEDED:
183 cout <<
"MM_ABORT_ON_MEMORY_EXCEEDED";
185 case MM_WARN_ON_MEMORY_EXCEEDED:
186 cout <<
"MM_WARN_ON_MEMORY_EXCEEDED";
188 case MM_IGNORE_MEMORY_EXCEEDED:
189 cout <<
"MM_IGNORE_MEMORY_EXCEEDED";
192 cout <<
" mode." << endl;
200 size_t MM_register::memory_available() {
205 size_t MM_register::memory_used() {
211 size_t MM_register::memory_limit() {
224 static const size_t SIZE_SPACE=(
sizeof(size_t) > 8 ?
sizeof(
size_t) : 8);
228 int MM_register::space_overhead () {
238 MM_err MM_register::register_allocation(
size_t request) {
240 if (request > remaining) {
243 return MM_ERROR_INSUFFICIENT_SPACE;
247 remaining -= request;
248 return MM_ERROR_NO_ERROR;
258 MM_err MM_register::register_deallocation(
size_t sz) {
262 remaining = user_limit;
263 return MM_ERROR_UNDERFLOW;
267 if (used < user_limit) {
268 remaining = user_limit - used;
270 assert(remaining == 0);
272 return MM_ERROR_NO_ERROR;
279 void*
operator new[] (
size_t sz)
throw(std::bad_alloc) {
282 MM_DEBUG cout <<
"new: sz=" << sz <<
", register "
283 << sz+SIZE_SPACE <<
"B ,";
285 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
289 case MM_ABORT_ON_MEMORY_EXCEEDED:
290 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. "
291 <<
"allocating " << sz <<
"B. "
292 <<
"limit exceeded by "
299 case MM_WARN_ON_MEMORY_EXCEEDED:
300 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. "
301 <<
"allocating " << sz <<
"B. "
302 <<
" limit exceeded by "
307 case MM_IGNORE_MEMORY_EXCEEDED:
312 p = malloc(sz + SIZE_SPACE);
315 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
320 *((
size_t *) p) = sz;
322 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
324 return ((
char *) p) + SIZE_SPACE;
330 void*
operator new (
size_t sz)
throw(std::bad_alloc) {
333 MM_DEBUG cout <<
"new: sz=" << sz <<
", register "
334 << sz+SIZE_SPACE <<
"B ,";
336 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
340 case MM_ABORT_ON_MEMORY_EXCEEDED:
341 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. "
342 <<
"allocating " << sz <<
"B. "
343 <<
"limit exceeded by "
350 case MM_WARN_ON_MEMORY_EXCEEDED:
351 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. "
352 <<
"allocating " << sz <<
"B. "
353 <<
" limit exceeded by "
358 case MM_IGNORE_MEMORY_EXCEEDED:
363 p = malloc(sz + SIZE_SPACE);
366 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
371 *((
size_t *) p) = sz;
373 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
375 return ((
char *) p) + SIZE_SPACE;
382 void operator delete (
void *ptr)
throw() {
386 MM_DEBUG cout <<
"delete: ptr=" << ptr <<
",";
389 cerr <<
"MM warning: operator delete was given a NULL pointer\n";
402 p = ((
char *)ptr) - SIZE_SPACE;
405 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate "
406 << sz + SIZE_SPACE << endl;
408 if(
MM_manager.register_deallocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
410 cerr <<
"delete: MM_manager.register_deallocation failed\n";
422 void operator delete[] (
void *ptr)
throw() {
426 MM_DEBUG cout <<
"delete[]: ptr=" << ptr <<
",";
430 cerr <<
"MM warning: operator delete [] was given a NULL pointer\n";
437 p = ((
char *)ptr) - SIZE_SPACE;
440 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate "
441 << sz + SIZE_SPACE << endl;
443 if(
MM_manager.register_deallocation (sz + SIZE_SPACE)!= MM_ERROR_NO_ERROR){
445 cerr <<
"delete[]: MM_manager.register_deallocation failed\n";
461 int MM_register::instances = 0;
463 MM_mode MM_register::register_new = MM_IGNORE_MEMORY_EXCEEDED;
478 mm_register_init::mm_register_init(
void) {
480 MM_manager.set_memory_limit(MM_DEFAULT_MM_SIZE);
484 mm_register_init::~mm_register_init(
void) {