tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

utimer.h (9289B)


      1 // © 2016 and later: Unicode, Inc. and others.
      2 // License & terms of use: http://www.unicode.org/copyright.html
      3 /*
      4 ************************************************************************
      5 * Copyright (c) 1997-2012, International Business Machines
      6 * Corporation and others.  All Rights Reserved.
      7 ************************************************************************
      8 */
      9 
     10 #ifndef _UTIMER_H
     11 #define _UTIMER_H
     12 
     13 #include "unicode/utypes.h"
     14 
     15 #if U_PLATFORM_USES_ONLY_WIN32_API
     16 #   define VC_EXTRALEAN
     17 #   define WIN32_LEAN_AND_MEAN
     18 #   include <windows.h>
     19 #else
     20 #   if U_PLATFORM == U_PF_OS390 && !defined(__UU)
     21 #     define __UU  /* Universal Unix - for struct timeval */
     22 #   endif
     23 #   include <time.h>
     24 #   include <sys/time.h> 
     25 #   include <unistd.h> 
     26 #endif
     27 
     28 /**
     29 * This API provides functions for performing performance measurement
     30 * There are 3 main usage scenarios.
     31 * i) Loop until a threshold time is reached:
     32 *    Example:
     33 *    <code>
     34 *      typedef Params Params;
     35 *      struct Params{
     36 *          char16_t* target;
     37 *          int32_t targetLen;
     38 *          const char16_t* source;
     39 *          int32_t sourceLen;
     40 *          UNormalizationMode mode;
     41 *      }
     42 *      void NormFn( void* param){
     43 *          Params* parameters = ( Params*) param;
     44 *          UErrorCode error = U_ZERO_ERROR;
     45 *          unorm_normalize(parameters->source, parameters->sourceLen, parameters->mode, 0, parameters->target, parameters->targetLen, &error);
     46 *          if(U_FAILURE(error)){
     47 *              printf("Normalization failed\n");
     48 *          }
     49 *      }
     50 *  
     51 *      int main(){
     52 *          // time the normalization function 
     53 *          double timeTaken = 0;
     54 *          Params param;
     55 *          param.source  // set up the source buffer 
     56 *          param.target   // set up the target buffer
     57 *          .... so on ...
     58 *          UTimer timer;
     59 *          // time the loop for 10 seconds at least and find out the loop count and time taken
     60 *          timeTaken = utimer_loopUntilDone((double)10,(void*) param, NormFn, &loopCount);
     61 *      }
     62 *     </code>
     63 *
     64 * ii) Measure the time taken
     65 *     Example:
     66 *     <code>
     67 *      double perfNormalization(NormFn fn,const char* mode,Line* fileLines,int32_t loopCount){
     68 *          int  line;
     69 *          int  loops;
     70 *          UErrorCode error = U_ZERO_ERROR;
     71 *          char16_t* dest=nullptr;
     72 *          int32_t destCapacity=0;
     73 *          int len =-1;
     74 *          double elapsedTime = 0; 
     75 *          int retVal=0;
     76 *
     77 *          char16_t arr[5000];
     78 *          dest=arr;
     79 *          destCapacity = 5000;
     80 *          UTimer start;
     81 *
     82 *          // Initialize cache and ensure the data is loaded.
     83 *          // This loop checks for errors in Normalization. Once we pass the initialization
     84 *          // without errors we can safelly assume that there are no errors while timing the 
     85 *          // function
     86 *          for (loops=0; loops<10; loops++) {
     87 *              for (line=0; line < gNumFileLines; line++) {
     88 *                  if (opt_uselen) {
     89 *                      len = fileLines[line].len;
     90 *                  }
     91 *
     92 *                  retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
     93 *      #if U_PLATFORM_HAS_WIN32_API
     94 *                  if(retVal==0 ){
     95 *                      fprintf(stderr,"Normalization of string in Windows API failed for mode %s. ErrorNo: %i at line number %i\n",mode,GetLastError(),line);
     96 *                      return 0;
     97 *                  }
     98 *      #endif
     99 *                  if(U_FAILURE(error)){
    100 *                      fprintf(stderr,"Normalization of string in ICU API failed for mode %s. Error: %s at line number %i\n",mode,u_errorName(error),line);
    101 *                      return 0;
    102 *                  }
    103 *        
    104 *              }
    105 *          }
    106 *
    107 *          //compute the time
    108 *
    109 *          utimer_getTime(&start);
    110 *          for (loops=0; loops<loopCount; loops++) {
    111 *              for (line=0; line < gNumFileLines; line++) {
    112 *                  if (opt_uselen) {
    113 *                      len = fileLines[line].len;
    114 *                  }
    115 *
    116 *                  retVal= fn(fileLines[line].name,len,dest,destCapacity,&error);
    117 *       
    118 *              }
    119 *          }
    120 *
    121 *          return utimer_getElapsedSeconds(&start);
    122 *      }
    123 *      </code>
    124 *
    125 * iii) Let a higher level function do the calculation of confidence levels etc.
    126 *     Example:
    127 *     <code>
    128 *       void perf(UTimer* timer, char16_t* source, int32_t sourceLen, char16_t* target, int32_t targetLen, int32_t loopCount,UNormalizationMode mode, UErrorCode* error){
    129 *              int32_t loops;
    130 *              for (loops=0; loops<loopCount; loops++) {
    131 *                  unorm_normalize(source,sourceLen,target, targetLen,mode,error);
    132 *              }
    133 *              utimer_getTime(timer);
    134 *       }
    135 *       void main(const char* argsc, int argv){
    136 *          // read the file and setup the data
    137 *          // set up options
    138 *          UTimer start,timer1, timer2, timer3, timer4;
    139 *          double NFDTimeTaken, NFCTimeTaken, FCDTimeTaken;
    140 *          switch(opt){
    141 *              case 0:
    142 *                  utimer_getTime(start);
    143 *                  perf(timer1, source,sourceLen, target, targetLen,loopCount,UNORM_NFD,&error);
    144 *                  NFDTimeTaken = utimer_getDeltaSeconds(start,timer1);
    145 *              case 1:
    146 *                  timer_getTime(start);
    147 *                  perf(timer2,source,sourceLen,target,targetLen,loopCount,UNORM_NFC,&error);
    148 *                  NFCTimeTaken = utimer_getDeltaSeconds(start,timer2);
    149 *                  perf(timer3, source, sourceLen, target,targetLen, loopCount, UNORM_FCD,&error);
    150 *              // ........so on .............          
    151 *           }
    152 *          // calculate confidence levels etc and print            
    153 *
    154 *       }
    155 *           
    156 *     </code>
    157 *      
    158 */
    159 
    160 typedef struct UTimer UTimer;
    161 
    162 typedef void FunctionToBeTimed(void* param);
    163 
    164 
    165 #if U_PLATFORM_USES_ONLY_WIN32_API
    166 
    167    struct UTimer{
    168        LARGE_INTEGER start;
    169        LARGE_INTEGER placeHolder;
    170    };      
    171        
    172 static    int uprv_initFrequency(UTimer* timer)
    173    {
    174        return QueryPerformanceFrequency(&timer->placeHolder);
    175    }
    176 static    void uprv_start(UTimer* timer)
    177    {
    178        QueryPerformanceCounter(&timer->start);
    179    }
    180 static    double uprv_delta(UTimer* timer1, UTimer* timer2){
    181        return ((double)(timer2->start.QuadPart - timer1->start.QuadPart))/((double)timer1->placeHolder.QuadPart);
    182    }
    183 static    UBool uprv_compareFrequency(UTimer* timer1, UTimer* timer2){
    184        return (timer1->placeHolder.QuadPart == timer2->placeHolder.QuadPart);
    185    }
    186 
    187 #else
    188 
    189    struct UTimer{
    190        struct timeval start;
    191        struct timeval placeHolder;
    192    };
    193    
    194 static    int32_t uprv_initFrequency(UTimer* /*timer*/)
    195    {
    196        return 0;
    197    }
    198 static    void uprv_start(UTimer* timer)
    199    {
    200        gettimeofday(&timer->start, nullptr);
    201    }
    202 static    double uprv_delta(UTimer* timer1, UTimer* timer2){
    203        double t1, t2;
    204 
    205        t1 =  (double)timer1->start.tv_sec + (double)timer1->start.tv_usec/(1000*1000);
    206        t2 =  (double)timer2->start.tv_sec + (double)timer2->start.tv_usec/(1000*1000);
    207        return (t2-t1);
    208    }
    209 static    UBool uprv_compareFrequency(UTimer* /*timer1*/, UTimer* /*timer2*/){
    210        return true;
    211    }
    212 
    213 #endif
    214 /**
    215 * Initializes the timer with the current time
    216 *
    217 * @param timer A pointer to UTimer struct to receive the current time
    218 */
    219 static inline void U_EXPORT2
    220 utimer_getTime(UTimer* timer){
    221    uprv_initFrequency(timer);
    222    uprv_start(timer);
    223 }
    224 
    225 /**
    226 * Returns the difference in times between timer1 and timer2 by subtracting
    227 * timer1's time from timer2's time
    228 *
    229 * @param timer1 A pointer to UTimer struct to be used as starting time
    230 * @param timer2 A pointer to UTimer struct to be used as end time
    231 * @return Time in seconds
    232 */
    233 static inline double U_EXPORT2
    234 utimer_getDeltaSeconds(UTimer* timer1, UTimer* timer2){
    235    if(uprv_compareFrequency(timer1,timer2)){
    236        return uprv_delta(timer1,timer2);
    237    }
    238    /* got error return -1 */
    239    return -1;
    240 }
    241 
    242 /**
    243 * Returns the time elapsed from the starting time represented by the 
    244 * UTimer struct pointer passed
    245 * @param timer A pointer to UTimer struct to be used as starting time
    246 * @return Time elapsed in seconds
    247 */
    248 static inline double U_EXPORT2
    249 utimer_getElapsedSeconds(UTimer* timer){
    250    UTimer temp;
    251    utimer_getTime(&temp);
    252    return uprv_delta(timer,&temp);
    253 }
    254 
    255 /**
    256 * Executes the function pointed to for a given time and returns exact time
    257 * taken and number of iterations of the loop
    258 * @param thresholTimeVal 
    259 * @param loopCount output param to receive the number of iterations
    260 * @param fn    The function to be executed
    261 * @param param Parameters to be passed to the fn
    262 * @return the time elapsed in seconds
    263 */
    264 static inline double U_EXPORT2
    265 utimer_loopUntilDone(double thresholdTimeVal,
    266                     int32_t* loopCount, 
    267                     FunctionToBeTimed fn, 
    268                     void* param){
    269    UTimer timer;
    270    double currentVal=0;
    271    *loopCount = 0;
    272    utimer_getTime(&timer);
    273    for(;currentVal<thresholdTimeVal;){
    274        fn(param);
    275        currentVal = utimer_getElapsedSeconds(&timer);
    276        (*loopCount)++;
    277    }
    278    return currentVal;
    279 }
    280 
    281 #endif