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 #ifdef M_MMAP_MAX
166  if(mallopt(M_MMAP_MAX,values_.mmap_max_)<0)
167  error_message_ += "Could not set M_MMAP_MAX\n";
168 #endif
169 #ifdef M_TRIM_THRESHOLD
170  if(mallopt(M_TRIM_THRESHOLD,values_.trim_thr_)<0)
171  error_message_ += "Could not set M_TRIM_THRESHOLD\n";
172 #endif
173 #ifdef M_TOP_PAD
174  if(mallopt(M_TOP_PAD,values_.top_pad_)<0)
175  error_message_ += "ERROR: Could not set M_TOP_PAD\n";
176 #endif
177 #ifdef M_MMAP_THRESHOLD
178  if(mallopt(M_MMAP_THRESHOLD,values_.mmap_thr_)<0)
179  error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
180 #endif
181  }
182 
184  {
185  const char* par = getenv("CMSRUN_MALLOC_RESET");
186  if(par==0) return false; // leave quickly here
187  std::string spar(par);
188  bool rc = false;
189 
190  // CMSRUN_MALLOC_RESET = "mmap_max trim_thres top_pad mmap_thres"
191 
192  if(spar.size()>1)
193  {
194  std::istringstream ist(spar);
197 
198  if(ist.bad())
199  {
200  std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: "
201  << spar << "\n"
202  << "format is: "
203  << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
204  }
205  else
206  {
207  std::cout << "MALLOC_OPTIONS> Reset options: "
208  << "CMSRUN_MALLOC_RESET=" << par << "\n";
209  }
210  rc=true;
211  changed_=true;
212  }
213 
214  return rc;
215  }
216 
218 
220  {
221  return global_malloc_options;
222  }
223 
224 
225  // ----------------------------------------------------------------
226 }
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:217
MallocOptionSetter & getGlobalOptionSetter()
Definition: MallocOpts.cc:219
opt_type top_pad_
Definition: MallocOpts.h:46