BESMemoryGlobalArea.cc
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include <iostream>
00034 #include <cstdlib>
00035 #include <cstring>
00036 #include <cerrno>
00037
00038 using std::cerr ;
00039 using std::endl ;
00040
00041 #include "BESMemoryGlobalArea.h"
00042 #include "BESInternalFatalError.h"
00043 #include "BESDebug.h"
00044 #include "BESLog.h"
00045 #include "TheBESKeys.h"
00046
00047 int BESMemoryGlobalArea::_counter = 0 ;
00048 unsigned long BESMemoryGlobalArea::_size = 0 ;
00049 void* BESMemoryGlobalArea::_buffer = 0 ;
00050
00051 BESMemoryGlobalArea::BESMemoryGlobalArea()
00052 {
00053 if( _counter++ == 0 )
00054 {
00055 try
00056 {
00057 bool fnd = false ;
00058 string key = "BES.Memory.GlobalArea." ;
00059 string eps =
00060 TheBESKeys::TheKeys()->get_key( key + "EmergencyPoolSize", fnd);
00061 string mhs =
00062 TheBESKeys::TheKeys()->get_key( key + "MaximumHeapSize", fnd ) ;
00063 string verbose =
00064 TheBESKeys::TheKeys()->get_key( key + "Verbose", fnd ) ;
00065 string control_heap =
00066 TheBESKeys::TheKeys()->get_key( key + "ControlHeap", fnd ) ;
00067 if( (eps=="") || (mhs=="") || (verbose=="") || (control_heap=="") )
00068 {
00069 string line = "cannot determine memory keys." ;
00070 line += (string)"Please set values for"
00071 + " BES.Memory.GlobalArea.EmergencyPoolSize,"
00072 + " BES.Memory.GlobalArea.MaxiumumHeapSize,"
00073 + " BES.Memory.GlobalArea.Verbose, and"
00074 + " BES.Memory.GlobalArea.ControlHeap" ;
00075 throw BESInternalFatalError( line, __FILE__, __LINE__ ) ;
00076 }
00077 else
00078 {
00079 if( verbose=="no" )
00080 BESLog::TheLog()->suspend();
00081
00082 unsigned int emergency=atol(eps.c_str());
00083
00084 if( control_heap == "yes" )
00085 {
00086 unsigned int max = atol(mhs.c_str());
00087 BESDEBUG( "bes", "Initializing emergency heap to "
00088 << (long int)emergency << " MB" << endl )
00089 BESDEBUG( "bes", "Initializing max heap size to "
00090 << (long int)(max+1) << " MB" << endl )
00091 (*BESLog::TheLog()) << "Initialize emergency heap size to "
00092 << (long int)emergency
00093 << " and heap size to ";
00094 (*BESLog::TheLog()) << (long int)(max+1)
00095 << " megabytes" << endl ;
00096 if( emergency > max )
00097 {
00098 string s = string ( "BES: " )
00099 + "unable to start since the emergency "
00100 + "pool is larger than the maximum size of "
00101 + "the heap.\n" ;
00102 (*BESLog::TheLog()) << s ;
00103 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00104 }
00105 log_limits( "before setting limits: " ) ;
00106 limit.rlim_cur = megabytes( max + 1 ) ;
00107 limit.rlim_max = megabytes( max + 1 ) ;
00108
00109
00110
00111
00112
00113
00114
00115 if( setrlimit( RLIMIT_DATA, &limit ) < 0 )
00116 {
00117 string s = string( "BES: " )
00118 + "Could not set limit for the heap "
00119 + "because " + strerror(errno) + "\n" ;
00120 if( errno == EPERM )
00121 {
00122 s = s + "Attempting to increase the soft/hard "
00123 + "limit above the current hard limit, "
00124 + "must be superuser\n" ;
00125 }
00126 (*BESLog::TheLog()) << s ;
00127 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00128 }
00129 log_limits( "after setting limits: " ) ;
00130 _buffer = 0 ;
00131 _buffer = malloc( megabytes( max ) ) ;
00132 if( !_buffer )
00133 {
00134 string s = string( "BES: " )
00135 + "cannot get heap of size "
00136 + mhs + " to start running" ;
00137 (*BESLog::TheLog()) << s ;
00138 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00139 }
00140 free( _buffer ) ;
00141 }
00142 else
00143 {
00144 if( emergency > 10 )
00145 {
00146 string s = "Emergency pool is larger than 10 Megabytes";
00147 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00148 }
00149 }
00150
00151 _size = megabytes( emergency ) ;
00152 _buffer = 0 ;
00153 _buffer = malloc( _size ) ;
00154 if( !_buffer )
00155 {
00156 string s = (string)"BES: cannot expand heap to "
00157 + eps + " to start running" ;
00158 (*BESLog::TheLog()) << s << endl ;
00159 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00160 }
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172 }
00173 }
00174 catch( BESError &ex )
00175 {
00176 cerr << "BES: unable to start properly because "
00177 << ex.get_message()
00178 << endl ;
00179 exit(1) ;
00180 }
00181 catch(...)
00182 {
00183 cerr << "BES: unable to start: undefined exception happened\n" ;
00184 exit(1) ;
00185 }
00186 }
00187 BESLog::TheLog()->resume();
00188 }
00189
00190 BESMemoryGlobalArea::~BESMemoryGlobalArea()
00191 {
00192 if (--_counter == 0)
00193 {
00194 if (_buffer)
00195 free( _buffer ) ;
00196 _buffer = 0 ;
00197 }
00198 }
00199
00200 inline void
00201 BESMemoryGlobalArea::log_limits( const string &msg )
00202 {
00203 if( getrlimit( RLIMIT_DATA, &limit ) < 0 )
00204 {
00205 (*BESLog::TheLog()) << msg << "Could not get limits because "
00206 << strerror( errno ) << endl ;
00207 _counter-- ;
00208 throw BESInternalFatalError( strerror( errno ), __FILE__, __LINE__ ) ;
00209 }
00210 if( limit.rlim_cur == RLIM_INFINITY )
00211 (*BESLog::TheLog()) << msg << "heap size soft limit is infinte"
00212 << endl ;
00213 else
00214 (*BESLog::TheLog()) << msg << "heap size soft limit is "
00215 << (long int)limit.rlim_cur
00216 << " bytes ("
00217 << (long int)(limit.rlim_cur)/(MEGABYTE)
00218 << " MB - may be rounded up)" << endl ;
00219 if( limit.rlim_max == RLIM_INFINITY )
00220 (*BESLog::TheLog()) << msg << "heap size hard limit is infinite"
00221 << endl ;
00222 else
00223 (*BESLog::TheLog()) << msg << "heap size hard limit is "
00224 << (long int)limit.rlim_max
00225 << " bytes ("
00226 << (long int)(limit.rlim_cur)/(MEGABYTE)
00227 << " MB - may be rounded up)" << endl ;
00228 }
00229
00230 void
00231 BESMemoryGlobalArea::release_memory()
00232 {
00233 if( _buffer )
00234 {
00235 free( _buffer ) ;
00236 _buffer = 0 ;
00237 }
00238 }
00239
00240 bool
00241 BESMemoryGlobalArea::reclaim_memory()
00242 {
00243 if( !_buffer )
00244 _buffer = malloc( _size ) ;
00245 if( _buffer )
00246 return true ;
00247 else
00248 return false ;
00249 }
00250
00258 void
00259 BESMemoryGlobalArea::dump( ostream &strm ) const
00260 {
00261 strm << BESIndent::LMarg << "BESMemoryGlobalArea::dump - ("
00262 << (void *)this << ")" << endl ;
00263 BESIndent::Indent() ;
00264 strm << BESIndent::LMarg << "area set? " << _counter << endl ;
00265 strm << BESIndent::LMarg << "emergency buffer: "
00266 << (void *)_buffer << endl ;
00267 strm << BESIndent::LMarg << "buffer size: " << _size << endl ;
00268 strm << BESIndent::LMarg << "rlimit current: " << limit.rlim_cur << endl ;
00269 strm << BESIndent::LMarg << "rlimit max: " << limit.rlim_max << endl ;
00270 BESIndent::UnIndent() ;
00271 }
00272