OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
233 | 233 |
234 // ---------------------------------------------------------------------------- | 234 // ---------------------------------------------------------------------------- |
235 // The Time class represents time on win32. A timestamp is represented as | 235 // The Time class represents time on win32. A timestamp is represented as |
236 // a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript | 236 // a 64-bit integer in 100 nanoseconds since January 1, 1601 (UTC). JavaScript |
237 // timestamps are represented as a doubles in milliseconds since 00:00:00 UTC, | 237 // timestamps are represented as a doubles in milliseconds since 00:00:00 UTC, |
238 // January 1, 1970. | 238 // January 1, 1970. |
239 | 239 |
240 class Win32Time { | 240 class Win32Time { |
241 public: | 241 public: |
242 // Constructors. | 242 // Constructors. |
| 243 Win32Time(); |
243 explicit Win32Time(double jstime); | 244 explicit Win32Time(double jstime); |
244 Win32Time(int year, int mon, int day, int hour, int min, int sec); | 245 Win32Time(int year, int mon, int day, int hour, int min, int sec); |
245 | 246 |
246 // Convert timestamp to JavaScript representation. | 247 // Convert timestamp to JavaScript representation. |
247 double ToJSTime(); | 248 double ToJSTime(); |
248 | 249 |
| 250 // Set timestamp to current time. |
| 251 void SetToCurrentTime(); |
| 252 |
249 // Returns the local timezone offset in milliseconds east of UTC. This is | 253 // Returns the local timezone offset in milliseconds east of UTC. This is |
250 // the number of milliseconds you must add to UTC to get local time, i.e. | 254 // the number of milliseconds you must add to UTC to get local time, i.e. |
251 // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This | 255 // LocalOffset(CET) = 3600000 and LocalOffset(PST) = -28800000. This |
252 // routine also takes into account whether daylight saving is effect | 256 // routine also takes into account whether daylight saving is effect |
253 // at the time. | 257 // at the time. |
254 int64_t LocalOffset(); | 258 int64_t LocalOffset(); |
255 | 259 |
256 // Returns the daylight savings time offset for the time in milliseconds. | 260 // Returns the daylight savings time offset for the time in milliseconds. |
257 int64_t DaylightSavingsOffset(); | 261 int64_t DaylightSavingsOffset(); |
258 | 262 |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
307 }; | 311 }; |
308 | 312 |
309 | 313 |
310 // Static variables. | 314 // Static variables. |
311 bool Win32Time::tz_initialized_ = false; | 315 bool Win32Time::tz_initialized_ = false; |
312 TIME_ZONE_INFORMATION Win32Time::tzinfo_; | 316 TIME_ZONE_INFORMATION Win32Time::tzinfo_; |
313 char Win32Time::std_tz_name_[kTzNameSize]; | 317 char Win32Time::std_tz_name_[kTzNameSize]; |
314 char Win32Time::dst_tz_name_[kTzNameSize]; | 318 char Win32Time::dst_tz_name_[kTzNameSize]; |
315 | 319 |
316 | 320 |
| 321 // Initialize timestamp to start of epoc. |
| 322 Win32Time::Win32Time() { |
| 323 t() = 0; |
| 324 } |
| 325 |
| 326 |
317 // Initialize timestamp from a JavaScript timestamp. | 327 // Initialize timestamp from a JavaScript timestamp. |
318 Win32Time::Win32Time(double jstime) { | 328 Win32Time::Win32Time(double jstime) { |
319 t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc; | 329 t() = static_cast<int64_t>(jstime) * kTimeScaler + kTimeEpoc; |
320 } | 330 } |
321 | 331 |
322 | 332 |
323 // Initialize timestamp from date/time components. | 333 // Initialize timestamp from date/time components. |
324 Win32Time::Win32Time(int year, int mon, int day, int hour, int min, int sec) { | 334 Win32Time::Win32Time(int year, int mon, int day, int hour, int min, int sec) { |
325 SYSTEMTIME st; | 335 SYSTEMTIME st; |
326 st.wYear = year; | 336 st.wYear = year; |
327 st.wMonth = mon; | 337 st.wMonth = mon; |
328 st.wDay = day; | 338 st.wDay = day; |
329 st.wHour = hour; | 339 st.wHour = hour; |
330 st.wMinute = min; | 340 st.wMinute = min; |
331 st.wSecond = sec; | 341 st.wSecond = sec; |
332 st.wMilliseconds = 0; | 342 st.wMilliseconds = 0; |
333 SystemTimeToFileTime(&st, &ft()); | 343 SystemTimeToFileTime(&st, &ft()); |
334 } | 344 } |
335 | 345 |
336 | 346 |
337 // Convert timestamp to JavaScript timestamp. | 347 // Convert timestamp to JavaScript timestamp. |
338 double Win32Time::ToJSTime() { | 348 double Win32Time::ToJSTime() { |
339 return static_cast<double>((t() - kTimeEpoc) / kTimeScaler); | 349 return static_cast<double>((t() - kTimeEpoc) / kTimeScaler); |
340 } | 350 } |
341 | 351 |
342 | 352 |
| 353 // Set timestamp to current time. |
| 354 void Win32Time::SetToCurrentTime() { |
| 355 // The default GetSystemTimeAsFileTime has a ~15.5ms resolution. |
| 356 // Because we're fast, we like fast timers which have at least a |
| 357 // 1ms resolution. |
| 358 // |
| 359 // timeGetTime() provides 1ms granularity when combined with |
| 360 // timeBeginPeriod(). If the host application for v8 wants fast |
| 361 // timers, it can use timeBeginPeriod to increase the resolution. |
| 362 // |
| 363 // Using timeGetTime() has a drawback because it is a 32bit value |
| 364 // and hence rolls-over every ~49days. |
| 365 // |
| 366 // To use the clock, we use GetSystemTimeAsFileTime as our base; |
| 367 // and then use timeGetTime to extrapolate current time from the |
| 368 // start time. To deal with rollovers, we resync the clock |
| 369 // any time when more than kMaxClockElapsedTime has passed or |
| 370 // whenever timeGetTime creates a rollover. |
| 371 |
| 372 static bool initialized = false; |
| 373 static TimeStamp init_time; |
| 374 static DWORD init_ticks; |
| 375 static const int64_t kHundredNanosecondsPerSecond = 10000000; |
| 376 static const int64_t kMaxClockElapsedTime = |
| 377 60*kHundredNanosecondsPerSecond; // 1 minute |
| 378 |
| 379 // If we are uninitialized, we need to resync the clock. |
| 380 bool needs_resync = !initialized; |
| 381 |
| 382 // Get the current time. |
| 383 TimeStamp time_now; |
| 384 GetSystemTimeAsFileTime(&time_now.ft_); |
| 385 DWORD ticks_now = timeGetTime(); |
| 386 |
| 387 // Check if we need to resync due to clock rollover. |
| 388 needs_resync |= ticks_now < init_ticks; |
| 389 |
| 390 // Check if we need to resync due to elapsed time. |
| 391 needs_resync |= (time_now.t_ - init_time.t_) > kMaxClockElapsedTime; |
| 392 |
| 393 // Check if we need to resync due to backwards time change. |
| 394 needs_resync |= time_now.t_ < init_time.t_; |
| 395 |
| 396 // Resync the clock if necessary. |
| 397 if (needs_resync) { |
| 398 GetSystemTimeAsFileTime(&init_time.ft_); |
| 399 init_ticks = ticks_now = timeGetTime(); |
| 400 initialized = true; |
| 401 } |
| 402 |
| 403 // Finally, compute the actual time. Why is this so hard. |
| 404 DWORD elapsed = ticks_now - init_ticks; |
| 405 this->time_.t_ = init_time.t_ + (static_cast<int64_t>(elapsed) * 10000); |
| 406 } |
| 407 |
| 408 |
343 // Guess the name of the timezone from the bias. | 409 // Guess the name of the timezone from the bias. |
344 // The guess is very biased towards the northern hemisphere. | 410 // The guess is very biased towards the northern hemisphere. |
345 const char* Win32Time::GuessTimezoneNameFromBias(int bias) { | 411 const char* Win32Time::GuessTimezoneNameFromBias(int bias) { |
346 static const int kHour = 60; | 412 static const int kHour = 60; |
347 switch (-bias) { | 413 switch (-bias) { |
348 case -9*kHour: return "Alaska"; | 414 case -9*kHour: return "Alaska"; |
349 case -8*kHour: return "Pacific"; | 415 case -8*kHour: return "Pacific"; |
350 case -7*kHour: return "Mountain"; | 416 case -7*kHour: return "Mountain"; |
351 case -6*kHour: return "Central"; | 417 case -6*kHour: return "Central"; |
352 case -5*kHour: return "Eastern"; | 418 case -5*kHour: return "Eastern"; |
(...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
522 // Convert to seconds and microseconds | 588 // Convert to seconds and microseconds |
523 *secs = static_cast<uint32_t>(usertime / 1000000); | 589 *secs = static_cast<uint32_t>(usertime / 1000000); |
524 *usecs = static_cast<uint32_t>(usertime % 1000000); | 590 *usecs = static_cast<uint32_t>(usertime % 1000000); |
525 return 0; | 591 return 0; |
526 } | 592 } |
527 | 593 |
528 | 594 |
529 // Returns current time as the number of milliseconds since | 595 // Returns current time as the number of milliseconds since |
530 // 00:00:00 UTC, January 1, 1970. | 596 // 00:00:00 UTC, January 1, 1970. |
531 double OS::TimeCurrentMillis() { | 597 double OS::TimeCurrentMillis() { |
532 return Time::Now().ToJsTime(); | 598 Win32Time t; |
| 599 t.SetToCurrentTime(); |
| 600 return t.ToJSTime(); |
533 } | 601 } |
534 | 602 |
535 | 603 |
536 // Returns a string identifying the current timezone taking into | 604 // Returns a string identifying the current timezone taking into |
537 // account daylight saving. | 605 // account daylight saving. |
538 const char* OS::LocalTimezone(double time) { | 606 const char* OS::LocalTimezone(double time) { |
539 return Win32Time(time).LocalTimezone(); | 607 return Win32Time(time).LocalTimezone(); |
540 } | 608 } |
541 | 609 |
542 | 610 |
(...skipping 897 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1440 ASSERT(result); | 1508 ASSERT(result); |
1441 } | 1509 } |
1442 | 1510 |
1443 | 1511 |
1444 | 1512 |
1445 void Thread::YieldCPU() { | 1513 void Thread::YieldCPU() { |
1446 Sleep(0); | 1514 Sleep(0); |
1447 } | 1515 } |
1448 | 1516 |
1449 } } // namespace v8::internal | 1517 } } // namespace v8::internal |
OLD | NEW |