Home | History | Annotate | Download | only in sdcard
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  *  * Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  *  * Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in
     12  *    the documentation and/or other materials provided with the
     13  *    distribution.
     14  *
     15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
     16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
     17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
     18  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
     19  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
     21  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
     22  * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
     23  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
     24  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
     25  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     26  * SUCH DAMAGE.
     27  */
     28 
     29 #ifndef ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
     30 #define ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
     31 
     32 #include <stdlib.h>
     33 #include <stdio.h>
     34 #include <time.h>
     35 
     36 namespace android_test {
     37 
     38 // StopWatch class to collect execution statistics.
     39 //
     40 // Once the watch has been created, start and stop can be called to
     41 // capture an event duration.
     42 //
     43 // On completion, use 'sprint' to retrieve the data.
     44 //
     45 // If StopWatch::setPrintRawMode(true) has been called, the raw
     46 // samples also are printed.
     47 // The print method is thread safe to avoid mixing the result of
     48 // watches on different threads. For processes, use different files
     49 // that you concat after the run.
     50 //
     51 // If the time measure is associated with some volume of data, use
     52 // setMbytes, the print method will compute the average throughput
     53 // based on that value.
     54 //
     55 // To capture the time accurately and since the runs are not too long,
     56 // we collect the raw start and stop time in an array that get
     57 // processed once all the measurements have been done.
     58 //
     59 // Typical Usage:
     60 // ==============
     61 //
     62 //  StopWatch watch("my name", 20);
     63 //
     64 //  for (int i = 0; i < 20; ++i) {
     65 //    watch.start();
     66 //    doMyStuff();
     67 //    watch.stop();
     68 //  }
     69 //  char buffer[4096];
     70 //  char *str = buffer;
     71 //  size_t size = sizeof(buffer);
     72 //  watch.sprint(&str, &size);
     73 //
     74 
     75 class StopWatch {
     76   public:
     77     // Time of the snapshot and its nature (start of the interval or end of it).
     78     struct Measurement {
     79         struct timespec mTime;
     80         bool mIsStart;
     81     };
     82     static const size_t kUseDefaultCapacity = 20;
     83 
     84     // Create a stop watch. Default capacity == 2 * interval_nb
     85     // @param name To be used when the results are displayed. No
     86     //             spaces, use _ instead.
     87     // @param capacity Hint about the number of sampless that will be
     88     //                 measured (1 sample == 1 start + 1 stop). Used
     89     //                 to size the internal storage, when the capacity
     90     //                 is reached, it is doubled.
     91     StopWatch(const char *name, size_t capacity = kUseDefaultCapacity);
     92     ~StopWatch();
     93 
     94     // A StopWatch instance measures time intervals. Use setDataSize
     95     // if some volume of data is processed during these intervals, to
     96     // get the average throughput (in kbytes/s) printed.
     97     void setDataSize(size_t size_in_bytes) { mSizeKbytes = size_in_bytes / 1000; }
     98 
     99     // Starts and stops the timer. The time between the 2 calls is an
    100     // interval whose duration will be reported in sprint.
    101     void start();
    102     void stop();
    103 
    104     // Print a summary of the measurement and optionaly the raw data.
    105     // The summary is commented out using a leading '#'.  The raw data
    106     // is a pair (time, duration). The 1st sample is always at time
    107     // '0.0'.
    108     // @param str[inout] On entry points to the begining of a buffer
    109     // where to write the data. On exit points pass the last byte
    110     // written.
    111     // @param size[inout] On entry points to the size of the buffer
    112     // pointed by *str. On exit *size is the amount of free space left
    113     // in the buffer. If there was not enough space the data is truncated
    114     // and a warning is printed.
    115     void sprint(char **str, size_t *size);
    116 
    117     // @return true if at least one interval was timed.
    118     bool used() const { return mUsed; }
    119 
    120     // Affects all the timers. Instructs all the timers to print the
    121     // raw data as well as the summary.
    122     static void setPrintRawMode(bool printRaw);
    123 
    124   private:
    125     void checkCapacity();
    126     double timespecToDouble(const struct timespec& time);
    127     void printAverageMinMax(char **str, size_t *size);
    128     void printThroughput(char **str, size_t *size);
    129     // Allocate mDeltas and fill it in. Search for the min and max.
    130     void processSamples();
    131 
    132     char *const mName;  // Name of the test.
    133     struct timespec mStart;
    134     size_t mNum; // # of intervals == # of start() calls.
    135     struct Measurement *mData;
    136     size_t mDataLen;
    137     size_t mCapacity;
    138     int mSizeKbytes;
    139 
    140     bool mAlreadyPrinted;
    141     bool mPrintRaw;
    142 
    143     double mDuration;
    144     double mDeviation;
    145     double mMinDuration;
    146     size_t mMinIdx;
    147     double mMaxDuration;
    148     size_t mMaxIdx;
    149     double *mDeltas;
    150 
    151     bool mUsed;
    152 };
    153 
    154 }  // namespace android_test
    155 
    156 #endif  // ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_
    157