1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ppapi/shared_impl/ppb_trace_event_impl.h"
6
7#include "base/basictypes.h"
8#include "base/debug/trace_event.h"
9#include "base/threading/platform_thread.h"
10#include "ppapi/thunk/thunk.h"
11
12namespace ppapi {
13
14// PPB_Trace_Event_Dev is a shared implementation because Trace Events can be
15// sent from either the plugin process or renderer process depending on whether
16// the plugin is in- or out-of-process.  Also, for NaCl plugins these functions
17// will be executed from untrusted code and handled appropriately by tracing
18// functionality in the IRT.
19
20// static
21void* TraceEventImpl::GetCategoryEnabled(const char* category_name) {
22  // This casting is here because all mem_t return types in Pepper are void* and
23  // non-const.  All mem_t parameters are const void* so there is no way to
24  // return a pointer type to the caller without some const_cast.  The pointer
25  // type the tracing system works with is normally unsigned char*.
26  return const_cast<void*>(static_cast<const void*>(
27      base::debug::TraceLog::GetInstance()->GetCategoryGroupEnabled(
28          category_name)));
29}
30
31// static
32void TraceEventImpl::AddTraceEvent(int8_t phase,
33                                   const void* category_enabled,
34                                   const char* name,
35                                   uint64_t id,
36                                   uint32_t num_args,
37                                   const char* arg_names[],
38                                   const uint8_t arg_types[],
39                                   const uint64_t arg_values[],
40                                   uint8_t flags) {
41
42  COMPILE_ASSERT(sizeof(unsigned long long) == sizeof(uint64_t), msg);
43
44  base::debug::TraceLog::GetInstance()->AddTraceEvent(
45      phase,
46      static_cast<const unsigned char*>(category_enabled),
47      name,
48      id,
49      num_args,
50      arg_names,
51      arg_types,
52      // This cast is necessary for LP64 systems, where uint64_t is defined as
53      // an unsigned long int, but trace_event internals are hermetic and
54      // accepts an |unsigned long long*|.  The pointer types are compatible but
55      // the compiler throws an error without an explicit cast.
56      reinterpret_cast<const unsigned long long*>(arg_values),
57      NULL,
58      flags);
59}
60
61// static
62void TraceEventImpl::AddTraceEventWithThreadIdAndTimestamp(
63    int8_t phase,
64    const void* category_enabled,
65    const char* name,
66    uint64_t id,
67    int32_t thread_id,
68    int64_t timestamp,
69    uint32_t num_args,
70    const char* arg_names[],
71    const uint8_t arg_types[],
72    const uint64_t arg_values[],
73    uint8_t flags) {
74  base::debug::TraceLog::GetInstance()->AddTraceEventWithThreadIdAndTimestamp(
75      phase,
76      static_cast<const unsigned char*>(category_enabled),
77      name,
78      id,
79      thread_id,
80      base::TimeTicks::FromInternalValue(timestamp),
81      num_args,
82      arg_names,
83      arg_types,
84      // This cast is necessary for LP64 systems, where uint64_t is defined as
85      // an unsigned long int, but trace_event internals are hermetic and
86      // accepts an |unsigned long long*|.  The pointer types are compatible but
87      // the compiler throws an error without an explicit cast.
88      reinterpret_cast<const unsigned long long*>(arg_values),
89      NULL,
90      flags);
91}
92
93// static
94int64_t TraceEventImpl::Now() {
95  return base::TimeTicks::NowFromSystemTraceTime().ToInternalValue();
96}
97
98// static
99void TraceEventImpl::SetThreadName(const char* thread_name) {
100  base::PlatformThread::SetName(thread_name);
101}
102
103namespace {
104
105const PPB_Trace_Event_Dev_0_1 g_ppb_trace_event_thunk_0_1 = {
106    &TraceEventImpl::GetCategoryEnabled, &TraceEventImpl::AddTraceEvent,
107    &TraceEventImpl::SetThreadName, };
108
109const PPB_Trace_Event_Dev_0_2 g_ppb_trace_event_thunk_0_2 = {
110    &TraceEventImpl::GetCategoryEnabled,
111    &TraceEventImpl::AddTraceEvent,
112    &TraceEventImpl::AddTraceEventWithThreadIdAndTimestamp,
113    &TraceEventImpl::Now,
114    &TraceEventImpl::SetThreadName, };
115
116}  // namespace ppapi
117
118}  // namespace
119
120namespace ppapi {
121namespace thunk {
122
123const PPB_Trace_Event_Dev_0_1* GetPPB_Trace_Event_Dev_0_1_Thunk() {
124  return &g_ppb_trace_event_thunk_0_1;
125}
126
127const PPB_Trace_Event_Dev_0_2* GetPPB_Trace_Event_Dev_0_2_Thunk() {
128  return &g_ppb_trace_event_thunk_0_2;
129}
130
131}  // namespace thunk
132}  // namespace ppapi
133