47#include <grass/iostream/mm.h>
49#define MM_DEBUG if (0)
52MM_register::MM_register()
57 cerr <<
"MM_register(): Only 1 instance of MM_register should exist.\n";
64 register_new = MM_IGNORE_MEMORY_EXCEEDED;
68MM_register::~MM_register(
void)
72 cerr <<
"MM_register(): Only 1 instance of MM_register should exist.\n";
81void MM_register::print()
84 size_t availMB = (remaining >> 20);
86 cout <<
"available memory: " << availMB <<
"MB "
87 <<
"(" << remaining <<
"B)" << endl;
90 cout <<
"available memory: " << remaining
91 <<
"B, exceeding: " << used - user_limit <<
"B" << endl;
97MM_err MM_register::set_memory_limit(
size_t new_limit)
101 if (used > new_limit) {
103 switch (register_new) {
104 case MM_ABORT_ON_MEMORY_EXCEEDED:
105 cerr <<
" MM_register::set_memory_limit to " << new_limit
106 <<
", used " << used <<
". allocation exceeds new limit.\n";
112 case MM_WARN_ON_MEMORY_EXCEEDED:
113 cerr <<
" MM_register::set_memory_limit to " << new_limit
114 <<
", used " << used <<
". allocation exceeds new limit.\n";
117 case MM_IGNORE_MEMORY_EXCEEDED:
120 user_limit = new_limit;
122 return MM_ERROR_NO_ERROR;
125 assert(used <= new_limit);
127 if (new_limit < user_limit) {
128 remaining -= user_limit - new_limit;
131 remaining += new_limit - user_limit;
133 user_limit = new_limit;
134 return MM_ERROR_NO_ERROR;
139void MM_register::warn_memory_limit()
141 register_new = MM_WARN_ON_MEMORY_EXCEEDED;
146void MM_register::enforce_memory_limit()
148 register_new = MM_ABORT_ON_MEMORY_EXCEEDED;
150 if (used > user_limit) {
151 cerr <<
" MM_register::enforce_memory_limit: limit=" << user_limit
152 <<
", used=" << used <<
". allocation exceeds limit.\n";
160void MM_register::ignore_memory_limit()
162 register_new = MM_IGNORE_MEMORY_EXCEEDED;
167MM_mode MM_register::get_limit_mode()
174void MM_register::print_limit_mode()
176 cout <<
"Memory manager registering memory in ";
177 switch (register_new) {
178 case MM_ABORT_ON_MEMORY_EXCEEDED:
179 cout <<
"MM_ABORT_ON_MEMORY_EXCEEDED";
181 case MM_WARN_ON_MEMORY_EXCEEDED:
182 cout <<
"MM_WARN_ON_MEMORY_EXCEEDED";
184 case MM_IGNORE_MEMORY_EXCEEDED:
185 cout <<
"MM_IGNORE_MEMORY_EXCEEDED";
188 cout <<
" mode." << endl;
194size_t MM_register::memory_available()
200size_t MM_register::memory_used()
206size_t MM_register::memory_limit()
218static const size_t SIZE_SPACE = (
sizeof(size_t) > 8 ?
sizeof(
size_t) : 8);
220int MM_register::space_overhead()
228MM_err MM_register::register_allocation(
size_t request)
231 if (request > remaining) {
234 return MM_ERROR_INSUFFICIENT_SPACE;
238 remaining -= request;
239 return MM_ERROR_NO_ERROR;
247MM_err MM_register::register_deallocation(
size_t sz)
252 remaining = user_limit;
253 return MM_ERROR_UNDERFLOW;
258 if (used < user_limit) {
259 remaining = user_limit - used;
264 return MM_ERROR_NO_ERROR;
274#ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER
275void *MM_register::operator
new[](
size_t sz)
throw(std::bad_alloc)
278void *MM_register::operator
new[](
size_t sz)
283 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " << sz + SIZE_SPACE
286 if (
MM_manager.register_allocation(sz + SIZE_SPACE) != MM_ERROR_NO_ERROR) {
290 case MM_ABORT_ON_MEMORY_EXCEEDED:
291 cerr <<
"MM error: limit =" <<
MM_manager.memory_limit() <<
"B. "
292 <<
"allocating " << sz <<
"B. "
293 <<
"limit exceeded by "
300 case MM_WARN_ON_MEMORY_EXCEEDED:
301 cerr <<
"MM warning: limit=" <<
MM_manager.memory_limit() <<
"B. "
302 <<
"allocating " << sz <<
"B. "
303 <<
" limit exceeded by "
308 case MM_IGNORE_MEMORY_EXCEEDED:
313 p = malloc(sz + SIZE_SPACE);
316 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
323 MM_DEBUG cout <<
"ptr=" << (
void *)(((
char *)p) + SIZE_SPACE) << endl;
325 return ((
char *)p) + SIZE_SPACE;
329#ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER
330void *MM_register::operator
new(
size_t sz)
throw(std::bad_alloc)
333void *MM_register::operator
new(
size_t sz)
338 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " << sz + SIZE_SPACE
341 if (
MM_manager.register_allocation(sz + SIZE_SPACE) != MM_ERROR_NO_ERROR) {
345 case MM_ABORT_ON_MEMORY_EXCEEDED:
346 cerr <<
"MM error: limit =" <<
MM_manager.memory_limit() <<
"B. "
347 <<
"allocating " << sz <<
"B. "
348 <<
"limit exceeded by "
355 case MM_WARN_ON_MEMORY_EXCEEDED:
356 cerr <<
"MM warning: limit=" <<
MM_manager.memory_limit() <<
"B. "
357 <<
"allocating " << sz <<
"B. "
358 <<
" limit exceeded by "
363 case MM_IGNORE_MEMORY_EXCEEDED:
368 p = malloc(sz + SIZE_SPACE);
371 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
378 MM_DEBUG cout <<
"ptr=" << (
void *)(((
char *)p) + SIZE_SPACE) << endl;
380 return ((
char *)p) + SIZE_SPACE;
384#ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER
385void MM_register::operator
delete(
void *ptr)
throw()
388void MM_register::operator
delete(
void *ptr)
noexcept
394 MM_DEBUG cout <<
"delete: ptr=" << ptr <<
",";
397 cerr <<
"MM warning: operator delete was given a NULL pointer\n";
413 p = ((
char *)ptr) - SIZE_SPACE;
416 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate "
417 << sz + SIZE_SPACE << endl;
419 if (
MM_manager.register_deallocation(sz + SIZE_SPACE) !=
422 cerr <<
"delete: MM_manager.register_deallocation failed\n";
431#ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER
432void MM_register::operator
delete[](
void *ptr)
throw()
435void MM_register::operator
delete[](
void *ptr)
noexcept
441 MM_DEBUG cout <<
"delete[]: ptr=" << ptr <<
",";
445 cerr <<
"MM warning: operator delete [] was given a NULL pointer\n";
455 p = ((
char *)ptr) - SIZE_SPACE;
458 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate "
459 << sz + SIZE_SPACE << endl;
461 if (
MM_manager.register_deallocation(sz + SIZE_SPACE) !=
464 cerr <<
"delete[]: MM_manager.register_deallocation failed\n";
476int MM_register::instances = 0;
478MM_mode MM_register::register_new = MM_IGNORE_MEMORY_EXCEEDED;
484unsigned int mm_register_init::count;
488mm_register_init::mm_register_init(
void)
491 MM_manager.set_memory_limit(MM_DEFAULT_MM_SIZE);
495mm_register_init::~mm_register_init(
void)
#define assert(condition)