stopwatch.h revision b0ba9854ae1310425d7c09c72c528239a001e7c7
139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania/* 239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Copyright (C) 2009 The Android Open Source Project 339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * All rights reserved. 439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * 539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * Redistribution and use in source and binary forms, with or without 639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * modification, are permitted provided that the following conditions 739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * are met: 839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * * Redistributions of source code must retain the above copyright 939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * notice, this list of conditions and the following disclaimer. 1039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * * Redistributions in binary form must reproduce the above copyright 1139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * notice, this list of conditions and the following disclaimer in 1239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * the documentation and/or other materials provided with the 1339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * distribution. 1439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * 1539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 1639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 1739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 1839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 1939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 2039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 2139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS 2239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 2339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 2439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 2539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania * SUCH DAMAGE. 2739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania */ 2839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 2939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#ifndef ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_ 3039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#define ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_ 3139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 3239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <stdlib.h> 3339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <stdio.h> 3439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#include <time.h> 3539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 3639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catanianamespace android_test { 3739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 3839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// StopWatch class to collect execution statistics. 3939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 4039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Once the watch has been created, start and stop can be called to 4139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// capture an event duration. 4239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 4339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// On completion, use 'sprint' to retrieve the data. 4439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 4539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// If StopWatch::setPrintRawMode(true) has been called, the raw 4639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// samples also are printed. 4739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// The print method is thread safe to avoid mixing the result of 4839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// watches on different threads. For processes, use different files 4939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// that you concat after the run. 5039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 5139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// If the time measure is associated with some volume of data, use 5239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// setMbytes, the print method will compute the average throughput 5339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// based on that value. 5439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 5539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// To capture the time accurately and since the runs are not too long, 5639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// we collect the raw start and stop time in an array that get 5739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// processed once all the measurements have been done. 5839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 5939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// Typical Usage: 6039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// ============== 6139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 6239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// StopWatch watch("my name", 20); 6339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 6439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// for (int i = 0; i < 20; ++i) { 6539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// watch.start(); 6639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// doMyStuff(); 6739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// watch.stop(); 6839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// } 6939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// char buffer[4096]; 7039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// char *str = buffer; 7139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// size_t size = sizeof(buffer); 7239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// watch.sprint(&str, &size); 7339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania// 7439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 7539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Cataniaclass StopWatch { 7639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania public: 7739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Time of the snapshot and its nature (start of the interval or end of it). 7839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania struct Measurement { 7939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania struct timespec mTime; 8039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania bool mIsStart; 8139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania }; 8239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania static const size_t kUseDefaultCapacity = 20; 8339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 8439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Create a stop watch. Default capacity == 2 * interval_nb 8539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // @param name To be used when the results are displayed. No 8639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // spaces, use _ instead. 8739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // @param capacity Hint about the number of sampless that will be 8839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // measured (1 sample == 1 start + 1 stop). Used 8939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // to size the internal storage, when the capacity 9039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // is reached, it is doubled. 9139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania StopWatch(const char *name, size_t capacity = kUseDefaultCapacity); 9239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania ~StopWatch(); 9339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 9439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // A StopWatch instance measures time intervals. Use setDataSize 9539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // if some volume of data is processed during these intervals, to 9639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // get the average throughput (in kbytes/s) printed. 9739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void setDataSize(size_t size_in_bytes) { mSizeKbytes = size_in_bytes / 1000; } 9839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 9939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Starts and stops the timer. The time between the 2 calls is an 10039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // interval whose duration will be reported in sprint. 10139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void start(); 10239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void stop(); 10339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 10439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Print a summary of the measurement and optionaly the raw data. 10539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // The summary is commented out using a leading '#'. The raw data 10639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // is a pair (time, duration). The 1st sample is always at time 10739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // '0.0'. 10839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // @param str[inout] On entry points to the begining of a buffer 10939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // where to write the data. On exit points pass the last byte 11039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // written. 11139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // @param size[inout] On entry points to the size of the buffer 11239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // pointed by *str. On exit *size is the amount of free space left 11339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // in the buffer. If there was not enough space the data is truncated 11439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // and a warning is printed. 11539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void sprint(char **str, size_t *size); 11639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 11739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // @return true if at least one interval was timed. 11839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania bool used() const { return mUsed; } 11939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 12039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Affects all the timers. Instructs all the timers to print the 12139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // raw data as well as the summary. 12239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania static void setPrintRawMode(bool printRaw); 12339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 12439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania private: 12539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void checkCapacity(); 12639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania double timespecToDouble(const struct timespec& time); 12739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void printAverageMinMax(char **str, size_t *size); 12839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void printThroughput(char **str, size_t *size); 12939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania // Allocate mDeltas and fill it in. Search for the min and max. 13039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania void processSamples(); 13139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 13239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania char *const mName; // Name of the test. 13339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania struct timespec mStart; 13439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania size_t mNum; // # of intervals == # of start() calls. 13539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania struct Measurement *mData; 13639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania size_t mDataLen; 13739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania size_t mCapacity; 13839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania int mSizeKbytes; 13939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 14039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania bool mAlreadyPrinted; 14139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania bool mPrintRaw; 14239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 14339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania double mDuration; 144b0ba9854ae1310425d7c09c72c528239a001e7c7Xia Wang double mDeviation; 14539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania double mMinDuration; 14639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania size_t mMinIdx; 14739c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania double mMaxDuration; 14839c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania size_t mMaxIdx; 14939c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania double *mDeltas; 15039c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 15139c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania bool mUsed; 15239c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania}; 15339c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 15439c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania} // namespace android_test 15539c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania 15639c016f875b793296a121f41de5775b88f6fa1c9Nicolas Catania#endif // ANDROID_NATIVETEST_SYSTEM_EXTRAS_TESTS_SDCARD_STOPWATCH_H_ 157