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 ans[4];
47 #if defined(__i386__) || defined(__x86_64__)
48  static volatile int op=0,a;
49 #endif
50 
51 // Still some problem on x86_64, so only i386 for now
52 #if defined(__x86_64__)
53 
54  __asm__ __volatile__ ("pushq %%rdx;\
55  pushq %%rcx; \
56  pushq %%rsi; \
57  pushq %%rbx; \
58  cpuid; \
59  movq %%rbx,%%rsi; \
60  popq %%rbx; \
61  movl %%ecx,%0; \
62  movl %%edx,%1; \
63  movl %%esi,%2; \
64  movl %%eax,%3; \
65  popq %%rsi; \
66  popq %%rcx; \
67  popq %%rdx;"
68  : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
69  : "a"(op)
70  );
71 
72 #elif defined(__i386__)
73 
74 
75  __asm__ __volatile__ ("pushl %%edx;\
76  pushl %%ecx; \
77  pushl %%esi; \
78  pushl %%ebx; \
79  cpuid; \
80  movl %%ebx,%%esi; \
81  popl %%ebx; \
82  movl %%ecx,%0; \
83  movl %%edx,%1; \
84  movl %%esi,%2; \
85  movl %%eax,%3; \
86  popl %%esi; \
87  popl %%ecx; \
88  popl %%edx;"
89  : "=m"(ans[2]), "=m"(ans[1]), "=m"(ans[0]), "=m"(a)
90  : "a"(op)
91  );
92 
93 
94 #else
95  const char* unknown_str = "Unknown";
96  // int unknown_sz = strlen(unknown_str);
97  strcpy((char*)&ans[0],unknown_str);
98 #endif
99 
100  const char* amd_str = "AuthenticAMD";
101  int amd_sz = strlen(amd_str);
102  const char* intel_str = "GenuineIntel";
103  int intel_sz = strlen(intel_str);
104 
105  char* str = (char*)&ans[0];
106  ans[3]=0;
107 
108  return strncmp(str,amd_str,amd_sz)==0?AMD_CPU:
109  strncmp(str,intel_str,intel_sz)==0?INTEL_CPU:UNKNOWN_CPU;
110  }
111 
112  // values determined experimentally for each architecture
113  const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
114  const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
115 
116  }
117 
118 
120  {
121  bool rc=true;
122 
123  switch(get_cpu_type())
124  {
125  case AMD_CPU:
126  {
127  values_ = amd_opts;
128  changed_=true;
129  break;
130  }
131  case INTEL_CPU:
132  {
133  values_ = intel_opts;
134  changed_=true;
135  break;
136  }
137  case UNKNOWN_CPU:
138  default:
139  rc=false;
140  }
141 
142  return rc;
143  }
144 
146  changed_(false)
147  {
149  {
151  if(hasErrors())
152  {
153  std::cerr << "ERROR: Reset of malloc options has fails:\n"
154  << error_message_ << "\n";
155  }
156  }
157  }
158 
160  {
161  if(changed_==false) return; // only adjust if they changed
162  error_message_.clear();
163  changed_ = false;
164 
165 #ifndef __SANITIZE_ADDRESS__
166 #ifdef M_MMAP_MAX
167  if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
168  error_message_ += "Could not set M_MMAP_MAX\n";
169 #endif
170 #ifdef M_TRIM_THRESHOLD
171  if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
172  error_message_ += "Could not set M_TRIM_THRESHOLD\n";
173 #endif
174 #ifdef M_TOP_PAD
175  if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
176  error_message_ += "ERROR: Could not set M_TOP_PAD\n";
177 #endif
178 #ifdef M_MMAP_THRESHOLD
179  if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
180  error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
181 #endif
182 #endif
183  }
184 
186  {
187  const char* par = getenv("CMSRUN_MALLOC_RESET");
188  if(par==0) return false; // leave quickly here
189  std::string spar(par);
190  bool rc = false;
191 
192  // CMSRUN_MALLOC_RESET = "mmap_max trim_thres top_pad mmap_thres"
193 
194  if(spar.size()>1)
195  {
196  std::istringstream ist(spar);
199 
200  if(ist.bad())
201  {
202  std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
203  << spar << "\n"
204  << "format is: "
205  << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
206  }
207  else
208  {
209  std::cout << "MALLOC_OPTIONS> Reset options: "
210  << "CMSRUN_MALLOC_RESET=" << par << "\n";
211  }
212  rc=true;
213  changed_=true;
214  }
215 
216  return rc;
217  }
218 
220 
222  {
223  return global_malloc_options;
224  }
225 
226 
227  // ----------------------------------------------------------------
228 }
std::string error_message_
Definition: MallocOpts.h:90
bool hasErrors() const
Definition: MallocOpts.h:72
opt_type mmap_max_
Definition: MallocOpts.h:44
opt_type trim_thr_
Definition: MallocOpts.h:45
double a
Definition: hdecay.h:121
tuple cout
Definition: gather_cfg.py:121
volatile std::atomic< bool > shutdown_flag false
std::ostream & operator<<(std::ostream &ost, const HLTGlobalStatus &hlt)
Formatted printout of trigger tbale.
opt_type mmap_thr_
Definition: MallocOpts.h:47
MallocOptionSetter global_malloc_options
Definition: MallocOpts.cc:219
MallocOptionSetter & getGlobalOptionSetter()
Definition: MallocOpts.cc:221
opt_type top_pad_
Definition: MallocOpts.h:46