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