Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "FWCore/Utilities/interface/MallocOpts.h"
00014
00015 #if !defined(__APPLE__)
00016 #include <malloc.h>
00017 #endif
00018 #include <sstream>
00019 #include <iostream>
00020 #include <cstdlib>
00021 #include <cstring>
00022
00023 namespace edm
00024 {
00025
00026 std::ostream& operator<<(std::ostream& ost,const MallocOpts& opts)
00027 {
00028 ost << "mmap_max=" << opts.mmap_max_
00029 << " trim_threshold=" << opts.trim_thr_
00030 << " top_padding=" << opts.top_pad_
00031 << " mmap_threshold=" << opts.mmap_thr_;
00032 return ost;
00033 }
00034
00035 namespace
00036 {
00037 typedef enum { UNKNOWN_CPU=0, AMD_CPU=1, INTEL_CPU=2 } cpu_type;
00038
00039 cpu_type get_cpu_type()
00040 {
00041
00042
00043
00044
00045
00046 static volatile int ans[4];
00047 #if defined(__i386__) || defined(__x86_64__)
00048 static volatile int op=0,a;
00049 #endif
00050
00051
00052 #if defined(__x86_64__)
00053
00054 __asm__ __volatile__ ("pushq %%rdx;\
00055 pushq %%rcx; \
00056 pushq %%rsi; \
00057 pushq %%rbx; \
00058 cpuid; \
00059 movq %%rbx,%%rsi; \
00060 popq %%rbx; \
00061 movl %%ecx,%0; \
00062 movl %%edx,%1; \
00063 movl %%esi,%2; \
00064 movl %%eax,%3; \
00065 popq %%rsi; \
00066 popq %%rcx; \
00067 popq %%rdx;"
00068 : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00069 : "a"(op)
00070 );
00071
00072 #elif defined(__i386__)
00073
00074
00075 __asm__ __volatile__ ("pushl %%edx;\
00076 pushl %%ecx; \
00077 pushl %%esi; \
00078 pushl %%ebx; \
00079 cpuid; \
00080 movl %%ebx,%%esi; \
00081 popl %%ebx; \
00082 movl %%ecx,%0; \
00083 movl %%edx,%1; \
00084 movl %%esi,%2; \
00085 movl %%eax,%3; \
00086 popl %%esi; \
00087 popl %%ecx; \
00088 popl %%edx;"
00089 : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00090 : "a"(op)
00091 );
00092
00093
00094 #else
00095 const char* unknown_str = "Unknown";
00096
00097 strcpy((char*)&ans[0],unknown_str);
00098 #endif
00099
00100 const char* amd_str = "AuthenticAMD";
00101 int amd_sz = strlen(amd_str);
00102 const char* intel_str = "GenuineIntel";
00103 int intel_sz = strlen(intel_str);
00104
00105 char* str = (char*)&ans[0];
00106 ans[3]=0;
00107
00108 return strncmp(str,amd_str,amd_sz)==0?AMD_CPU:
00109 strncmp(str,intel_str,intel_sz)==0?INTEL_CPU:UNKNOWN_CPU;
00110 }
00111
00112
00113 const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
00114 const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
00115
00116 }
00117
00118
00119 bool MallocOptionSetter::retrieveFromCpuType()
00120 {
00121 bool rc=true;
00122
00123 switch(get_cpu_type())
00124 {
00125 case AMD_CPU:
00126 {
00127 values_ = amd_opts;
00128 changed_=true;
00129 break;
00130 }
00131 case INTEL_CPU:
00132 {
00133 values_ = intel_opts;
00134 changed_=true;
00135 break;
00136 }
00137 case UNKNOWN_CPU:
00138 default:
00139 rc=false;
00140 }
00141
00142 return rc;
00143 }
00144
00145 MallocOptionSetter::MallocOptionSetter():
00146 changed_(false)
00147 {
00148 if(retrieveFromEnv() || retrieveFromCpuType())
00149 {
00150 adjustMallocParams();
00151 if(hasErrors())
00152 {
00153 std::cerr << "ERROR: Reset of malloc options has fails:\n"
00154 << error_message_ << "\n";
00155 }
00156 }
00157 }
00158
00159 void MallocOptionSetter::adjustMallocParams()
00160 {
00161 if(changed_==false) return;
00162 error_message_.clear();
00163 changed_ = false;
00164
00165 #ifdef M_MMAP_MAX
00166 if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
00167 error_message_ += "Could not set M_MMAP_MAX\n";
00168 #endif
00169 #ifdef M_TRIM_THRESHOLD
00170 if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
00171 error_message_ += "Could not set M_TRIM_THRESHOLD\n";
00172 #endif
00173 #ifdef M_TOP_PAD
00174 if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
00175 error_message_ += "ERROR: Could not set M_TOP_PAD\n";
00176 #endif
00177 #ifdef M_MMAP_THRESHOLD
00178 if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
00179 error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
00180 #endif
00181 }
00182
00183 bool MallocOptionSetter::retrieveFromEnv()
00184 {
00185 const char* par = getenv("CMSRUN_MALLOC_RESET");
00186 if(par==0) return false;
00187 std::string spar(par);
00188 bool rc = false;
00189
00190
00191
00192 if(spar.size()>1)
00193 {
00194 std::istringstream ist(spar);
00195 ist >> values_.mmap_max_ >> values_.trim_thr_
00196 >> values_.top_pad_ >> values_.mmap_thr_;
00197
00198 if(ist.bad())
00199 {
00200 std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
00201 << spar << "\n"
00202 << "format is: "
00203 << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
00204 }
00205 else
00206 {
00207 std::cout << "MALLOC_OPTIONS> Reset options: "
00208 << "CMSRUN_MALLOC_RESET=" << par << "\n";
00209 }
00210 rc=true;
00211 changed_=true;
00212 }
00213
00214 return rc;
00215 }
00216
00217 MallocOptionSetter global_malloc_options;
00218
00219 MallocOptionSetter& getGlobalOptionSetter()
00220 {
00221 return global_malloc_options;
00222 }
00223
00224
00225
00226 }