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 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 280 void*
operator new[] (
size_t sz)
throw (std::bad_alloc) {
282 void*
operator new[] (
size_t sz) {
286 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " 287 << sz+SIZE_SPACE <<
"B ,";
289 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
293 case MM_ABORT_ON_MEMORY_EXCEEDED:
294 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. " 295 <<
"allocating " << sz <<
"B. " 296 <<
"limit exceeded by " 303 case MM_WARN_ON_MEMORY_EXCEEDED:
304 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. " 305 <<
"allocating " << sz <<
"B. " 306 <<
" limit exceeded by " 311 case MM_IGNORE_MEMORY_EXCEEDED:
316 p = malloc(sz + SIZE_SPACE);
319 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
324 *((
size_t *) p) = sz;
326 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
328 return ((
char *) p) + SIZE_SPACE;
334 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 335 void*
operator new (
size_t sz)
throw (std::bad_alloc) {
337 void*
operator new (
size_t sz) {
341 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " 342 << sz+SIZE_SPACE <<
"B ,";
344 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
348 case MM_ABORT_ON_MEMORY_EXCEEDED:
349 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. " 350 <<
"allocating " << sz <<
"B. " 351 <<
"limit exceeded by " 358 case MM_WARN_ON_MEMORY_EXCEEDED:
359 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. " 360 <<
"allocating " << sz <<
"B. " 361 <<
" limit exceeded by " 366 case MM_IGNORE_MEMORY_EXCEEDED:
371 p = malloc(sz + SIZE_SPACE);
374 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
379 *((
size_t *) p) = sz;
381 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
383 return ((
char *) p) + SIZE_SPACE;
390 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 391 void operator delete (
void *ptr)
throw() {
393 void operator delete (
void *ptr) noexcept {
398 MM_DEBUG cout <<
"delete: ptr=" << ptr <<
",";
401 cerr <<
"MM warning: operator delete was given a NULL pointer\n";
414 p = ((
char *)ptr) - SIZE_SPACE;
417 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate " 418 << sz + SIZE_SPACE << endl;
420 if(
MM_manager.register_deallocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
422 cerr <<
"delete: MM_manager.register_deallocation failed\n";
434 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 435 void operator delete[] (
void *ptr)
throw() {
437 void operator delete[] (
void *ptr) noexcept {
442 MM_DEBUG cout <<
"delete[]: ptr=" << ptr <<
",";
446 cerr <<
"MM warning: operator delete [] was given a NULL pointer\n";
453 p = ((
char *)ptr) - SIZE_SPACE;
456 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate " 457 << sz + SIZE_SPACE << endl;
459 if(
MM_manager.register_deallocation (sz + SIZE_SPACE)!= MM_ERROR_NO_ERROR){
461 cerr <<
"delete[]: MM_manager.register_deallocation failed\n";
477 int MM_register::instances = 0;
479 MM_mode MM_register::register_new = MM_IGNORE_MEMORY_EXCEEDED;
494 mm_register_init::mm_register_init(
void) {
496 MM_manager.set_memory_limit(MM_DEFAULT_MM_SIZE);
500 mm_register_init::~mm_register_init(
void) {