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
3// BSD-style license that can be found in the LICENSE file.
4
5#include "platform/globals.h"
6#if defined(HOST_OS_MACOS)
7
8#include <errno.h> // NOLINT
9#include <mach/clock.h> // NOLINT
10#include <mach/mach.h> // NOLINT
11#include <mach/mach_time.h> // NOLINT
12#include <netdb.h> // NOLINT
13#include <sys/time.h> // NOLINT
14#include <time.h> // NOLINT
15
16#include "bin/utils.h"
17#include "platform/assert.h"
18#include "platform/utils.h"
19
20namespace dart {
21namespace bin {
22
23OSError::OSError() : sub_system_(kSystem), code_(0), message_(NULL) {
24 Reload();
25}
26
27void OSError::Reload() {
28 SetCodeAndMessage(kSystem, errno);
29}
30
31void OSError::SetCodeAndMessage(SubSystem sub_system, int code) {
32 set_sub_system(sub_system);
33 set_code(code);
34 if (sub_system == kSystem) {
35 const int kBufferSize = 1024;
36 char error_message[kBufferSize];
37 Utils::StrError(code, error_message, kBufferSize);
38 SetMessage(error_message);
39 } else if (sub_system == kGetAddressInfo) {
40 SetMessage(gai_strerror(code));
41 } else {
42 UNREACHABLE();
43 }
44}
45
46const char* StringUtils::ConsoleStringToUtf8(const char* str,
47 intptr_t len,
48 intptr_t* result_len) {
49 UNIMPLEMENTED();
50 return NULL;
51}
52
53const char* StringUtils::Utf8ToConsoleString(const char* utf8,
54 intptr_t len,
55 intptr_t* result_len) {
56 UNIMPLEMENTED();
57 return NULL;
58}
59
60char* StringUtils::ConsoleStringToUtf8(char* str,
61 intptr_t len,
62 intptr_t* result_len) {
63 UNIMPLEMENTED();
64 return NULL;
65}
66
67char* StringUtils::Utf8ToConsoleString(char* utf8,
68 intptr_t len,
69 intptr_t* result_len) {
70 UNIMPLEMENTED();
71 return NULL;
72}
73
74bool ShellUtils::GetUtf8Argv(int argc, char** argv) {
75 return false;
76}
77
78static mach_timebase_info_data_t timebase_info;
79
80void TimerUtils::InitOnce() {
81 kern_return_t kr = mach_timebase_info(&timebase_info);
82 ASSERT(KERN_SUCCESS == kr);
83}
84
85int64_t TimerUtils::GetCurrentMonotonicMillis() {
86 return GetCurrentMonotonicMicros() / 1000;
87}
88
89int64_t TimerUtils::GetCurrentMonotonicMicros() {
90 ASSERT(timebase_info.denom != 0);
91 // timebase_info converts absolute time tick units into nanoseconds. Convert
92 // to microseconds.
93 int64_t result = mach_absolute_time() / kNanosecondsPerMicrosecond;
94 result *= timebase_info.numer;
95 result /= timebase_info.denom;
96 return result;
97}
98
99void TimerUtils::Sleep(int64_t millis) {
100 struct timespec req; // requested.
101 struct timespec rem; // remainder.
102 int64_t micros = millis * kMicrosecondsPerMillisecond;
103 int64_t seconds = micros / kMicrosecondsPerSecond;
104 micros = micros - seconds * kMicrosecondsPerSecond;
105 int64_t nanos = micros * kNanosecondsPerMicrosecond;
106 req.tv_sec = seconds;
107 req.tv_nsec = nanos;
108 while (true) {
109 int r = nanosleep(&req, &rem);
110 if (r == 0) {
111 break;
112 }
113 // We should only ever see an interrupt error.
114 ASSERT(errno == EINTR);
115 // Copy remainder into requested and repeat.
116 req = rem;
117 }
118}
119
120} // namespace bin
121} // namespace dart
122
123#endif // defined(HOST_OS_MACOS)
124