40 #include <sys/resource.h>
47 #include "BESMemoryGlobalArea.h"
48 #include "BESInternalFatalError.h"
51 #include "TheBESKeys.h"
53 int BESMemoryGlobalArea::_counter = 0;
54 unsigned long BESMemoryGlobalArea::_size = 0;
55 void* BESMemoryGlobalArea::_buffer = 0;
57 BESMemoryGlobalArea::BESMemoryGlobalArea()
62 if (_counter++ == 0) {
65 string key =
"BES.Memory.GlobalArea.";
79 if ((eps ==
"") || (mhs ==
"") || (verbose ==
"") || (control_heap ==
"")) {
80 string line =
"cannot determine memory keys.";
81 line += (string)
"Please set values for" +
" BES.Memory.GlobalArea.EmergencyPoolSize,"
82 +
" BES.Memory.GlobalArea.MaxiumumHeapSize," +
" BES.Memory.GlobalArea.Verbose, and"
83 +
" BES.Memory.GlobalArea.ControlHeap" +
" in the BES configuration file.";
87 if (verbose ==
"no") BESLog::TheLog()->
suspend();
89 unsigned int emergency = atol(eps.c_str());
91 if (control_heap ==
"yes") {
92 unsigned int max = atol(mhs.c_str());
94 LOG(
"Initialize emergency heap size to " << (
unsigned long)emergency <<
" and heap size to " << (
unsigned long)(max + 1) <<
" MB" << endl);
95 if (emergency > max) {
96 string s = string(
"BES: ") +
"unable to start since the emergency "
97 +
"pool is larger than the maximum size of " +
"the heap.\n";
101 log_limits(
"before setting limits: ");
102 limit.rlim_cur = megabytes(max + 1);
103 limit.rlim_max = megabytes(max + 1);
104 if (setrlimit( RLIMIT_DATA, &limit) < 0) {
105 string s = string(
"BES: ") +
"Could not set limit for the heap " +
"because " + strerror(errno)
107 if ( errno == EPERM) {
108 s = s +
"Attempting to increase the soft/hard " +
"limit above the current hard limit, "
109 +
"must be superuser\n";
114 log_limits(
"after setting limits: ");
116 _buffer = malloc(megabytes(max));
118 string s = string(
"BES: ") +
"cannot get heap of size " + mhs +
" to start running";
125 if (emergency > 10) {
126 string s =
"Emergency pool is larger than 10 Megabytes";
131 _size = megabytes(emergency);
133 _buffer = malloc(_size);
135 string s = (string)
"BES: cannot expand heap to " + eps +
" to start running";
142 cerr <<
"BES: unable to start properly because " << ex.
get_message() << endl;
146 cerr <<
"BES: unable to start: undefined exception happened\n";
151 BESLog::TheLog()->
resume();
154 BESMemoryGlobalArea::~BESMemoryGlobalArea()
156 if (--_counter == 0) {
157 if (_buffer) free(_buffer);
162 inline void BESMemoryGlobalArea::log_limits(
const string &msg)
164 if (getrlimit( RLIMIT_DATA, &limit) < 0) {
165 LOG(msg <<
"Could not get limits because " << strerror( errno) << endl);
169 if (limit.rlim_cur == RLIM_INFINITY)
170 LOG(msg <<
"BES heap size soft limit is infinite" << endl);
172 LOG(msg <<
"BES heap size soft limit is " << (
long int) limit.rlim_cur <<
" bytes ("
173 << (
long int) (limit.rlim_cur) / (MEGABYTE) <<
" MB - may be rounded up)" << endl);
174 if (limit.rlim_max == RLIM_INFINITY)
175 LOG(msg <<
"BES heap size hard limit is infinite" << endl);
177 LOG(
"BES heap size hard limit is " << (
long int) limit.rlim_max <<
" bytes ("
178 << (
long int) (limit.rlim_max) / (MEGABYTE) <<
" MB - may be rounded up)" << endl);
181 void BESMemoryGlobalArea::release_memory()
189 bool BESMemoryGlobalArea::reclaim_memory()
191 if (!_buffer) _buffer = malloc(_size);
207 strm << BESIndent::LMarg <<
"BESMemoryGlobalArea::dump - (" << (
void *)
this <<
")" << endl;
209 strm << BESIndent::LMarg <<
"area set? " << _counter << endl;
210 strm << BESIndent::LMarg <<
"emergency buffer: " << (
void *) _buffer << endl;
211 strm << BESIndent::LMarg <<
"buffer size: " << _size << endl;
212 strm << BESIndent::LMarg <<
"rlimit current: " << limit.rlim_cur << endl;
213 strm << BESIndent::LMarg <<
"rlimit max: " << limit.rlim_max << endl;
214 BESIndent::UnIndent();
Abstract exception class for the BES with basic string message.
virtual std::string get_message()
get the error message for this exception
exception thrown if an internal error is found and is fatal to the BES
void resume()
Resumes logging after being suspended.
void suspend()
Suspend logging of any information until resumed.
virtual void dump(std::ostream &strm) const
dumps information about this object
void get_value(const std::string &s, std::string &val, bool &found)
Retrieve the value of a given key, if set.
static TheBESKeys * TheKeys()