Quick Links:

bal | bbl | bdl | bsl

Namespaces

Component balb_performancemonitor
[Package balb]

Provide a mechanism to collect process performance measures. More...

Namespaces

namespace  balb

Detailed Description

Outline
Purpose:
Provide a mechanism to collect process performance measures.
Classes:
balb::PerformanceMonitor monitor process performance
balb::PerformanceMonitor::Statistics performance stats
balb::PerformanceMonitor::ConstIterator stats iteration
Description:
This component provides an application developer the means to collect and report performance statistics for an arbitrary number of processes running on the local machine. The balb::PerformanceMonitor provides the mechanism for doing so, the balb::PerformanceMonitor::Statistics class holds the data and the balb::PerformanceMonitor::ConstIterator class is used to iterate over the data. The following table describes the measures collecting by this component. Note that all the collected measures are specific to the monitored process and do not refer to any system-wide measurement.
 Measure           Identifier           Description
 -------           ----------           -----------
 User CPU Time     e_CPU_TIME_USER      Total amount of time spent executing
                                        instructions in user mode.

 System CPU Time   e_CPU_TIME_SYSTEM    Total amount of time spent executing
                                        instructions in kernel mode.

 CPU Time          e_CPU_TIME           The sum of User and System CPU times.

 User CPU %        e_CPU_UTIL_USER      Percentage of elapsed CPU time this
                                        process spent executing instructions
                                        in user mode.

 System CPU %      e_CPU_UTIL_SYSTEM    Percentage of elapsed CPU time this
                                        process spent executing instructions
                                        in kernel mode.

 CPU %             e_CPU_UTIL           Sum of User CPU % and System CPU %.

 Resident Size     e_RESIDENT_SIZE      Number of mega-bytes of physical
                                        memory used by the process.

 Virtual Size      e_VIRTUAL_SIZE       The size of the heap, in
                                        mega-bytes. This value does not
                                        include the size of the address
                                        space mapped to files (anonymous or
                                        otherwise.)

 Thread Count      e_NUM_THREADS        Number of threads executing in the
                                        process.

 Page Faults       e_NUM_PAGEFAULTS     Total number of page faults incurred
                                        throughout the lifetime of the
                                        process.
OS-Specific Permissions:
Various OSs might require specific permissions in order to inspect processes other than the current process. For example, on Darwin, users other than root can only inspect processes running under the user with which the current process is running. This error condition will be indicated by a non-zero return value from registerPid.
Unsupported Platform/Compiler mode - Solaris/g++/32-bits:
Note that this component is not supported when building in 32-bit mode with the g++ compiler on Solaris, due to Solaris's procfs.h header not supporting that compiler in 32-bit mode. (DRQS 170291732)
Iterator Invalidation:
Registration of new pids does not invalidate existing iterators. Unregistration of a pid invalidates only iterators pointing to the statistics for the pid being unregistered. Additionally, unregistering a pid with a balb::PerformanceMonitor object invalidates all references to Statistics objects retrieved from those iterators. All other iterators remain valid.
Thread Safety:
The classes balb::PerformanceMonitor and balb::PerformanceMonitory::Statistics, provided by this component, are both independently fully thread-safe (see bsldoc_glossary). However, balb::PerformanceMonitor::ConstIterator is only const thread-safe, meaning it is not safe to access or modify a ConstIterator in one thread while another thread modifies the same object. As unregistering a pid with a balb::PerformanceMonitor object invalidates iterators (see Iterator Invalidation), external synchronization is needed if unregisterPid is called concurrently to iterating over statistics. Also, in a multi-threaded context, a Statistics object accessed via a reference (or pointer) from a ConstIterator object may have its statistics updated at any time by a call to collect or resetStatistics in another thread. If consistent access is needed to multiple items in a set of statistics, then the user should copy the statistics object, and then inspect the copy at their leisure.
Notice that this component was implemented with particular usage patterns in mind, which are captured in the usage examples.
Usage:
This section illustrates intended use of this component.
Example 1: Basic Use of balb::PerformanceMonitor:
The following example shows how to monitor the currently executing process and produce a formatted report of the collected measures after a certain interval.
First, we instantiate a scheduler used by the performance monitor to schedule collection events.
  bdlmt::TimerEventScheduler scheduler;
  scheduler.start();
Then, we create the performance monitor, monitoring the current process and auto-collecting statistics every second.
  balb::PerformanceMonitor perfmon(&scheduler, 1.0);
  int                      rc  = perfmon.registerPid(0, "perfmon");
  const int                pid = bdls::ProcessUtil::getProcessId();

  assert(0 == rc);
  assert(1 == perfmon.numRegisteredPids());
Next, we print a formatted report of the performance statistics collected for each pid every 5 seconds for half a minute. Note, that Statistics object can be simultaneously modified by scheduler callback and accessed via a ConstIterator. To ensure that the call to Statistics::print outputs consistent data from a single update of the statistics for this process, we create a local copy (copy construction is guaranteed to be thread-safe).
  for (int i = 0; i < 6; ++i) {
      bslmt::ThreadUtil::microSleep(0, 5);

      balb::PerformanceMonitor::ConstIterator    it    = perfmon.begin();
      const balb::PerformanceMonitor::Statistics stats = *it;

      assert(pid == stats.pid());

      bsl::cout << "PID = " << stats.pid() << ":\n";
      stats.print(bsl::cout);
  }
Finally, we unregister the process and stop the scheduler to cease collecting statistics for this process. It is safe to call unregisterPid here, because we don't have any ConstIterators objects or references to Statistics objects.
  rc  = perfmon.unregisterPid(pid);

  assert(0 == rc);
  assert(0 == perfmon.numRegisteredPids());

  scheduler.stop();