CMS 3D CMS Logo

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 : UNKNOWN_CPU;
101  }
102 
103  // values determined experimentally for each architecture
104  const MallocOpts intel_opts(262144, 524288, 5242880, 131072);
105  const MallocOpts amd_opts(0, 8388608, 131072, 10485760);
106 
107  } // namespace
108 
110  bool rc = true;
111 
112  switch (get_cpu_type()) {
113  case AMD_CPU: {
114  values_ = amd_opts;
115  changed_ = true;
116  break;
117  }
118  case INTEL_CPU: {
119  values_ = intel_opts;
120  changed_ = true;
121  break;
122  }
123  case UNKNOWN_CPU:
124  default:
125  rc = false;
126  }
127 
128  return rc;
129  }
130 
134  if (hasErrors()) {
135  std::cerr << "ERROR: Reset of malloc options has fails:\n" << error_message_ << "\n";
136  }
137  }
138  }
139 
141  if (changed_ == false)
142  return; // only adjust if they changed
143  error_message_.clear();
144  changed_ = false;
145 
146 #ifndef __SANITIZE_ADDRESS__
147 #ifdef M_MMAP_MAX
148  if (mallopt(M_MMAP_MAX, values_.mmap_max_) < 0)
149  error_message_ += "Could not set M_MMAP_MAX\n";
150 #endif
151 #ifdef M_TRIM_THRESHOLD
152  if (mallopt(M_TRIM_THRESHOLD, values_.trim_thr_) < 0)
153  error_message_ += "Could not set M_TRIM_THRESHOLD\n";
154 #endif
155 #ifdef M_TOP_PAD
156  if (mallopt(M_TOP_PAD, values_.top_pad_) < 0)
157  error_message_ += "ERROR: Could not set M_TOP_PAD\n";
158 #endif
159 #ifdef M_MMAP_THRESHOLD
160  if (mallopt(M_MMAP_THRESHOLD, values_.mmap_thr_) < 0)
161  error_message_ += "ERROR: Could not set M_MMAP_THRESHOLD\n";
162 #endif
163 #endif
164  }
165 
167  const char* par = std::getenv("CMSRUN_MALLOC_RESET");
168  if (par == nullptr)
169  return false; // leave quickly here
170  std::string spar(par);
171  bool rc = false;
172 
173  // CMSRUN_MALLOC_RESET = "mmap_max trim_thres top_pad mmap_thres"
174 
175  if (spar.size() > 1) {
176  std::istringstream ist(spar);
178 
179  if (ist.bad()) {
180  std::cerr << "bad malloc options in CMSRUN_MALLOC_RESET: " << spar << "\n"
181  << "format is: "
182  << "CMSRUN_MALLOC_RESET=\"mmap_max trim_thres top_pad mmap_thres\"\n";
183  } else {
184  std::cout << "MALLOC_OPTIONS> Reset options: "
185  << "CMSRUN_MALLOC_RESET=" << par << "\n";
186  }
187  rc = true;
188  changed_ = true;
189  }
190 
191  return rc;
192  }
193 
195 
197 
198  // ----------------------------------------------------------------
199 } // 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
HLT enums.
double a
Definition: hdecay.h:119
#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:194
MallocOptionSetter & getGlobalOptionSetter()
Definition: MallocOpts.cc:196
opt_type top_pad_
Definition: MallocOpts.h:41