ATLAS Offline Software
Loading...
Searching...
No Matches
LeakCheckModule.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8
9
10//
11// includes
12//
13
15
16#include <EventLoop/Job.h>
19#include <TSystem.h>
20#include <TTree.h>
21#include <exception>
22
23//
24// method implementations
25//
26
27namespace EL
28{
29 namespace Detail
30 {
31 StatusCode LeakCheckModule ::
32 postFirstEvent (ModuleData& data)
33 {
34 m_skippedEvents = data.m_eventsProcessed + 1;
35
36 // Get the memory usage of the process after initialisation.
37 ::ProcInfo_t pinfo;
38 if (gSystem->GetProcInfo (&pinfo) != 0) {
39 ANA_MSG_ERROR ("Could not get memory usage information");
40 return StatusCode::FAILURE;
41 }
42 m_initMemResident = pinfo.fMemResident;
43 m_initMemVirtual = pinfo.fMemVirtual;
44 ANA_MSG_DEBUG ("starting memory: " << pinfo.fMemResident << " " << pinfo.fMemVirtual);
45 return StatusCode::SUCCESS;
46 }
47
48
49
50 StatusCode LeakCheckModule ::
51 postFinalize (ModuleData& data)
52 {
53 if (m_skippedEvents > 0) {
54 // Get the memory usage of the process after finalisation.
55 ::ProcInfo_t pinfo;
56 if (gSystem->GetProcInfo (&pinfo) != 0) {
57 ANA_MSG_ERROR ("Could not get memory usage information");
58 return StatusCode::FAILURE;
59 }
60 m_finMemResident = pinfo.fMemResident;
61 m_finMemVirtual = pinfo.fMemVirtual;
62 ANA_MSG_DEBUG ("finishing memory: " << pinfo.fMemResident << " " << pinfo.fMemVirtual);
63
64 // Save the memory increase values into the job statistics tree.
65 // The values are held in module members because the tree is only
66 // filled later, in Worker::finalize, by which point any function
67 // local would be out of scope and the branch address dangling.
68 RCU_ASSERT (data.m_jobStats != nullptr);
70 if (! data.m_jobStats->Branch ("memIncreaseResident", &m_incResBuffer)) {
71 ANA_MSG_ERROR ("Failed to create branch memIncreaseResident");
72 return StatusCode::FAILURE;
73 }
75 if (! data.m_jobStats->Branch ("memIncreaseVirtual", &m_incVirtBuffer)) {
76 ANA_MSG_ERROR ("Failed to create branch memIncreaseVirtual");
77 return StatusCode::FAILURE;
78 }
79 }
80 return StatusCode::SUCCESS;
81 }
82
83
84
85 StatusCode LeakCheckModule ::
86 onWorkerEnd (ModuleData& data)
87 {
88 // Perform a memory leak check in case at least one event was processed.
89 if (m_skippedEvents > 0 &&
90 data.m_eventsProcessed > m_skippedEvents) {
91
92 // Calculate and print the memory increase of the job.
93 const Long_t resLeak = memIncreaseResident();
94 const Double_t resLeakPerEv =
95 (static_cast< Double_t > (resLeak) /
96 static_cast< Double_t > (data.m_eventsProcessed-m_skippedEvents));
97 const Long_t virtLeak = memIncreaseVirtual();
98 const Double_t virtLeakPerEv =
99 (static_cast< Double_t > (virtLeak) /
100 static_cast< Double_t > (data.m_eventsProcessed-m_skippedEvents) );
101 ANA_MSG_INFO ("Memory increase/change during the job:");
102 ANA_MSG_INFO (" - resident: " << resLeakPerEv << " kB/event ("
103 << resLeak << " kB total)");
104 ANA_MSG_INFO (" - virtual : " << virtLeakPerEv << " kB/event ("
105 << virtLeak << " kB total)");
106
107 // Decide if this acceptable or not.
108 if ((resLeak > absResidentLimit.value()) &&
109 (resLeakPerEv > perEvResidentLimit.value()) &&
110 (virtLeak > absVirtualLimit.value()) &&
111 (virtLeakPerEv > perEvVirtualLimit.value())) {
112
113 // If not, decide what to do about it.
114 if (failOnLeak.value()) {
115 ANA_MSG_ERROR ("A significant memory leak was detected");
116 return StatusCode::FAILURE;
117 } else {
118 ANA_MSG_WARNING ("*");
119 ANA_MSG_WARNING ("* A significant memory leak was detected");
120 ANA_MSG_WARNING ("*");
121 }
122 }
123 }
124 return StatusCode::SUCCESS;
125 }
126
127
128
129 Long_t LeakCheckModule ::
130 memIncreaseResident () const
131 {
132 // Check that the user called the function at the correct time.
133 if ((m_initMemResident == -1) || (m_finMemResident == -1)) {
134 throw std::logic_error ("Function called at incorrect time");
135 }
136 // Return the resident memory increase.
138 }
139
140
141
142 Long_t LeakCheckModule ::
143 memIncreaseVirtual () const
144 {
145 // Check that the user called the function at the correct time.
146 if ((m_initMemVirtual == -1) || (m_finMemVirtual == -1)) {
147 throw std::logic_error ("Function called at incorrect time");
148 }
149 // Return the resident memory increase.
151 }
152 }
153}
#define RCU_ASSERT(x)
Definition Assert.h:210
#define ANA_MSG_ERROR(xmsg,...)
Macro printing error messages.
#define ANA_MSG_DEBUG(xmsg,...)
Macro printing debug messages.
#define ANA_MSG_INFO(xmsg,...)
Macro printing info messages.
#define ANA_MSG_WARNING(xmsg,...)
Macro printing warning messages.
Long_t m_initMemVirtual
Amount of virtual memory used after initialisation in kB.
Gaudi::Property< int > absResidentLimit
Float_t m_incResBuffer
buffer for the resident memory increase branch
Long_t m_finMemResident
Amount of resident memory used after finalisation in kB.
Long_t memIncreaseVirtual() const
Virtual memory leak/increase during the job.
Gaudi::Property< int > perEvResidentLimit
uint64_t m_skippedEvents
number of skipped events
Gaudi::Property< int > absVirtualLimit
Long_t memIncreaseResident() const
Resident memory leak/increase during the job.
Gaudi::Property< int > perEvVirtualLimit
Long_t m_finMemVirtual
Amount of virtual memory used after finalisation in kB.
Gaudi::Property< bool > failOnLeak
Long_t m_initMemResident
Amount of resident memory used after initialisation in kB.
Float_t m_incVirtBuffer
buffer for the virtual memory increase branch
This module defines the arguments passed from the BATCH driver to the BATCH worker.
::StatusCode StatusCode
StatusCode definition for legacy code.
the data the EventLoop core classes are sharing with the Module implementation
Definition ModuleData.h:64