• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3  *
4  *  Use of this source code is governed by a BSD-style license
5  *  that can be found in the LICENSE file in the root of the source
6  *  tree. An additional intellectual property rights grant can be found
7  *  in the file PATENTS.  All contributing project authors may
8  *  be found in the AUTHORS file in the root of the source tree.
9  */
10 
11 #include "rtc_base/cpu_time.h"
12 
13 #include "rtc_base/logging.h"
14 #include "rtc_base/time_utils.h"
15 
16 #if defined(WEBRTC_LINUX)
17 #include <time.h>
18 #elif defined(WEBRTC_MAC)
19 #include <mach/mach_init.h>
20 #include <mach/mach_port.h>
21 #include <mach/thread_act.h>
22 #include <mach/thread_info.h>
23 #include <sys/resource.h>
24 #include <sys/times.h>
25 #include <sys/types.h>
26 #include <unistd.h>
27 #elif defined(WEBRTC_WIN)
28 #include <windows.h>
29 #endif
30 
31 #if defined(WEBRTC_WIN)
32 namespace {
33 // FILETIME resolution is 100 nanosecs.
34 const int64_t kNanosecsPerFiletime = 100;
35 }  // namespace
36 #endif
37 
38 namespace rtc {
39 
GetProcessCpuTimeNanos()40 int64_t GetProcessCpuTimeNanos() {
41 #if defined(WEBRTC_LINUX)
42   struct timespec ts;
43   if (clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts) == 0) {
44     return ts.tv_sec * kNumNanosecsPerSec + ts.tv_nsec;
45   } else {
46     RTC_LOG_ERR(LS_ERROR) << "clock_gettime() failed.";
47   }
48 #elif defined(WEBRTC_MAC)
49   struct rusage rusage;
50   if (getrusage(RUSAGE_SELF, &rusage) == 0) {
51     return rusage.ru_utime.tv_sec * kNumNanosecsPerSec +
52            rusage.ru_utime.tv_usec * kNumNanosecsPerMicrosec;
53   } else {
54     RTC_LOG_ERR(LS_ERROR) << "getrusage() failed.";
55   }
56 #elif defined(WEBRTC_WIN)
57   FILETIME createTime;
58   FILETIME exitTime;
59   FILETIME kernelTime;
60   FILETIME userTime;
61   if (GetProcessTimes(GetCurrentProcess(), &createTime, &exitTime, &kernelTime,
62                       &userTime) != 0) {
63     return ((static_cast<uint64_t>(userTime.dwHighDateTime) << 32) +
64             userTime.dwLowDateTime) *
65            kNanosecsPerFiletime;
66   } else {
67     RTC_LOG_ERR(LS_ERROR) << "GetProcessTimes() failed.";
68   }
69 #elif defined(WEBRTC_FUCHSIA)
70   RTC_LOG_ERR(LS_ERROR) << "GetProcessCpuTimeNanos() not implemented";
71   return 0;
72 #else
73   // Not implemented yet.
74   static_assert(
75       false, "GetProcessCpuTimeNanos() platform support not yet implemented.");
76 #endif
77   return -1;
78 }
79 
GetThreadCpuTimeNanos()80 int64_t GetThreadCpuTimeNanos() {
81 #if defined(WEBRTC_LINUX)
82   struct timespec ts;
83   if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &ts) == 0) {
84     return ts.tv_sec * kNumNanosecsPerSec + ts.tv_nsec;
85   } else {
86     RTC_LOG_ERR(LS_ERROR) << "clock_gettime() failed.";
87   }
88 #elif defined(WEBRTC_MAC)
89   mach_port_t thread_port = mach_thread_self();
90   thread_basic_info_data_t info;
91   mach_msg_type_number_t count = THREAD_BASIC_INFO_COUNT;
92   kern_return_t kr =
93       thread_info(thread_port, THREAD_BASIC_INFO, (thread_info_t)&info, &count);
94   mach_port_deallocate(mach_task_self(), thread_port);
95   if (kr == KERN_SUCCESS) {
96     return info.user_time.seconds * kNumNanosecsPerSec +
97            info.user_time.microseconds * kNumNanosecsPerMicrosec;
98   } else {
99     RTC_LOG_ERR(LS_ERROR) << "thread_info() failed.";
100   }
101 #elif defined(WEBRTC_WIN)
102   FILETIME createTime;
103   FILETIME exitTime;
104   FILETIME kernelTime;
105   FILETIME userTime;
106   if (GetThreadTimes(GetCurrentThread(), &createTime, &exitTime, &kernelTime,
107                      &userTime) != 0) {
108     return ((static_cast<uint64_t>(userTime.dwHighDateTime) << 32) +
109             userTime.dwLowDateTime) *
110            kNanosecsPerFiletime;
111   } else {
112     RTC_LOG_ERR(LS_ERROR) << "GetThreadTimes() failed.";
113   }
114 #elif defined(WEBRTC_FUCHSIA)
115   RTC_LOG_ERR(LS_ERROR) << "GetThreadCpuTimeNanos() not implemented";
116   return 0;
117 #else
118   // Not implemented yet.
119   static_assert(
120       false, "GetThreadCpuTimeNanos() platform support not yet implemented.");
121 #endif
122   return -1;
123 }
124 
125 }  // namespace rtc
126