comparison OrthancServer/Sources/OrthancInitialization.cpp @ 4366:6a39ca7083b9

New config option "MallocArenaMax" to control memory usage on GNU/Linux
author Sebastien Jodogne <s.jodogne@gmail.com>
date Thu, 10 Dec 2020 09:32:39 +0100
parents d2f79a475b51
children 79ef2b6d8e76
comparison
equal deleted inserted replaced
4365:3150306fb4ad 4366:6a39ca7083b9
36 #if defined(_WIN32) 36 #if defined(_WIN32)
37 // "Please include winsock2.h before windows.h" 37 // "Please include winsock2.h before windows.h"
38 # include <winsock2.h> 38 # include <winsock2.h>
39 #endif 39 #endif
40 40
41 #if !defined(HAVE_MALLOPT)
42 # error Macro HAVE_MALLOPT must be defined
43 #endif
44
45 #if HAVE_MALLOPT == 1
46 # include <malloc.h>
47 #endif
48
41 #include "OrthancInitialization.h" 49 #include "OrthancInitialization.h"
42 50
43 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h" 51 #include "../../OrthancFramework/Sources/DicomParsing/FromDcmtkBridge.h"
44 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h" 52 #include "../../OrthancFramework/Sources/FileStorage/FilesystemStorage.h"
45 #include "../../OrthancFramework/Sources/HttpClient.h" 53 #include "../../OrthancFramework/Sources/HttpClient.h"
225 233
226 234
227 235
228 void OrthancInitialize(const char* configurationFile) 236 void OrthancInitialize(const char* configurationFile)
229 { 237 {
238 static const char* LOCALE = "Locale";
239 static const char* PKCS11 = "Pkcs11";
240 static const char* DEFAULT_ENCODING = "DefaultEncoding";
241 static const char* MALLOC_ARENA_MAX = "MallocArenaMax";
242
230 OrthancConfiguration::WriterLock lock; 243 OrthancConfiguration::WriterLock lock;
231 244
232 InitializeServerEnumerations(); 245 InitializeServerEnumerations();
233 246
234 // Read the user-provided configuration 247 // Read the user-provided configuration
235 lock.GetConfiguration().Read(configurationFile); 248 lock.GetConfiguration().Read(configurationFile);
236 249
237 { 250 {
238 std::string locale; 251 std::string locale;
239 252
240 if (lock.GetJson().isMember("Locale")) 253 if (lock.GetJson().isMember(LOCALE))
241 { 254 {
242 locale = lock.GetConfiguration().GetStringParameter("Locale", ""); 255 locale = lock.GetConfiguration().GetStringParameter(LOCALE, "");
243 } 256 }
244 257
245 bool loadPrivate = lock.GetConfiguration().GetBooleanParameter("LoadPrivateDictionary", true); 258 bool loadPrivate = lock.GetConfiguration().GetBooleanParameter("LoadPrivateDictionary", true);
246 Orthanc::InitializeFramework(locale, loadPrivate); 259 Orthanc::InitializeFramework(locale, loadPrivate);
247 } 260 }
248 261
249 // The Orthanc framework is now initialized 262 // The Orthanc framework is now initialized
250 263
251 if (lock.GetJson().isMember("DefaultEncoding")) 264 if (lock.GetJson().isMember(DEFAULT_ENCODING))
252 { 265 {
253 std::string encoding = lock.GetConfiguration().GetStringParameter("DefaultEncoding", ""); 266 std::string encoding = lock.GetConfiguration().GetStringParameter(DEFAULT_ENCODING, "");
254 SetDefaultDicomEncoding(StringToEncoding(encoding.c_str())); 267 SetDefaultDicomEncoding(StringToEncoding(encoding.c_str()));
255 } 268 }
256 else 269 else
257 { 270 {
258 SetDefaultDicomEncoding(ORTHANC_DEFAULT_DICOM_ENCODING); 271 SetDefaultDicomEncoding(ORTHANC_DEFAULT_DICOM_ENCODING);
259 } 272 }
260 273
261 if (lock.GetJson().isMember("Pkcs11")) 274 if (lock.GetJson().isMember(PKCS11))
262 { 275 {
263 ConfigurePkcs11(lock.GetJson()["Pkcs11"]); 276 ConfigurePkcs11(lock.GetJson()[PKCS11]);
264 } 277 }
265 278
266 RegisterUserMetadata(lock.GetJson()); 279 RegisterUserMetadata(lock.GetJson());
267 RegisterUserContentType(lock.GetJson()); 280 RegisterUserContentType(lock.GetJson());
268 281
269 LoadCustomDictionary(lock.GetJson()); 282 LoadCustomDictionary(lock.GetJson());
270 283
271 lock.GetConfiguration().RegisterFont(ServerResources::FONT_UBUNTU_MONO_BOLD_16); 284 lock.GetConfiguration().RegisterFont(ServerResources::FONT_UBUNTU_MONO_BOLD_16);
285
286 #if HAVE_MALLOPT == 1
287 // New in Orthanc 1.9.0
288 // https://book.orthanc-server.com/faq/scalability.html#controlling-memory-usage
289 unsigned int maxArena = lock.GetConfiguration().GetUnsignedIntegerParameter(MALLOC_ARENA_MAX, 5);
290 if (maxArena != 0)
291 {
292 // https://man7.org/linux/man-pages/man3/mallopt.3.html
293 LOG(INFO) << "Calling mallopt(M_ARENA_MAX, " << maxArena << ")";
294 if (mallopt(M_ARENA_MAX, maxArena) != 1 /* success */)
295 {
296 throw OrthancException(ErrorCode_InternalError, "The call to mallopt(M_ARENA_MAX, " +
297 boost::lexical_cast<std::string>(maxArena) + ") has failed");
298 }
299 }
300 #else
301 if (lock.GetJson().isMember(MALLOC_ARENA_MAX))
302 {
303 LOG(INFO) << "Your platform does not support mallopt(), ignoring configuration option \""
304 << MALLOC_ARENA_MAX << "\"";
305 }
306 #endif
272 } 307 }
273 308
274 309
275 310
276 void OrthancFinalize() 311 void OrthancFinalize()