| OLD | NEW |
| 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 | 4 |
| 5 #include "vm/globals.h" | 5 #include "vm/globals.h" |
| 6 #if defined(TARGET_OS_MACOS) | 6 #if defined(TARGET_OS_MACOS) |
| 7 | 7 |
| 8 #include "vm/os.h" | 8 #include "vm/os.h" |
| 9 | 9 |
| 10 #include <errno.h> // NOLINT | 10 #include <errno.h> // NOLINT |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 83 // gettimeofday has microsecond resolution. | 83 // gettimeofday has microsecond resolution. |
| 84 struct timeval tv; | 84 struct timeval tv; |
| 85 if (gettimeofday(&tv, NULL) < 0) { | 85 if (gettimeofday(&tv, NULL) < 0) { |
| 86 UNREACHABLE(); | 86 UNREACHABLE(); |
| 87 return 0; | 87 return 0; |
| 88 } | 88 } |
| 89 return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec; | 89 return (static_cast<int64_t>(tv.tv_sec) * 1000000) + tv.tv_usec; |
| 90 } | 90 } |
| 91 | 91 |
| 92 | 92 |
| 93 int64_t OS::GetCurrentMonotonicMicros() { | 93 static mach_timebase_info_data_t timebase_info; |
| 94 |
| 95 |
| 96 int64_t OS::GetCurrentMonotonicTicks() { |
| 94 #if TARGET_OS_IOS | 97 #if TARGET_OS_IOS |
| 95 // On iOS mach_absolute_time stops while the device is sleeping. Instead use | 98 // On iOS mach_absolute_time stops while the device is sleeping. Instead use |
| 96 // now - KERN_BOOTTIME to get a time difference that is not impacted by clock | 99 // now - KERN_BOOTTIME to get a time difference that is not impacted by clock |
| 97 // changes. KERN_BOOTTIME will be updated by the system whenever the system | 100 // changes. KERN_BOOTTIME will be updated by the system whenever the system |
| 98 // clock change. | 101 // clock change. |
| 99 struct timeval boottime; | 102 struct timeval boottime; |
| 100 int mib[2] = {CTL_KERN, KERN_BOOTTIME}; | 103 int mib[2] = {CTL_KERN, KERN_BOOTTIME}; |
| 101 size_t size = sizeof(boottime); | 104 size_t size = sizeof(boottime); |
| 102 int kr = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &boottime, &size, NULL, 0); | 105 int kr = sysctl(mib, sizeof(mib) / sizeof(mib[0]), &boottime, &size, NULL, 0); |
| 103 ASSERT(KERN_SUCCESS == kr); | 106 ASSERT(KERN_SUCCESS == kr); |
| 104 int64_t now = GetCurrentTimeMicros(); | 107 int64_t now = GetCurrentTimeMicros(); |
| 105 int64_t origin = boottime.tv_sec * kMicrosecondsPerSecond; | 108 int64_t origin = boottime.tv_sec * kMicrosecondsPerSecond; |
| 106 origin += boottime.tv_usec; | 109 origin += boottime.tv_usec; |
| 107 return now - origin; | 110 return now - origin; |
| 108 #else | 111 #else |
| 109 static mach_timebase_info_data_t timebase_info; | 112 ASSERT(timebase_info.denom != 0); |
| 110 if (timebase_info.denom == 0) { | 113 // timebase_info converts absolute time tick units into nanoseconds. |
| 111 // Zero-initialization of statics guarantees that denom will be 0 before | 114 int64_t result = mach_absolute_time(); |
| 112 // calling mach_timebase_info. mach_timebase_info will never set denom to | |
| 113 // 0 as that would be invalid, so the zero-check can be used to determine | |
| 114 // whether mach_timebase_info has already been called. This is | |
| 115 // recommended by Apple's QA1398. | |
| 116 kern_return_t kr = mach_timebase_info(&timebase_info); | |
| 117 ASSERT(KERN_SUCCESS == kr); | |
| 118 } | |
| 119 | |
| 120 // timebase_info converts absolute time tick units into nanoseconds. Convert | |
| 121 // to microseconds. | |
| 122 int64_t result = mach_absolute_time() / kNanosecondsPerMicrosecond; | |
| 123 result *= timebase_info.numer; | 115 result *= timebase_info.numer; |
| 124 result /= timebase_info.denom; | 116 result /= timebase_info.denom; |
| 125 return result; | 117 return result; |
| 126 #endif // TARGET_OS_IOS | 118 #endif // TARGET_OS_IOS |
| 127 } | 119 } |
| 128 | 120 |
| 129 | 121 |
| 122 int64_t OS::GetCurrentMonotonicFrequency() { |
| 123 #if TARGET_OS_IOS |
| 124 return kMicrosecondsPerSecond; |
| 125 #else |
| 126 return kNanosecondsPerSecond; |
| 127 #endif // TARGET_OS_IOS |
| 128 } |
| 129 |
| 130 |
| 131 int64_t OS::GetCurrentMonotonicMicros() { |
| 132 #if TARGET_OS_IOS |
| 133 ASSERT(GetCurrentMonotonicFrequency() == kMicrosecondsPerSecond); |
| 134 return GetCurrentMonotonicTicks(); |
| 135 #else |
| 136 ASSERT(GetCurrentMonotonicFrequency() == kNanosecondsPerSecond); |
| 137 return GetCurrentMonotonicTicks() / kNanosecondsPerMicrosecond; |
| 138 #endif // TARGET_OS_IOS |
| 139 } |
| 140 |
| 141 |
| 130 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) { | 142 void* OS::AlignedAllocate(intptr_t size, intptr_t alignment) { |
| 131 const int kMinimumAlignment = 16; | 143 const int kMinimumAlignment = 16; |
| 132 ASSERT(Utils::IsPowerOfTwo(alignment)); | 144 ASSERT(Utils::IsPowerOfTwo(alignment)); |
| 133 ASSERT(alignment >= kMinimumAlignment); | 145 ASSERT(alignment >= kMinimumAlignment); |
| 134 // Temporary workaround until xcode is upgraded. | 146 // Temporary workaround until xcode is upgraded. |
| 135 // Mac guarantees malloc returns a 16 byte aligned memory chunk. | 147 // Mac guarantees malloc returns a 16 byte aligned memory chunk. |
| 136 // Currently we only allocate with 16-bye alignment. | 148 // Currently we only allocate with 16-bye alignment. |
| 137 ASSERT(alignment == 16); | 149 ASSERT(alignment == 16); |
| 138 // TODO(johnmccutchan): Remove hack and switch to posix_memalign. | 150 // TODO(johnmccutchan): Remove hack and switch to posix_memalign. |
| 139 return malloc(size); | 151 return malloc(size); |
| (...skipping 214 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 354 } | 366 } |
| 355 | 367 |
| 356 | 368 |
| 357 void OS::InitOnce() { | 369 void OS::InitOnce() { |
| 358 // TODO(5411554): For now we check that initonce is called only once, | 370 // TODO(5411554): For now we check that initonce is called only once, |
| 359 // Once there is more formal mechanism to call InitOnce we can move | 371 // Once there is more formal mechanism to call InitOnce we can move |
| 360 // this check there. | 372 // this check there. |
| 361 static bool init_once_called = false; | 373 static bool init_once_called = false; |
| 362 ASSERT(init_once_called == false); | 374 ASSERT(init_once_called == false); |
| 363 init_once_called = true; | 375 init_once_called = true; |
| 376 kern_return_t kr = mach_timebase_info(&timebase_info); |
| 377 ASSERT(KERN_SUCCESS == kr); |
| 364 } | 378 } |
| 365 | 379 |
| 366 | 380 |
| 367 void OS::Shutdown() { | 381 void OS::Shutdown() { |
| 368 } | 382 } |
| 369 | 383 |
| 370 | 384 |
| 371 void OS::Abort() { | 385 void OS::Abort() { |
| 372 abort(); | 386 abort(); |
| 373 } | 387 } |
| 374 | 388 |
| 375 | 389 |
| 376 void OS::Exit(int code) { | 390 void OS::Exit(int code) { |
| 377 exit(code); | 391 exit(code); |
| 378 } | 392 } |
| 379 | 393 |
| 380 } // namespace dart | 394 } // namespace dart |
| 381 | 395 |
| 382 #endif // defined(TARGET_OS_MACOS) | 396 #endif // defined(TARGET_OS_MACOS) |
| OLD | NEW |