CMS 3D CMS Logo

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