Changeset 2560 for pjproject/trunk
- Timestamp:
- Mar 30, 2009 6:22:16 PM (16 years ago)
- Location:
- pjproject/trunk/pjlib
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
pjproject/trunk/pjlib/include/pj/os.h
r2481 r2560 1269 1269 1270 1270 /** 1271 * Variant of #pj_elapsed_msec() which returns 64bit value. 1272 */ 1273 PJ_DECL(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start, 1274 const pj_timestamp *stop ); 1275 1276 /** 1271 1277 * Calculate the elapsed time in 32-bit microseconds. 1272 1278 * This function calculates the elapsed time using highest precision -
pjproject/trunk/pjlib/src/pj/os_time_win32.c
r2394 r2560 20 20 #include <pj/os.h> 21 21 #include <pj/string.h> 22 #include <pj/log.h> 22 23 #include <windows.h> 23 24 … … 28 29 static LARGE_INTEGER base_time; 29 30 31 #if defined(PJ_WIN32_WINCE) && PJ_WIN32_WINCE 32 # define WINCE_TIME 33 #endif 34 35 #ifdef WINCE_TIME 36 /* Note: 37 * In Windows CE/Windows Mobile platforms, the availability of milliseconds 38 * time resolution in SYSTEMTIME.wMilliseconds depends on the OEM, and most 39 * likely it won't be available. When it's not available, the 40 * SYSTEMTIME.wMilliseconds will contain a constant arbitrary value. 41 * 42 * Because of that, we need to emulate the milliseconds time resolution 43 * using QueryPerformanceCounter() (via pj_get_timestamp() API). However 44 * there is limitation on using this, i.e. the time returned by 45 * pj_gettimeofday() may be off by up to plus/minus 999 msec (the second 46 * part will be correct, however the msec part may be off), because we're 47 * not synchronizing the msec field with the change of value of the "second" 48 * field of the system time. 49 * 50 * Also there is other caveat which need to be handled (and they are 51 * handled by this implementation): 52 * - user may change system time, so pj_gettimeofday() needs to periodically 53 * checks if system time has changed. The period on which system time is 54 * checked is controlled by PJ_WINCE_TIME_CHECK_INTERVAL macro. 55 */ 56 static LARGE_INTEGER g_start_time; /* Time gettimeofday() is first called */ 57 static pj_timestamp g_start_tick; /* TS gettimeofday() is first called */ 58 static pj_timestamp g_last_update; /* Last time check_system_time() is 59 called, to periodically synchronize 60 with up-to-date system time (in case 61 user changes system time). */ 62 static pj_uint64_t g_update_period; /* Period (in TS) check_system_time() 63 should be called. */ 64 65 /* Period on which check_system_time() is called, in seconds */ 66 #ifndef PJ_WINCE_TIME_CHECK_INTERVAL 67 # define PJ_WINCE_TIME_CHECK_INTERVAL (10) 68 #endif 69 70 #endif 71 72 #ifdef WINCE_TIME 73 static pj_status_t init_start_time(void) 74 { 75 SYSTEMTIME st; 76 FILETIME ft; 77 pj_timestamp freq; 78 pj_status_t status; 79 80 GetLocalTime(&st); 81 SystemTimeToFileTime(&st, &ft); 82 83 g_start_time.LowPart = ft.dwLowDateTime; 84 g_start_time.HighPart = ft.dwHighDateTime; 85 g_start_time.QuadPart /= SECS_TO_FT_MULT; 86 g_start_time.QuadPart -= base_time.QuadPart; 87 88 status = pj_get_timestamp(&g_start_tick); 89 if (status != PJ_SUCCESS) 90 return status; 91 92 g_last_update.u64 = g_start_tick.u64; 93 94 status = pj_get_timestamp_freq(&freq); 95 if (status != PJ_SUCCESS) 96 return status; 97 98 g_update_period = PJ_WINCE_TIME_CHECK_INTERVAL * freq.u64; 99 100 PJ_LOG(4,("os_time_win32.c", "WinCE time (re)started")); 101 102 return PJ_SUCCESS; 103 } 104 105 static pj_status_t check_system_time(pj_uint64_t ts_elapsed) 106 { 107 enum { MIS = 5 }; 108 SYSTEMTIME st; 109 FILETIME ft; 110 LARGE_INTEGER cur, calc; 111 DWORD diff; 112 pj_timestamp freq; 113 pj_status_t status; 114 115 /* Get system's current time */ 116 GetLocalTime(&st); 117 SystemTimeToFileTime(&st, &ft); 118 119 cur.LowPart = ft.dwLowDateTime; 120 cur.HighPart = ft.dwHighDateTime; 121 cur.QuadPart /= SECS_TO_FT_MULT; 122 cur.QuadPart -= base_time.QuadPart; 123 124 /* Get our calculated system time */ 125 status = pj_get_timestamp_freq(&freq); 126 if (status != PJ_SUCCESS) 127 return status; 128 129 calc.QuadPart = g_start_time.QuadPart + ts_elapsed / freq.u64; 130 131 /* See the difference between calculated and actual system time */ 132 if (calc.QuadPart >= cur.QuadPart) { 133 diff = (DWORD)(calc.QuadPart - cur.QuadPart); 134 } else { 135 diff = (DWORD)(cur.QuadPart - calc.QuadPart); 136 } 137 138 if (diff > MIS) { 139 /* System time has changed */ 140 PJ_LOG(3,("os_time_win32.c", "WinCE system time changed detected " 141 "(diff=%u)", diff)); 142 status = init_start_time(); 143 } else { 144 status = PJ_SUCCESS; 145 } 146 147 return status; 148 } 149 150 #endif 151 30 152 // Find 1st Jan 1970 as a FILETIME 31 static void get_base_time(void) 32 { 33 SYSTEMTIME st; 34 FILETIME ft; 153 static pj_status_t get_base_time(void) 154 { 155 SYSTEMTIME st; 156 FILETIME ft; 157 pj_status_t status = PJ_SUCCESS; 35 158 36 159 memset(&st,0,sizeof(st)); … … 43 166 base_time.HighPart = ft.dwHighDateTime; 44 167 base_time.QuadPart /= SECS_TO_FT_MULT; 168 169 #ifdef WINCE_TIME 170 pj_enter_critical_section(); 171 status = init_start_time(); 172 pj_leave_critical_section(); 173 #endif 174 175 return status; 45 176 } 46 177 47 178 PJ_DEF(pj_status_t) pj_gettimeofday(pj_time_val *tv) 48 179 { 180 #ifdef WINCE_TIME 181 pj_timestamp tick; 182 pj_uint64_t msec_elapsed; 183 #else 49 184 SYSTEMTIME st; 50 185 FILETIME ft; 51 186 LARGE_INTEGER li; 52 53 if (base_time.QuadPart == 0) 54 get_base_time(); 55 187 #endif 188 pj_status_t status; 189 190 if (base_time.QuadPart == 0) { 191 status = get_base_time(); 192 if (status != PJ_SUCCESS) 193 return status; 194 } 195 196 #ifdef WINCE_TIME 197 do { 198 status = pj_get_timestamp(&tick); 199 if (status != PJ_SUCCESS) 200 return status; 201 202 if (tick.u64 - g_last_update.u64 >= g_update_period) { 203 pj_enter_critical_section(); 204 if (tick.u64 - g_last_update.u64 >= g_update_period) { 205 g_last_update.u64 = tick.u64; 206 check_system_time(tick.u64 - g_start_tick.u64); 207 } 208 pj_leave_critical_section(); 209 } else { 210 break; 211 } 212 } while (1); 213 214 msec_elapsed = pj_elapsed_msec64(&g_start_tick, &tick); 215 216 tv->sec = (long)(g_start_time.QuadPart + msec_elapsed/1000); 217 tv->msec = (long)(msec_elapsed % 1000); 218 #else 219 /* Standard Win32 GetLocalTime */ 56 220 GetLocalTime(&st); 57 221 SystemTimeToFileTime(&st, &ft); … … 64 228 tv->sec = li.LowPart; 65 229 tv->msec = st.wMilliseconds; 230 #endif /* WINCE_TIME */ 66 231 67 232 return PJ_SUCCESS; -
pjproject/trunk/pjlib/src/pj/os_timestamp_common.c
r2394 r2560 153 153 } 154 154 155 PJ_DEF(pj_uint64_t) pj_elapsed_msec64(const pj_timestamp *start, 156 const pj_timestamp *stop ) 157 { 158 return (pj_uint64_t)elapsed_msec(start, stop); 159 } 160 155 161 PJ_DEF(pj_time_val) pj_elapsed_time( const pj_timestamp *start, 156 162 const pj_timestamp *stop ) -
pjproject/trunk/pjlib/src/pjlib-test/sleep.c
r2394 r2560 56 56 static int simple_sleep_test(void) 57 57 { 58 enum { COUNT = 5};58 enum { COUNT = 10 }; 59 59 int i; 60 60 pj_status_t rc; … … 63 63 64 64 for (i=0; i<COUNT; ++i) { 65 pj_time_val tv; 66 pj_parsed_time pt; 67 65 68 rc = pj_thread_sleep(1000); 66 69 if (rc != PJ_SUCCESS) { … … 68 71 return -10; 69 72 } 70 PJ_LOG(3,(THIS_FILE, "...wake up..")); 73 74 rc = pj_gettimeofday(&tv); 75 if (rc != PJ_SUCCESS) { 76 app_perror("...error: pj_gettimeofday()", rc); 77 return -11; 78 } 79 80 pj_time_decode(&tv, &pt); 81 82 PJ_LOG(3,(THIS_FILE, 83 "...%04d-%02d-%02d %02d:%02d:%02d.%03d", 84 pt.year, pt.mon, pt.day, 85 pt.hour, pt.min, pt.sec, pt.msec)); 86 71 87 } 72 88 … … 76 92 static int sleep_duration_test(void) 77 93 { 78 enum { MIS = 20, DURATION = 1000, DURATION2 = 500 }; 94 enum { MIS = 20}; 95 unsigned duration[] = { 2000, 1000, 500, 200, 100 }; 96 unsigned i; 79 97 pj_status_t rc; 80 98 … … 82 100 83 101 /* Test pj_thread_sleep() and pj_gettimeofday() */ 84 {102 for (i=0; i<PJ_ARRAY_SIZE(duration); ++i) { 85 103 pj_time_val start, stop; 86 104 pj_uint32_t msec; … … 94 112 95 113 /* Sleep */ 96 rc = pj_thread_sleep( DURATION);114 rc = pj_thread_sleep(duration[i]); 97 115 if (rc != PJ_SUCCESS) { 98 116 app_perror("...error: pj_thread_sleep()", rc); … … 110 128 111 129 /* Check if it's within range. */ 112 if (msec < DURATION* (100-MIS)/100 ||113 msec > DURATION* (100+MIS)/100)130 if (msec < duration[i] * (100-MIS)/100 || 131 msec > duration[i] * (100+MIS)/100) 114 132 { 115 133 PJ_LOG(3,(THIS_FILE, 116 134 "...error: slept for %d ms instead of %d ms " 117 135 "(outside %d%% err window)", 118 msec, DURATION, MIS));136 msec, duration[i], MIS)); 119 137 return -30; 120 138 } … … 123 141 124 142 /* Test pj_thread_sleep() and pj_get_timestamp() and friends */ 125 {143 for (i=0; i<PJ_ARRAY_SIZE(duration); ++i) { 126 144 pj_time_val t1, t2; 127 145 pj_timestamp start, stop; … … 141 159 142 160 /* Sleep */ 143 rc = pj_thread_sleep( DURATION2);161 rc = pj_thread_sleep(duration[i]); 144 162 if (rc != PJ_SUCCESS) { 145 163 app_perror("...error: pj_thread_sleep()", rc); … … 163 181 164 182 /* Check if it's within range. */ 165 if (msec < DURATION2* (100-MIS)/100 ||166 msec > DURATION2* (100+MIS)/100)183 if (msec < duration[i] * (100-MIS)/100 || 184 msec > duration[i] * (100+MIS)/100) 167 185 { 168 186 PJ_LOG(3,(THIS_FILE, 169 187 "...error: slept for %d ms instead of %d ms " 170 188 "(outside %d%% err window)", 171 msec, DURATION2, MIS));189 msec, duration[i], MIS)); 172 190 PJ_TIME_VAL_SUB(t2, t1); 173 191 PJ_LOG(3,(THIS_FILE,
Note: See TracChangeset
for help on using the changeset viewer.