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;
284 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 285 void* MM_register::operator
new[] (
size_t sz)
throw (std::bad_alloc) {
287 void* MM_register::operator
new[] (
size_t sz) {
291 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " 292 << sz+SIZE_SPACE <<
"B ,";
294 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
298 case MM_ABORT_ON_MEMORY_EXCEEDED:
299 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. " 300 <<
"allocating " << sz <<
"B. " 301 <<
"limit exceeded by " 308 case MM_WARN_ON_MEMORY_EXCEEDED:
309 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. " 310 <<
"allocating " << sz <<
"B. " 311 <<
" limit exceeded by " 316 case MM_IGNORE_MEMORY_EXCEEDED:
321 p = malloc(sz + SIZE_SPACE);
324 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
329 *((
size_t *) p) = sz;
331 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
333 return ((
char *) p) + SIZE_SPACE;
339 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 340 void* MM_register::operator
new (
size_t sz)
throw (std::bad_alloc) {
342 void* MM_register::operator
new (
size_t sz) {
346 MM_DEBUG cout <<
"new: sz=" << sz <<
", register " 347 << sz+SIZE_SPACE <<
"B ,";
349 if (
MM_manager.register_allocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
353 case MM_ABORT_ON_MEMORY_EXCEEDED:
354 cerr <<
"MM error: limit ="<<
MM_manager.memory_limit() <<
"B. " 355 <<
"allocating " << sz <<
"B. " 356 <<
"limit exceeded by " 363 case MM_WARN_ON_MEMORY_EXCEEDED:
364 cerr <<
"MM warning: limit="<<
MM_manager.memory_limit() <<
"B. " 365 <<
"allocating " << sz <<
"B. " 366 <<
" limit exceeded by " 371 case MM_IGNORE_MEMORY_EXCEEDED:
376 p = malloc(sz + SIZE_SPACE);
379 cerr <<
"new: out of memory while allocating " << sz <<
"B" << endl;
384 *((
size_t *) p) = sz;
386 MM_DEBUG cout <<
"ptr=" << (
void*) (((
char *) p) + SIZE_SPACE) << endl;
388 return ((
char *) p) + SIZE_SPACE;
395 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 396 void MM_register::operator
delete (
void *ptr)
throw() {
398 void MM_register::operator
delete (
void *ptr) noexcept {
403 MM_DEBUG cout <<
"delete: ptr=" << ptr <<
",";
406 cerr <<
"MM warning: operator delete was given a NULL pointer\n";
422 p = ((
char *)ptr) - SIZE_SPACE;
425 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate " 426 << sz + SIZE_SPACE << endl;
428 if(
MM_manager.register_deallocation (sz + SIZE_SPACE) != MM_ERROR_NO_ERROR){
430 cerr <<
"delete: MM_manager.register_deallocation failed\n";
442 #ifdef GRASS_MM_USE_EXCEPTION_SPECIFIER 443 void MM_register::operator
delete[] (
void *ptr)
throw() {
445 void MM_register::operator
delete[] (
void *ptr) noexcept {
450 MM_DEBUG cout <<
"delete[]: ptr=" << ptr <<
",";
454 cerr <<
"MM warning: operator delete [] was given a NULL pointer\n";
464 p = ((
char *)ptr) - SIZE_SPACE;
467 MM_DEBUG cout <<
"size=" << sz <<
", free " << p <<
"B and deallocate " 468 << sz + SIZE_SPACE << endl;
470 if(
MM_manager.register_deallocation (sz + SIZE_SPACE)!= MM_ERROR_NO_ERROR){
472 cerr <<
"delete[]: MM_manager.register_deallocation failed\n";
488 int MM_register::instances = 0;
490 MM_mode MM_register::register_new = MM_IGNORE_MEMORY_EXCEEDED;
505 mm_register_init::mm_register_init(
void) {
507 MM_manager.set_memory_limit(MM_DEFAULT_MM_SIZE);
511 mm_register_init::~mm_register_init(
void) {