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
00060 string eps ;
00061 TheBESKeys::TheKeys()->get_value( key + "EmergencyPoolSize",
00062 eps, fnd ) ;
00063
00064 string mhs ;
00065 TheBESKeys::TheKeys()->get_value( key + "MaximumHeapSize",
00066 mhs, fnd ) ;
00067
00068 string verbose ;
00069 TheBESKeys::TheKeys()->get_value( key + "Verbose",
00070 verbose, fnd ) ;
00071
00072 string control_heap ;
00073 TheBESKeys::TheKeys()->get_value( key + "ControlHeap",
00074 control_heap, fnd ) ;
00075
00076 if( (eps=="") || (mhs=="") || (verbose=="") || (control_heap=="") )
00077 {
00078 string line = "cannot determine memory keys." ;
00079 line += (string)"Please set values for"
00080 + " BES.Memory.GlobalArea.EmergencyPoolSize,"
00081 + " BES.Memory.GlobalArea.MaxiumumHeapSize,"
00082 + " BES.Memory.GlobalArea.Verbose, and"
00083 + " BES.Memory.GlobalArea.ControlHeap"
00084 + " in the BES configuration file." ;
00085 throw BESInternalFatalError( line, __FILE__, __LINE__ ) ;
00086 }
00087 else
00088 {
00089 if( verbose=="no" )
00090 BESLog::TheLog()->suspend();
00091
00092 unsigned int emergency=atol(eps.c_str());
00093
00094 if( control_heap == "yes" )
00095 {
00096 unsigned int max = atol(mhs.c_str());
00097 BESDEBUG( "bes", "Initializing emergency heap to "
00098 << (long int)emergency << " MB" << endl ) ;
00099 BESDEBUG( "bes", "Initializing max heap size to "
00100 << (long int)(max+1) << " MB" << endl ) ;
00101 (*BESLog::TheLog()) << "Initialize emergency heap size to "
00102 << (long int)emergency
00103 << " and heap size to " ;
00104 (*BESLog::TheLog()) << (long int)(max+1)
00105 << " megabytes" << endl ;
00106 if( emergency > max )
00107 {
00108 string s = string ( "BES: " )
00109 + "unable to start since the emergency "
00110 + "pool is larger than the maximum size of "
00111 + "the heap.\n" ;
00112 (*BESLog::TheLog()) << s ;
00113 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00114 }
00115 log_limits( "before setting limits: " ) ;
00116 limit.rlim_cur = megabytes( max + 1 ) ;
00117 limit.rlim_max = megabytes( max + 1 ) ;
00118
00119
00120
00121
00122
00123
00124
00125 if( setrlimit( RLIMIT_DATA, &limit ) < 0 )
00126 {
00127 string s = string( "BES: " )
00128 + "Could not set limit for the heap "
00129 + "because " + strerror(errno) + "\n" ;
00130 if( errno == EPERM )
00131 {
00132 s = s + "Attempting to increase the soft/hard "
00133 + "limit above the current hard limit, "
00134 + "must be superuser\n" ;
00135 }
00136 (*BESLog::TheLog()) << s ;
00137 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00138 }
00139 log_limits( "after setting limits: " ) ;
00140 _buffer = 0 ;
00141 _buffer = malloc( megabytes( max ) ) ;
00142 if( !_buffer )
00143 {
00144 string s = string( "BES: " )
00145 + "cannot get heap of size "
00146 + mhs + " to start running" ;
00147 (*BESLog::TheLog()) << s ;
00148 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00149 }
00150 free( _buffer ) ;
00151 }
00152 else
00153 {
00154 if( emergency > 10 )
00155 {
00156 string s = "Emergency pool is larger than 10 Megabytes";
00157 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00158 }
00159 }
00160
00161 _size = megabytes( emergency ) ;
00162 _buffer = 0 ;
00163 _buffer = malloc( _size ) ;
00164 if( !_buffer )
00165 {
00166 string s = (string)"BES: cannot expand heap to "
00167 + eps + " to start running" ;
00168 (*BESLog::TheLog()) << s << endl ;
00169 throw BESInternalFatalError( s, __FILE__, __LINE__ ) ;
00170 }
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182 }
00183 }
00184 catch( BESError &ex )
00185 {
00186 cerr << "BES: unable to start properly because "
00187 << ex.get_message()
00188 << endl ;
00189 exit(1) ;
00190 }
00191 catch(...)
00192 {
00193 cerr << "BES: unable to start: undefined exception happened\n" ;
00194 exit(1) ;
00195 }
00196 }
00197 BESLog::TheLog()->resume();
00198 }
00199
00200 BESMemoryGlobalArea::~BESMemoryGlobalArea()
00201 {
00202 if (--_counter == 0)
00203 {
00204 if (_buffer)
00205 free( _buffer ) ;
00206 _buffer = 0 ;
00207 }
00208 }
00209
00210 inline void
00211 BESMemoryGlobalArea::log_limits( const string &msg )
00212 {
00213 if( getrlimit( RLIMIT_DATA, &limit ) < 0 )
00214 {
00215 (*BESLog::TheLog()) << msg << "Could not get limits because "
00216 << strerror( errno ) << endl ;
00217 _counter-- ;
00218 throw BESInternalFatalError( strerror( errno ), __FILE__, __LINE__ ) ;
00219 }
00220 if( limit.rlim_cur == RLIM_INFINITY )
00221 (*BESLog::TheLog()) << msg << "heap size soft limit is infinte"
00222 << endl ;
00223 else
00224 (*BESLog::TheLog()) << msg << "heap size soft limit is "
00225 << (long int)limit.rlim_cur
00226 << " bytes ("
00227 << (long int)(limit.rlim_cur)/(MEGABYTE)
00228 << " MB - may be rounded up)" << endl ;
00229 if( limit.rlim_max == RLIM_INFINITY )
00230 (*BESLog::TheLog()) << msg << "heap size hard limit is infinite"
00231 << endl ;
00232 else
00233 (*BESLog::TheLog()) << msg << "heap size hard limit is "
00234 << (long int)limit.rlim_max
00235 << " bytes ("
00236 << (long int)(limit.rlim_cur)/(MEGABYTE)
00237 << " MB - may be rounded up)" << endl ;
00238 }
00239
00240 void
00241 BESMemoryGlobalArea::release_memory()
00242 {
00243 if( _buffer )
00244 {
00245 free( _buffer ) ;
00246 _buffer = 0 ;
00247 }
00248 }
00249
00250 bool
00251 BESMemoryGlobalArea::reclaim_memory()
00252 {
00253 if( !_buffer )
00254 _buffer = malloc( _size ) ;
00255 if( _buffer )
00256 return true ;
00257 else
00258 return false ;
00259 }
00260
00268 void
00269 BESMemoryGlobalArea::dump( ostream &strm ) const
00270 {
00271 strm << BESIndent::LMarg << "BESMemoryGlobalArea::dump - ("
00272 << (void *)this << ")" << endl ;
00273 BESIndent::Indent() ;
00274 strm << BESIndent::LMarg << "area set? " << _counter << endl ;
00275 strm << BESIndent::LMarg << "emergency buffer: "
00276 << (void *)_buffer << endl ;
00277 strm << BESIndent::LMarg << "buffer size: " << _size << endl ;
00278 strm << BESIndent::LMarg << "rlimit current: " << limit.rlim_cur << endl ;
00279 strm << BESIndent::LMarg << "rlimit max: " << limit.rlim_max << endl ;
00280 BESIndent::UnIndent() ;
00281 }
00282