1 /*
2  * Copyright 2011 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 #include "SysTimer_mach.h"
8 
mac_cpu_time()9 static time_value_t mac_cpu_time() {
10     mach_port_t task = mach_task_self();
11     if (task == MACH_PORT_NULL) {
12         time_value_t none = {0, 0};
13         return none;
14     }
15 
16     task_thread_times_info thread_info_data;
17     mach_msg_type_number_t thread_info_count = TASK_THREAD_TIMES_INFO_COUNT;
18     if (KERN_SUCCESS != task_info(task,
19                                   TASK_THREAD_TIMES_INFO,
20                                   reinterpret_cast<task_info_t>(&thread_info_data),
21                                   &thread_info_count)) {
22         time_value_t none = {0, 0};
23         return none;
24     }
25 
26     time_value_add(&thread_info_data.user_time, &thread_info_data.system_time)
27     return thread_info_data.user_time;
28 }
29 
interval_in_ms(time_value_t start_clock,time_value_t end_clock)30 static double interval_in_ms(time_value_t start_clock, time_value_t end_clock) {
31     double duration_clock;
32     if ((end_clock.microseconds - start_clock.microseconds) < 0) {
33         duration_clock = (end_clock.seconds - start_clock.seconds-1) * 1000;
34         duration_clock += (1000000 + end_clock.microseconds - start_clock.microseconds) / 1000.0;
35     } else {
36         duration_clock = (end_clock.seconds - start_clock.seconds) * 1000;
37         duration_clock += (end_clock.microseconds - start_clock.microseconds) / 1000.0;
38     }
39     return duration_clock;
40 }
41 
startWall()42 void SysTimer::startWall() {
43     fStartWall = mach_absolute_time();
44 }
45 
startCpu()46 void SysTimer::startCpu() {
47     fStartCpu = mac_cpu_time();
48 }
49 
endCpu()50 double SysTimer::endCpu() {
51     time_value_t end_cpu = mac_cpu_time();
52     return interval_in_ms(fStartCpu, end_cpu);
53 }
54 
endWall()55 double SysTimer::endWall() {
56     uint64_t end_wall = mach_absolute_time();
57 
58     uint64_t elapsed = end_wall - fStartWall;
59     mach_timebase_info_data_t sTimebaseInfo;
60     if (KERN_SUCCESS != mach_timebase_info(&sTimebaseInfo)) {
61         return 0;
62     } else {
63         uint64_t elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
64         return elapsedNano / 1000000.0;
65     }
66 }
67