ATLAS Offline Software
AthDsoLogger.py
Go to the documentation of this file.
1 # Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
2 
3 # @file: AthenaServices/python/AthDsoLogger.py
4 # @purpose: log the vmem usage at each dso being dlopen'd
5 # @author: Sebastien Binet <binet@cern.ch>
6 
7 
8 __doc__ = "log the vmem usage at each dso being dlopen'd"
9 __version__ = "$Revision: 1.3 $"
10 __author__ = "Sebastien Binet <binet@cern.ch>"
11 
12 import os
13 import ctypes
14 import sys
15 
16 from os.path import realpath as _realpath
17 from os.path import basename as _basename
18 
19 class DsoEvent(ctypes.Structure):
20  _fields_ = [
21  ('fname', ctypes.c_char_p),
22  ('step', ctypes.c_int),
23  ]
24  pass
25 
26 class DsoLogger (object):
27  def __init__ (self, fname=None, cb_fct=None):
28  """log Dso loading by calling-back into `cb_fct`
29 
30  if `cb_fct` is None we use a default callback function which logs
31  the dVmem on stdout.
32  """
33  import ctypes
34  self.lib = ctypes.cdll.LoadLibrary ("libAthDSoCallBacks.so")
35 
37 
38 
39  self._cb_fct_type = ctypes.CFUNCTYPE(ctypes.c_int,
40  ctypes.POINTER(DsoEvent),
41  ctypes.c_void_p)
42  fct = self.lib.ath_dso_cbk_register
43  fct.argtypes = [self._cb_fct_type, ctypes.c_void_p]
44  fct.restype = ctypes.c_int
45 
46  fct = self.lib.ath_dso_cbk_unregister
47  fct.argtypes = [self._cb_fct_type]
48  fct.restype = ctypes.c_int
49 
50  from collections import defaultdict
51  self._data = defaultdict(dict)
52 
53  from AthenaCommon.Logging import logging
54  self.msg = logging.getLogger ("AthDsoLogger")
55  self.msg.setLevel (logging.INFO)
56 
57  if cb_fct is None:
58  cb_fct = self.default_cb_fct
59  # create the C-callback function wrapper
60  self.msg.info ("creating the C-callback function")
61  self.cb_fct = self._cb_fct_type(cb_fct)
62 
63  # create a CSV file holding the monitoring data
64  import csv
65  if fname is None:
66  fname = 'vmem-dso.csv'
67  if os.path.exists (fname):
68  os.remove (fname)
69  self._fd = open (fname, 'w')
70  self.out = csv.writer (self._fd, delimiter=';')
71  map (self.out.writerow,
72  [ ['master-pid', os.getpid()],
73  ['pid', 'libname',
74  'vmem-start (kb)', 'vmem-stop (kb)', 'dvmem (kb)'],
75  ])
76 
77  # start logging...
78  self.msg.info ("initializing the C-dlopen-logger")
79  self.lib.ath_dso_cbk_register(self.cb_fct, None)
80 
81  def __del__ (self):
82  # release library
83  self.lib.ath_dso_cbk_unregister(self.cb_fct)
84  self._fd.close()
85 
86  if sys.platform != 'darwin':
87  def default_cb_fct (self, evt, usrdata):
88  libname = evt.contents.fname
89  step = evt.contents.step
90 
91  if libname is None:
92  return 0
93  n = _basename (_realpath (libname))
94 
95  pid = os.getpid()
96  def vmem():
97  from os import sysconf
98  PAGE_SIZE = sysconf ('SC_PAGE_SIZE') # in bytes
99 
100  from string import split as ssplit
101  m = 0
102  with open('/proc/self/statm') as f:
103  m = int(ssplit (f.readlines()[0])[0])
104  return m * PAGE_SIZE # in bytes
105 
106  if step == 0:
107  self._data[pid][n] = [vmem(), None]
108  else:
109  data = self._data[pid][n]
110  data[1] = vmem()
111  vmem_start = data[0]/1024.
112  vmem_stop = data[1]/1024.
113  dvmem = vmem_stop - vmem_start
114  self.msg.info (
115  "[%d] loading lib: vmem=(%10.1f + %10.1f) kb [%s]",
116  pid, vmem_start, dvmem, n
117  )
118  self.out.writerow ([pid, n, vmem_start, vmem_stop, dvmem])
119  #del self._data[pid][n]
120  return 0
121  else:
122  def default_cb_fct (self, evt, usrdata):
123  libname = evt.fname
124  step = evt.step
125 
126  if libname is None:
127  return 0
128  n = _basename (_realpath (libname))
129 
130  pid = os.getpid()
131  def vmem():
132  from os import sysconf
133  PAGE_SIZE = sysconf ('SC_PAGE_SIZE') # in bytes
134  return PAGE_SIZE
135 
136  if step == 0:
137  self._data[pid][n] = [vmem(), None]
138  else:
139  data = self._data[pid][n]
140  data[1] = vmem()
141  vmem_start = data[0]/1024.
142  vmem_stop = data[1]/1024.
143  dvmem = vmem_stop - vmem_start
144  self.msg.info (
145  "[%d] loading lib: vmem=(%10.1f + %10.1f) kb [%s]",
146  pid, vmem_start, dvmem, n
147  )
148  self.out.writerow ([pid, n, vmem_start, vmem_stop, dvmem])
149  #del self._data[pid][n]
150  return 0
python.AthDsoLogger.default_cb_fct
def default_cb_fct(self, evt, usrdata)
Definition: AthDsoLogger.py:87
python.AthDsoLogger.DsoLogger.lib
lib
Definition: AthDsoLogger.py:34
ath_dso_cbk_register
int ath_dso_cbk_register(ath_dso_event_cbk_t cbk, void *userdata)
python.AthDsoLogger.DsoEvent
Definition: AthDsoLogger.py:19
Trk::open
@ open
Definition: BinningType.h:40
python.AthDsoLogger.DsoLogger.__init__
def __init__(self, fname=None, cb_fct=None)
Definition: AthDsoLogger.py:27
python.CaloAddPedShiftConfig.int
int
Definition: CaloAddPedShiftConfig.py:45
python.AthDsoLogger.__del__
def __del__(self)
Definition: AthDsoLogger.py:81
pickleTool.object
object
Definition: pickleTool.py:29
ath_dso_cbk_unregister
int ath_dso_cbk_unregister(ath_dso_event_cbk_t cbk)
python.AthDsoLogger.DsoLogger
Definition: AthDsoLogger.py:26