Changeset 70


Ignore:
Timestamp:
Nov 21, 2005 4:59:47 PM (18 years ago)
Author:
bennylp
Message:

Added rdtsc option for win32 timestamp and added pj_elapsed_msec

Location:
pjproject/trunk/pjlib
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • pjproject/trunk/pjlib/include/pj/config.h

    r66 r70  
    9898#   undef PJ_HAS_EVENT_OBJ 
    9999#   undef PJ_ENABLE_EXTRA_CHECK 
     100#   undef PJ_EXCEPTION_USE_WIN32_SEH 
    100101#endif 
    101102 
     
    320321#endif 
    321322 
     323/** 
     324 * Should we use Windows Structured Exception Handling (SEH) for the 
     325 * PJLIB exceptions. 
     326 * 
     327 * Default: 0 
     328 */ 
     329#ifndef PJ_EXCEPTION_USE_WIN32_SEH 
     330#  define PJ_EXCEPTION_USE_WIN32_SEH 0 
     331#endif 
     332 
     333/** 
     334 * Should we attempt to use Pentium's rdtsc for high resolution 
     335 * timestamp. 
     336 * 
     337 * Default: 0 
     338 */ 
     339#ifndef PJ_TIMESTAMP_USE_RDTSC 
     340#   define PJ_TIMESTAMP_USE_RDTSC   0 
     341#endif 
     342 
     343 
    322344/** @} */ 
    323345 
     
    354376#  define PJ_DECL(type)             type 
    355377#  define PJ_DECL_NO_RETURN(type)   type PJ_NORETURN 
     378#  define PJ_IDECL_NO_RETURN(type)  PJ_INLINE(type) PJ_NORETURN 
    356379#  define PJ_BEGIN_DECL             extern "C" { 
    357380#  define PJ_END_DECL               } 
     
    359382#  define PJ_DECL(type)             extern type 
    360383#  define PJ_DECL_NO_RETURN(type)   PJ_NORETURN type 
     384#  define PJ_IDECL_NO_RETURN(type)  PJ_NORETURN PJ_INLINE(type) 
    361385#  define PJ_BEGIN_DECL 
    362386#  define PJ_END_DECL 
  • pjproject/trunk/pjlib/include/pj/os.h

    r66 r70  
    923923 
    924924/** 
     925 * Calculate the elapsed time as 32-bit miliseconds. 
     926 * This function calculates the elapsed time using highest precision 
     927 * calculation that is available for current platform, considering 
     928 * whether floating point or 64-bit precision arithmetic is available.  
     929 * For maximum portability, application should prefer to use this function 
     930 * rather than calculating the elapsed time by itself. 
     931 * 
     932 * @param start     The starting timestamp. 
     933 * @param stop      The end timestamp. 
     934 * 
     935 * @return          Elapsed time in milisecond. 
     936 * 
     937 * @see pj_elapsed_time(), pj_elapsed_cycle(), pj_elapsed_nanosec() 
     938 */ 
     939PJ_DECL(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start, 
     940                                      const pj_timestamp *stop ); 
     941 
     942/** 
    925943 * Calculate the elapsed time in 32-bit microseconds. 
    926944 * This function calculates the elapsed time using highest precision 
  • pjproject/trunk/pjlib/src/pj/os_core_win32.c

    r66 r70  
    162162    { 
    163163        pj_timestamp dummy_ts; 
     164        if ((rc=pj_get_timestamp_freq(&dummy_ts)) != PJ_SUCCESS) { 
     165            return rc; 
     166        } 
    164167        if ((rc=pj_get_timestamp(&dummy_ts)) != PJ_SUCCESS) { 
    165             PJ_LOG(1, ("pj_init", "Unable to initialize timestamp")); 
    166168            return rc; 
    167169        } 
  • pjproject/trunk/pjlib/src/pj/os_timestamp_common.c

    r66 r70  
    2727#define MSEC    (1000) 
    2828 
     29#define u64tohighprec(u64)      ((pj_highprec_t)((pj_int64_t)(u64))) 
     30 
    2931static pj_highprec_t get_elapsed( const pj_timestamp *start, 
    3032                                  const pj_timestamp *stop ) 
    3133{ 
     34#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 
     35    return u64tohighprec(stop->u64 - start->u64); 
     36#else 
    3237    pj_highprec_t elapsed_hi, elapsed_lo; 
    3338 
     
    3944 
    4045    return elapsed_hi + elapsed_lo; 
     46#endif 
     47} 
     48 
     49static pj_highprec_t elapsed_msec( const pj_timestamp *start, 
     50                                   const pj_timestamp *stop ) 
     51{ 
     52    pj_timestamp ts_freq; 
     53    pj_highprec_t freq, elapsed; 
     54 
     55    if (pj_get_timestamp_freq(&ts_freq) != PJ_SUCCESS) 
     56        return 0; 
     57 
     58    /* Convert frequency timestamp */ 
     59#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 
     60    freq = u64tohighprec(ts_freq.u64); 
     61#else 
     62    freq = ts_freq.u32.hi; 
     63    pj_highprec_mul(freq, U32MAX); 
     64    freq += ts_freq.u32.lo; 
     65#endif 
     66 
     67    /* Avoid division by zero. */ 
     68    if (freq == 0) freq = 1; 
     69 
     70    /* Get elapsed time in cycles. */ 
     71    elapsed = get_elapsed(start, stop); 
     72 
     73    /* usec = elapsed * MSEC / freq */ 
     74    pj_highprec_mul(elapsed, MSEC); 
     75    pj_highprec_div(elapsed, freq); 
     76 
     77    return elapsed; 
    4178} 
    4279 
     
    5188 
    5289    /* Convert frequency timestamp */ 
     90#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 
     91    freq = u64tohighprec(ts_freq.u64); 
     92#else 
    5393    freq = ts_freq.u32.hi; 
    5494    pj_highprec_mul(freq, U32MAX); 
    5595    freq += ts_freq.u32.lo; 
     96#endif 
    5697 
    5798    /* Avoid division by zero. */ 
     
    78119 
    79120    /* Convert frequency timestamp */ 
     121#if defined(PJ_HAS_INT64) && PJ_HAS_INT64!=0 
     122    freq = u64tohighprec(ts_freq.u64); 
     123#else 
    80124    freq = ts_freq.u32.hi; 
    81125    pj_highprec_mul(freq, U32MAX); 
    82126    freq += ts_freq.u32.lo; 
     127#endif 
    83128 
    84129    /* Avoid division by zero. */ 
     
    101146} 
    102147 
     148PJ_DEF(pj_uint32_t) pj_elapsed_msec( const pj_timestamp *start, 
     149                                     const pj_timestamp *stop ) 
     150{ 
     151    return (pj_uint32_t)elapsed_msec(start, stop); 
     152} 
     153 
    103154PJ_DEF(pj_time_val) pj_elapsed_time( const pj_timestamp *start, 
    104155                                     const pj_timestamp *stop ) 
    105156{ 
    106     pj_highprec_t elapsed = elapsed_usec(start, stop); 
     157    pj_highprec_t elapsed = elapsed_msec(start, stop); 
    107158    pj_time_val tv_elapsed; 
    108159 
     
    114165 
    115166        sec = elapsed; 
    116         pj_highprec_div(sec, USEC); 
     167        pj_highprec_div(sec, MSEC); 
    117168        tv_elapsed.sec = (long)sec; 
    118169 
    119170        msec = elapsed; 
    120         pj_highprec_mod(msec, USEC); 
    121         pj_highprec_div(msec, 1000); 
     171        pj_highprec_mod(msec, MSEC); 
    122172        tv_elapsed.msec = (long)msec; 
    123173 
  • pjproject/trunk/pjlib/src/pj/os_timestamp_win32.c

    r66 r70  
    2121#include <windows.h> 
    2222 
     23#if defined(PJ_TIMESTAMP_USE_RDTSC) && PJ_TIMESTAMP_USE_RDTSC!=0 && \ 
     24    defined(PJ_M_I386) && PJ_M_I386 != 0 && \ 
     25    defined(_MSC_VER) 
     26/* 
     27 * Use rdtsc to get the OS timestamp. 
     28 */ 
     29static LONG CpuMhz; 
     30static pj_int64_t CpuHz; 
     31  
     32static pj_status_t GetCpuHz(void) 
     33{ 
     34    HKEY key; 
     35    LONG rc; 
     36    DWORD size; 
     37 
     38    rc = RegOpenKey( HKEY_LOCAL_MACHINE, 
     39                     "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 
     40                     &key); 
     41    if (rc != ERROR_SUCCESS) 
     42        return PJ_RETURN_OS_ERROR(rc); 
     43 
     44    size = sizeof(CpuMhz); 
     45    rc = RegQueryValueEx(key, "~MHz", NULL, NULL, (BYTE*)&CpuMhz, &size); 
     46    RegCloseKey(key); 
     47 
     48    if (rc != ERROR_SUCCESS) { 
     49        return PJ_RETURN_OS_ERROR(rc); 
     50    } 
     51 
     52    CpuHz = CpuMhz; 
     53    CpuHz = CpuHz * 1000000; 
     54 
     55    return PJ_SUCCESS; 
     56} 
     57 
     58/* __int64 is nicely returned in EDX:EAX */ 
     59__declspec(naked) __int64 rdtsc()  
     60{ 
     61    __asm  
     62    { 
     63        RDTSC 
     64        RET 
     65    } 
     66} 
     67 
     68PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts) 
     69{ 
     70    ts->u64 = rdtsc(); 
     71    return PJ_SUCCESS; 
     72} 
     73 
     74PJ_DEF(pj_status_t) pj_get_timestamp_freq(pj_timestamp *freq) 
     75{ 
     76    pj_status_t status; 
     77 
     78    if (CpuHz == 0) { 
     79        status = GetCpuHz(); 
     80        if (status != PJ_SUCCESS) 
     81            return status; 
     82    } 
     83 
     84    freq->u64 = CpuHz; 
     85    return PJ_SUCCESS; 
     86} 
     87 
     88#else 
     89/* 
     90 * Use QueryPerformanceCounter and QueryPerformanceFrequency. 
     91 */ 
    2392PJ_DEF(pj_status_t) pj_get_timestamp(pj_timestamp *ts) 
    2493{ 
     
    43112} 
    44113 
     114#endif  /* PJ_TIMESTAMP_USE_RDTSC */ 
     115 
  • pjproject/trunk/pjlib/src/pjlib-test/sleep.c

    r65 r70  
    125125        pj_time_val t1, t2; 
    126126        pj_timestamp start, stop; 
    127         pj_time_val elapsed; 
    128127        pj_uint32_t msec; 
     128 
     129        pj_thread_sleep(0); 
    129130 
    130131        /* Mark start of test. */ 
     
    157158        } 
    158159 
    159         /* Get elapsed time in time_val */ 
    160         elapsed = pj_elapsed_time(&start, &stop); 
    161  
    162         msec = PJ_TIME_VAL_MSEC(elapsed); 
     160        /* Get elapsed time in msec */ 
     161        msec = pj_elapsed_msec(&start, &stop); 
    163162 
    164163        /* Check if it's within range. */ 
     
    170169                      "(outside %d%% err window)", 
    171170                      msec, DURATION2, MIS)); 
    172             return -30; 
     171            PJ_TIME_VAL_SUB(t2, t1); 
     172            PJ_LOG(3,(THIS_FILE,  
     173                      "...info: gettimeofday() reported duration is " 
     174                      "%d msec", 
     175                      PJ_TIME_VAL_MSEC(t2))); 
     176 
     177            return -76; 
    173178        } 
    174179    } 
Note: See TracChangeset for help on using the changeset viewer.