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 op=0,a;
00047 static volatile int ans[4];
00048
00049
00050 #if defined(__x86_64__)
00051
00052 __asm__ __volatile__ ("pushq %%rdx;\
00053 pushq %%rcx; \
00054 pushq %%rsi; \
00055 pushq %%rbx; \
00056 cpuid; \
00057 movq %%rbx,%%rsi; \
00058 popq %%rbx; \
00059 movl %%ecx,%0; \
00060 movl %%edx,%1; \
00061 movl %%esi,%2; \
00062 movl %%eax,%3; \
00063 popq %%rsi; \
00064 popq %%rcx; \
00065 popq %%rdx;"
00066 : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00067 : "a"(op)
00068 );
00069
00070 #elif defined(__i386__)
00071
00072
00073 __asm__ __volatile__ ("pushl %%edx;\
00074 pushl %%ecx; \
00075 pushl %%esi; \
00076 pushl %%ebx; \
00077 cpuid; \
00078 movl %%ebx,%%esi; \
00079 popl %%ebx; \
00080 movl %%ecx,%0; \
00081 movl %%edx,%1; \
00082 movl %%esi,%2; \
00083 movl %%eax,%3; \
00084 popl %%esi; \
00085 popl %%ecx; \
00086 popl %%edx;"
00087 : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
00088 : "a"(op)
00089 );
00090
00091
00092 #else
00093 const char* unknown_str = "Unknown";
00094
00095 strcpy((char*)&ans[0],unknown_str);
00096 #endif
00097
00098 const char* amd_str = "AuthenticAMD";
00099 int amd_sz = strlen(amd_str);
00100 const char* intel_str = "GenuineIntel";
00101 int intel_sz = strlen(intel_str);
00102
00103 char* str = (char*)&ans[0];
00104 ans[3]=0;
00105
00106 return strncmp(str,amd_str,amd_sz)==0?AMD_CPU:
00107 strncmp(str,intel_str,intel_sz)==0?INTEL_CPU:UNKNOWN_CPU;
00108 }
00109
00110
00111 const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
00112 const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
00113
00114 }
00115
00116
00117 bool MallocOptionSetter::retrieveFromCpuType()
00118 {
00119 bool rc=true;
00120
00121 switch(get_cpu_type())
00122 {
00123 case AMD_CPU:
00124 {
00125 values_ = amd_opts;
00126 changed_=true;
00127 break;
00128 }
00129 case INTEL_CPU:
00130 {
00131 values_ = intel_opts;
00132 changed_=true;
00133 break;
00134 }
00135 case UNKNOWN_CPU:
00136 default:
00137 rc=false;
00138 }
00139
00140 return rc;
00141 }
00142
00143 MallocOptionSetter::MallocOptionSetter():
00144 changed_(false)
00145 {
00146 if(retrieveFromEnv() || retrieveFromCpuType())
00147 {
00148 adjustMallocParams();
00149 if(hasErrors())
00150 {
00151 std::cerr << "ERROR: Reset of malloc options has fails:\n"
00152 << error_message_ << "\n";
00153 }
00154 }
00155 }
00156
00157 void MallocOptionSetter::adjustMallocParams()
00158 {
00159 if(changed_==false) return;
00160 error_message_.clear();
00161 changed_ = false;
00162
00163 #ifdef M_MMAP_MAX
00164 if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
00165 error_message_ += "Could not set M_MMAP_MAX\n";
00166 #endif
00167 #ifdef M_TRIM_THRESHOLD
00168 if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
00169 error_message_ += "Could not set M_TRIM_THRESHOLD\n";
00170 #endif
00171 #ifdef M_TOP_PAD
00172 if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
00173 error_message_ += "ERROR: Could not set M_TOP_PAD\n";
00174 #endif
00175 #ifdef M_MMAP_THRESHOLD
00176 if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
00177 error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
00178 #endif
00179 }
00180
00181 bool MallocOptionSetter::retrieveFromEnv()
00182 {
00183 const char* par = getenv("CMSRUN_MALLOC_RESET");
00184 if(par==0) return false;
00185 std::string spar(par);
00186 bool rc = false;
00187
00188
00189
00190 if(spar.size()>1)
00191 {
00192 std::istringstream ist(spar);
00193 ist >> values_.mmap_max_ >> values_.trim_thr_
00194 >> values_.top_pad_ >> values_.mmap_thr_;
00195
00196 if(ist.bad())
00197 {
00198 std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
00199 << spar << "\n"
00200 << "format is: "
00201 << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
00202 }
00203 else
00204 {
00205 std::cout << "MALLOC_OPTIONS> Reset options: "
00206 << "CMSRUN_MALLOC_RESET=" << par << "\n";
00207 }
00208 rc=true;
00209 changed_=true;
00210 }
00211
00212 return rc;
00213 }
00214
00215 MallocOptionSetter global_malloc_options;
00216
00217 MallocOptionSetter& getGlobalOptionSetter()
00218 {
00219 return global_malloc_options;
00220 }
00221
00222
00223
00224 }