CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
MallocOpts.cc
Go to the documentation of this file.
1 
2 
3 // -*- C++ -*-
4 //
5 // Package: Utilities
6 // Class : MallocOpts
7 //
8 // Original Author: Jim Kowalkowski
9 //
10 // ------------------ resetting malloc options -----------------------
11 
12 
14 
15 #if !defined(__APPLE__)
16 #include <malloc.h>
17 #endif
18 #include <sstream>
19 #include <iostream>
20 #include <cstdlib>
21 #include <cstring>
22 
23 namespace edm
24 {
25 
26  std::ostream& operator<<(std::ostream& ost,const MallocOpts& opts)
27  {
28  ost << "mmap_max=" << opts.mmap_max_
29  << " trim_threshold=" << opts.trim_thr_
30  << " top_padding=" << opts.top_pad_
31  << " mmap_threshold=" << opts.mmap_thr_;
32  return ost;
33  }
34 
35  namespace
36  {
37  typedef enum { UNKNOWN_CPU=0, AMD_CPU=1, INTEL_CPU=2 } cpu_type;
38 
39  cpu_type get_cpu_type()
40  {
41  // issue: these need to be static. The asm instruction combined
42  // with optimization on the 64 bit platform moves the stack data
43  // member around in such a way that the =m directive misses the
44  // the location. Of course this means that this routine is not
45  // multithread safe.
46  static volatile int op=0,a;
47  static volatile int ans[4];
48 
49 // Still some problem on x86_64, so only i386 for now
50 #if defined(__x86_64__) && !defined(__APPLE__)
51 
52  __asm__ __volatile__ ("pushq %%rdx;\
53  pushq %%rcx; \
54  pushq %%rsi; \
55  pushq %%rbx; \
56  cpuid; \
57  movq %%rbx,%%rsi; \
58  popq %%rbx; \
59  movl %%ecx,%0; \
60  movl %%edx,%1; \
61  movl %%esi,%2; \
62  movl %%eax,%3; \
63  popq %%rsi; \
64  popq %%rcx; \
65  popq %%rdx;"
66  : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
67  : "a"(op)
68  );
69 
70 #elif defined(__i386__) && !defined(__APPLE__)
71 
72 
73  __asm__ __volatile__ ("pushl %%edx;\
74  pushl %%ecx; \
75  pushl %%esi; \
76  pushl %%ebx; \
77  cpuid; \
78  movl %%ebx,%%esi; \
79  popl %%ebx; \
80  movl %%ecx,%0; \
81  movl %%edx,%1; \
82  movl %%esi,%2; \
83  movl %%eax,%3; \
84  popl %%esi; \
85  popl %%ecx; \
86  popl %%edx;"
87  : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
88  : "a"(op)
89  );
90 
91 
92 #else
93  const char* unknown_str = "Unknown";
94  // int unknown_sz = strlen(unknown_str);
95  strcpy((char*)&ans[0],unknown_str);
96 #endif
97 
98  const char* amd_str = "AuthenticAMD";
99  int amd_sz = strlen(amd_str);
100  const char* intel_str = "GenuineIntel";
101  int intel_sz = strlen(intel_str);
102 
103  char* str = (char*)&ans[0];
104  ans[3]=0;
105 
106  return strncmp(str,amd_str,amd_sz)==0?AMD_CPU:
107  strncmp(str,intel_str,intel_sz)==0?INTEL_CPU:UNKNOWN_CPU;
108  }
109 
110  // values determined experimentally for each architecture
111  const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
112  const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
113 
114  }
115 
116 
118  {
119  bool rc=true;
120 
121  switch(get_cpu_type())
122  {
123  case AMD_CPU:
124  {
125  values_ = amd_opts;
126  changed_=true;
127  break;
128  }
129  case INTEL_CPU:
130  {
131  values_ = intel_opts;
132  changed_=true;
133  break;
134  }
135  case UNKNOWN_CPU:
136  default:
137  rc=false;
138  }
139 
140  return rc;
141  }
142 
144  changed_(false)
145  {
147  {
149  if(hasErrors())
150  {
151  std::cerr << "ERROR: Reset of malloc options has fails:\n"
152  << error_message_ << "\n";
153  }
154  }
155  }
156 
158  {
159  if(changed_==false) return; // only adjust if they changed
160  error_message_.clear();
161  changed_ = false;
162 
163 #ifdef M_MMAP_MAX
164  if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
165  error_message_ += "Could not set M_MMAP_MAX\n";
166 #endif
167 #ifdef M_TRIM_THRESHOLD
168  if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
169  error_message_ += "Could not set M_TRIM_THRESHOLD\n";
170 #endif
171 #ifdef M_TOP_PAD
172  if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
173  error_message_ += "ERROR: Could not set M_TOP_PAD\n";
174 #endif
175 #ifdef M_MMAP_THRESHOLD
176  if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
177  error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
178 #endif
179  }
180 
182  {
183  const char* par = getenv("CMSRUN_MALLOC_RESET");
184  if(par==0) return false; // leave quickly here
185  std::string spar(par);
186  bool rc = false;
187 
188  // CMSRUN_MALLOC_RESET = "mmap_max trim_thres top_pad mmap_thres"
189 
190  if(spar.size()>1)
191  {
192  std::istringstream ist(spar);
195 
196  if(ist.bad())
197  {
198  std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
199  << spar << "\n"
200  << "format is: "
201  << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
202  }
203  else
204  {
205  std::cout << "MALLOC_OPTIONS> Reset options: "
206  << "CMSRUN_MALLOC_RESET=" << par << "\n";
207  }
208  rc=true;
209  changed_=true;
210  }
211 
212  return rc;
213  }
214 
216 
218  {
219  return global_malloc_options;
220  }
221 
222 
223  // ----------------------------------------------------------------
224 }
std::string error_message_
Definition: MallocOpts.h:91
bool hasErrors() const
Definition: MallocOpts.h:73
opt_type mmap_max_
Definition: MallocOpts.h:45
opt_type trim_thr_
Definition: MallocOpts.h:46
double a
Definition: hdecay.h:121
tuple cout
Definition: gather_cfg.py:41
std::ostream & operator<<(std::ostream &ost, const HLTGlobalStatus &hlt)
Formatted printout of trigger tbale.
opt_type mmap_thr_
Definition: MallocOpts.h:48
MallocOptionSetter global_malloc_options
Definition: MallocOpts.cc:215
MallocOptionSetter & getGlobalOptionSetter()
Definition: MallocOpts.cc:217
opt_type top_pad_
Definition: MallocOpts.h:47
const double par[8 *NPar][4]