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