1 /*
2  * Copyright (C) 2012 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <cutils/trace.h>
18 
19 #include "trace-dev.inc"
20 
21 static pthread_once_t atrace_once_control = PTHREAD_ONCE_INIT;
22 
23 // Set whether tracing is enabled in this process.  This is used to prevent
24 // the Zygote process from tracing.
atrace_set_tracing_enabled(bool enabled)25 void atrace_set_tracing_enabled(bool enabled)
26 {
27     atomic_store_explicit(&atrace_is_enabled, enabled, memory_order_release);
28     atrace_update_tags();
29 }
30 
atrace_init_once()31 static void atrace_init_once()
32 {
33     atrace_marker_fd = open("/sys/kernel/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
34     if (atrace_marker_fd == -1) {
35         atrace_marker_fd = open("/sys/kernel/debug/tracing/trace_marker", O_WRONLY | O_CLOEXEC);
36     }
37 
38     if (atrace_marker_fd == -1) {
39         ALOGE("Error opening trace file: %s (%d)", strerror(errno), errno);
40         atrace_enabled_tags = 0;
41     } else {
42       atrace_enabled_tags = atrace_get_property();
43     }
44 }
45 
atrace_seq_number_changed(uint32_t prev_seq_no,uint32_t seq_no)46 static void atrace_seq_number_changed(uint32_t prev_seq_no, uint32_t seq_no) {
47     if (!atomic_load_explicit(&atrace_is_enabled, memory_order_acquire)) {
48         return;
49     }
50 
51     // Someone raced us.
52     if (!atomic_compare_exchange_strong(&last_sequence_number, &prev_seq_no, seq_no)) {
53         return;
54     }
55 
56     if (CC_UNLIKELY(prev_seq_no == kSeqNoNotInit)) {
57 #if defined(__BIONIC__)
58         const prop_info* new_pi = __system_property_find("debug.atrace.tags.enableflags");
59         if (new_pi) atrace_property_info = new_pi;
60 #endif
61         pthread_once(&atrace_once_control, atrace_init_once);
62     }
63 
64     atrace_update_tags();
65 }
66 
atrace_setup()67 void atrace_setup()
68 {
69     atrace_init();
70 }
71 
atrace_begin_body(const char * name)72 void atrace_begin_body(const char* name)
73 {
74     WRITE_MSG("B|%d|", "%s", name, "");
75 }
76 
atrace_end_body()77 void atrace_end_body()
78 {
79     WRITE_MSG("E|%d", "%s", "", "");
80 }
81 
atrace_async_begin_body(const char * name,int32_t cookie)82 void atrace_async_begin_body(const char* name, int32_t cookie)
83 {
84     WRITE_MSG("S|%d|", "|%" PRId32, name, cookie);
85 }
86 
atrace_async_end_body(const char * name,int32_t cookie)87 void atrace_async_end_body(const char* name, int32_t cookie)
88 {
89     WRITE_MSG("F|%d|", "|%" PRId32, name, cookie);
90 }
91 
atrace_int_body(const char * name,int32_t value)92 void atrace_int_body(const char* name, int32_t value)
93 {
94     WRITE_MSG("C|%d|", "|%" PRId32, name, value);
95 }
96 
atrace_int64_body(const char * name,int64_t value)97 void atrace_int64_body(const char* name, int64_t value)
98 {
99     WRITE_MSG("C|%d|", "|%" PRId64, name, value);
100 }
101