Home | History | Annotate | Download | only in cpustats
      1 /*
      2  * Copyright (C) 2011 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef _THREAD_CPU_USAGE_H
     18 #define _THREAD_CPU_USAGE_H
     19 
     20 #include <cpustats/CentralTendencyStatistics.h>
     21 
     22 // Track CPU usage for the current thread, and maintain statistics on
     23 // the CPU usage.  Units are in per-thread CPU ns, as reported by
     24 // clock_gettime(CLOCK_THREAD_CPUTIME_ID).  Simple usage: for cyclic
     25 // threads where you want to measure the execution time of the whole
     26 // cycle, just call sampleAndEnable() at the start of each cycle.
     27 // Then call statistics() to get the results, and resetStatistics()
     28 // to start a new set of measurements.
     29 // For acyclic threads, or for cyclic threads where you want to measure
     30 // only part of each cycle, call enable(), disable(), and/or setEnabled()
     31 // to demarcate the region(s) of interest, and then call sample() periodically.
     32 // This class is not thread-safe for concurrent calls from multiple threads;
     33 // the methods of this class may only be called by the current thread
     34 // which constructed the object.
     35 
     36 class ThreadCpuUsage
     37 {
     38 
     39 public:
     40     ThreadCpuUsage() :
     41         mIsEnabled(false),
     42         mWasEverEnabled(false),
     43         mAccumulator(0),
     44         // mPreviousTs
     45         // mMonotonicTs
     46         mMonotonicKnown(false)
     47         // mStatistics
     48         { }
     49 
     50     ~ThreadCpuUsage() { }
     51 
     52     // Return whether currently tracking CPU usage by current thread
     53     bool isEnabled()    { return mIsEnabled; }
     54 
     55     // Enable tracking of CPU usage by current thread;
     56     // any CPU used from this point forward will be tracked.
     57     // Returns the previous enabled status.
     58     bool enable()       { return setEnabled(true); }
     59 
     60     // Disable tracking of CPU usage by current thread;
     61     // any CPU used from this point forward will be ignored.
     62     // Returns the previous enabled status.
     63     bool disable()      { return setEnabled(false); }
     64 
     65     // Set the enabled status and return the previous enabled status.
     66     // This method is intended to be used for safe nested enable/disabling.
     67     bool setEnabled(bool isEnabled);
     68 
     69     // Add a sample point for central tendency statistics, and also
     70     // enable tracking if needed.  If tracking has never been enabled, then
     71     // enables tracking but does not add a sample (it is not possible to add
     72     // a sample the first time because no previous).  Otherwise if tracking is
     73     // enabled, then adds a sample for tracked CPU ns since the previous
     74     // sample, or since the first call to sampleAndEnable(), enable(), or
     75     // setEnabled(true).  If there was a previous sample but tracking is
     76     // now disabled, then adds a sample for the tracked CPU ns accumulated
     77     // up until the most recent disable(), resets this accumulator, and then
     78     // enables tracking.  Calling this method rather than enable() followed
     79     // by sample() avoids a race condition for the first sample.
     80     void sampleAndEnable();
     81 
     82     // Add a sample point for central tendency statistics, but do not
     83     // change the tracking enabled status.  If tracking has either never been
     84     // enabled, or has never been enabled since the last sample, then log a warning
     85     // and don't add sample.  Otherwise, adds a sample for tracked CPU ns since
     86     // the previous sample or since the first call to sampleAndEnable(),
     87     // enable(), or setEnabled(true) if no previous sample.
     88     void sample();
     89 
     90     // Return the elapsed delta wall clock ns since initial enable or statistics reset,
     91     // as reported by clock_gettime(CLOCK_MONOTONIC).
     92     long long elapsed() const;
     93 
     94     // Reset statistics and elapsed.  Has no effect on tracking or accumulator.
     95     void resetStatistics();
     96 
     97     // Return a const reference to the central tendency statistics.
     98     // Note that only the const methods can be called on this object.
     99     const CentralTendencyStatistics& statistics() const {
    100         return mStatistics;
    101     }
    102 
    103 private:
    104     bool mIsEnabled;                // whether tracking is currently enabled
    105     bool mWasEverEnabled;           // whether tracking was ever enabled
    106     long long mAccumulator;         // accumulated thread CPU time since last sample, in ns
    107     struct timespec mPreviousTs;    // most recent thread CPU time, valid only if mIsEnabled is true
    108     struct timespec mMonotonicTs;   // most recent monotonic time
    109     bool mMonotonicKnown;           // whether mMonotonicTs has been set
    110     CentralTendencyStatistics mStatistics;
    111 };
    112 
    113 #endif //  _THREAD_CPU_USAGE_H
    114