10a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/*
20a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Copyright (C) 2012 The Android Open Source Project
30a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
40a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Licensed under the Apache License, Version 2.0 (the "License");
50a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * you may not use this file except in compliance with the License.
60a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * You may obtain a copy of the License at
70a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
80a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *      http://www.apache.org/licenses/LICENSE-2.0
90a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
100a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Unless required by applicable law or agreed to in writing, software
110a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * distributed under the License is distributed on an "AS IS" BASIS,
120a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * See the License for the specific language governing permissions and
140a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * limitations under the License.
150a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
160a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
170a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#ifndef _LIBS_CUTILS_TRACE_H
180a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define _LIBS_CUTILS_TRACE_H
190a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
200a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#include <sys/cdefs.h>
210a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#include <sys/types.h>
220a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#include <stdint.h>
23774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis#include <stdbool.h>
240a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#include <unistd.h>
250a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#include <cutils/compiler.h>
260a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
27448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray#ifdef ANDROID_SMP
28448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray#include <cutils/atomic-inline.h>
29448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray#else
30448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray#include <cutils/atomic.h>
31448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray#endif
32448f76a1c4eb78661b5ac68013e8a2348c92df63Alex Ray
330a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray__BEGIN_DECLS
340a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
350a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
360a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * The ATRACE_TAG macro can be defined before including this header to trace
370a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * using one of the tags defined below.  It must be defined to one of the
380a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * following ATRACE_TAG_* macros.  The trace tag is used to filter tracing in
390a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * userland to avoid some of the runtime cost of tracing when it is not desired.
400a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
410a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Defining ATRACE_TAG to be ATRACE_TAG_ALWAYS will result in the tracing always
420a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * being enabled - this should ONLY be done for debug code, as userland tracing
430a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * has a performance cost even when the trace is not being recorded.  Defining
440a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * ATRACE_TAG to be ATRACE_TAG_NEVER or leaving ATRACE_TAG undefined will result
450a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * in the tracing always being disabled.
460a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
470a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * ATRACE_TAG_HAL should be bitwise ORed with the relevant tags for tracing
480a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * within a hardware module.  For example a camera hardware module would set:
490a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * #define ATRACE_TAG  (ATRACE_TAG_CAMERA | ATRACE_TAG_HAL)
500a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray *
510a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Keep these in sync with frameworks/base/core/java/android/os/Trace.java.
520a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
530a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_NEVER            0       // This tag is never enabled.
540a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_ALWAYS           (1<<0)  // This tag is always enabled.
550a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_GRAPHICS         (1<<1)
560a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_INPUT            (1<<2)
570a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_VIEW             (1<<3)
580a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_WEBVIEW          (1<<4)
590a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_WINDOW_MANAGER   (1<<5)
600a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_ACTIVITY_MANAGER (1<<6)
610a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_SYNC_MANAGER     (1<<7)
620a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_AUDIO            (1<<8)
630a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_VIDEO            (1<<9)
640a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_CAMERA           (1<<10)
650a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_HAL              (1<<11)
66774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis#define ATRACE_TAG_APP              (1<<12)
6724bc41b78ca004ac7a6873054ff919da1ba9a6f8Dianne Hackborn#define ATRACE_TAG_RESOURCES        (1<<13)
682b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_TAG_DALVIK           (1<<14)
692b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_TAG_LAST             ATRACE_TAG_DALVIK
700a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
710a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray// Reserved for initialization.
720a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_NOT_READY        (1LL<<63)
730a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
740a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG_VALID_MASK ((ATRACE_TAG_LAST - 1) | ATRACE_TAG_LAST)
750a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
760a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#ifndef ATRACE_TAG
770a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_TAG ATRACE_TAG_NEVER
780a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#elif ATRACE_TAG > ATRACE_TAG_VALID_MASK
790a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#error ATRACE_TAG must be defined to be one of the tags defined in cutils/trace.h
800a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#endif
810a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
822b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#ifdef HAVE_ANDROID_OS
830a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
840a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Maximum size of a message that can be logged to the trace buffer.
850a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Note this message includes a tag, the pid, and the string given as the name.
860a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Names should be kept short to get the most use of the trace buffer.
870a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
880a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_MESSAGE_LENGTH 1024
890a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
900a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
910a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Opens the trace file for writing and reads the property for initial tags.
920a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * The atrace.tags.enableflags property sets the tags to trace.
930a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * This function should not be explicitly called, the first call to any normal
940a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * trace function will cause it to be run safely.
950a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
960a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Rayvoid atrace_setup();
970a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
980a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
99e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Ray * If tracing is ready, set atrace_enabled_tags to the system property
100e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Ray * debug.atrace.tags.enableflags. Can be used as a sysprop change callback.
101e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Ray */
102e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Rayvoid atrace_update_tags();
103e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Ray
104e7bb7bca4f4036c213763673627e1eb6c2c2fdd6Alex Ray/**
105774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis * Set whether the process is debuggable.  By default the process is not
106774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis * considered debuggable.  If the process is not debuggable then application-
107774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis * level tracing is not allowed unless the ro.debuggable system property is
108774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis * set to '1'.
109774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis */
110774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennisvoid atrace_set_debuggable(bool debuggable);
111774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis
112774f9299912cdf9f2a6b3805bb557e30bafbad05Jamie Gennis/**
113b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennis * Set whether tracing is enabled for the current process.  This is used to
114b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennis * prevent tracing within the Zygote process.
115b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennis */
116b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennisvoid atrace_set_tracing_enabled(bool enabled);
117b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennis
118b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennis/**
1190a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Flag indicating whether setup has been completed, initialized to 0.
1200a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Nonzero indicates setup has completed.
1210a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Note: This does NOT indicate whether or not setup was successful.
1220a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
123b13ea45a04a463646a7098b03f9f64d91b29d2b9Jamie Gennisextern volatile int32_t atrace_is_ready;
1240a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1250a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1260a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Set of ATRACE_TAG flags to trace for, initialized to ATRACE_TAG_NOT_READY.
1270a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * A value of zero indicates setup has failed.
1280a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Any other nonzero value indicates setup has succeeded, and tracing is on.
1290a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1300a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Rayextern uint64_t atrace_enabled_tags;
1310a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1320a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1330a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Handle to the kernel's trace buffer, initialized to -1.
1340a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Any other value indicates setup has succeeded, and is a valid fd for tracing.
1350a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1360a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Rayextern int atrace_marker_fd;
1370a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1380a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1390a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * atrace_init readies the process for tracing by opening the trace_marker file.
1400a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Calling any trace function causes this to be run, so calling it is optional.
1410a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * This can be explicitly run to avoid setup delay on first trace function.
1420a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1430a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_INIT() atrace_init()
1440a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline void atrace_init()
1450a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
1460a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    if (CC_UNLIKELY(!android_atomic_acquire_load(&atrace_is_ready))) {
1470a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        atrace_setup();
1480a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    }
1490a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
1500a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1510a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1520a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Get the mask of all tags currently enabled.
1530a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * It can be used as a guard condition around more expensive trace calculations.
1540a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Every trace function calls this, which ensures atrace_init is run.
1550a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1560a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_GET_ENABLED_TAGS() atrace_get_enabled_tags()
1570a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline uint64_t atrace_get_enabled_tags()
1580a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
1590a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    atrace_init();
1600a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    return atrace_enabled_tags;
1610a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
1620a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1630a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1640a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Test if a given tag is currently enabled.
1650a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Returns nonzero if the tag is enabled, otherwise zero.
1660a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * It can be used as a guard condition around more expensive trace calculations.
1670a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1680a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_ENABLED() atrace_is_tag_enabled(ATRACE_TAG)
1690a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline uint64_t atrace_is_tag_enabled(uint64_t tag)
1700a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
1710a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    return atrace_get_enabled_tags() & tag;
1720a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
1730a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1740a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1750a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Trace the beginning of a context.  name is used to identify the context.
1760a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * This is often used to time function execution.
1770a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1780a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_BEGIN(name) atrace_begin(ATRACE_TAG, name)
1790a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline void atrace_begin(uint64_t tag, const char* name)
1800a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
1810a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
1820a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        char buf[ATRACE_MESSAGE_LENGTH];
1830a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        size_t len;
1840a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1850a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "B|%d|%s", getpid(), name);
1860a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        write(atrace_marker_fd, buf, len);
1870a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    }
1880a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
1890a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
1900a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
1910a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Trace the end of a context.
1920a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * This should match up (and occur after) a corresponding ATRACE_BEGIN.
1930a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
1940a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_END() atrace_end(ATRACE_TAG)
1950a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline void atrace_end(uint64_t tag)
1960a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
1970a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
1980a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        char c = 'E';
1990a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        write(atrace_marker_fd, &c, 1);
2000a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    }
2010a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
2020a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
2030a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray/**
20466317770d37c012b12609defdc750304c97bd8d3Alex Ray * Trace the beginning of an asynchronous event. Unlike ATRACE_BEGIN/ATRACE_END
20566317770d37c012b12609defdc750304c97bd8d3Alex Ray * contexts, asynchronous events do not need to be nested. The name describes
20666317770d37c012b12609defdc750304c97bd8d3Alex Ray * the event, and the cookie provides a unique identifier for distinguishing
20766317770d37c012b12609defdc750304c97bd8d3Alex Ray * simultaneous events. The name and cookie used to begin an event must be
20866317770d37c012b12609defdc750304c97bd8d3Alex Ray * used to end it.
20966317770d37c012b12609defdc750304c97bd8d3Alex Ray */
21066317770d37c012b12609defdc750304c97bd8d3Alex Ray#define ATRACE_ASYNC_BEGIN(name, cookie) \
21166317770d37c012b12609defdc750304c97bd8d3Alex Ray    atrace_async_begin(ATRACE_TAG, name, cookie)
21266317770d37c012b12609defdc750304c97bd8d3Alex Raystatic inline void atrace_async_begin(uint64_t tag, const char* name,
21366317770d37c012b12609defdc750304c97bd8d3Alex Ray        int32_t cookie)
21466317770d37c012b12609defdc750304c97bd8d3Alex Ray{
21566317770d37c012b12609defdc750304c97bd8d3Alex Ray    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
21666317770d37c012b12609defdc750304c97bd8d3Alex Ray        char buf[ATRACE_MESSAGE_LENGTH];
21766317770d37c012b12609defdc750304c97bd8d3Alex Ray        size_t len;
21866317770d37c012b12609defdc750304c97bd8d3Alex Ray
21966317770d37c012b12609defdc750304c97bd8d3Alex Ray        len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "S|%d|%s|%d", getpid(),
22066317770d37c012b12609defdc750304c97bd8d3Alex Ray                name, cookie);
22166317770d37c012b12609defdc750304c97bd8d3Alex Ray        write(atrace_marker_fd, buf, len);
22266317770d37c012b12609defdc750304c97bd8d3Alex Ray    }
22366317770d37c012b12609defdc750304c97bd8d3Alex Ray}
22466317770d37c012b12609defdc750304c97bd8d3Alex Ray
22566317770d37c012b12609defdc750304c97bd8d3Alex Ray/**
22666317770d37c012b12609defdc750304c97bd8d3Alex Ray * Trace the end of an asynchronous event.
22766317770d37c012b12609defdc750304c97bd8d3Alex Ray * This should have a corresponding ATRACE_ASYNC_BEGIN.
22866317770d37c012b12609defdc750304c97bd8d3Alex Ray */
22966317770d37c012b12609defdc750304c97bd8d3Alex Ray#define ATRACE_ASYNC_END(name, cookie) atrace_async_end(ATRACE_TAG, name, cookie)
23066317770d37c012b12609defdc750304c97bd8d3Alex Raystatic inline void atrace_async_end(uint64_t tag, const char* name,
23166317770d37c012b12609defdc750304c97bd8d3Alex Ray        int32_t cookie)
23266317770d37c012b12609defdc750304c97bd8d3Alex Ray{
23366317770d37c012b12609defdc750304c97bd8d3Alex Ray    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
23466317770d37c012b12609defdc750304c97bd8d3Alex Ray        char buf[ATRACE_MESSAGE_LENGTH];
23566317770d37c012b12609defdc750304c97bd8d3Alex Ray        size_t len;
23666317770d37c012b12609defdc750304c97bd8d3Alex Ray
23766317770d37c012b12609defdc750304c97bd8d3Alex Ray        len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "F|%d|%s|%d", getpid(),
23866317770d37c012b12609defdc750304c97bd8d3Alex Ray                name, cookie);
23966317770d37c012b12609defdc750304c97bd8d3Alex Ray        write(atrace_marker_fd, buf, len);
24066317770d37c012b12609defdc750304c97bd8d3Alex Ray    }
24166317770d37c012b12609defdc750304c97bd8d3Alex Ray}
24266317770d37c012b12609defdc750304c97bd8d3Alex Ray
24366317770d37c012b12609defdc750304c97bd8d3Alex Ray
24466317770d37c012b12609defdc750304c97bd8d3Alex Ray/**
2450a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * Traces an integer counter value.  name is used to identify the counter.
2460a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray * This can be used to track how a value changes over time.
2470a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray */
2480a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#define ATRACE_INT(name, value) atrace_int(ATRACE_TAG, name, value)
2490a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Raystatic inline void atrace_int(uint64_t tag, const char* name, int32_t value)
2500a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray{
2510a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    if (CC_UNLIKELY(atrace_is_tag_enabled(tag))) {
2520a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        char buf[ATRACE_MESSAGE_LENGTH];
2530a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        size_t len;
2540a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
2550a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        len = snprintf(buf, ATRACE_MESSAGE_LENGTH, "C|%d|%s|%d",
2560a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray                getpid(), name, value);
2570a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray        write(atrace_marker_fd, buf, len);
2580a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray    }
2590a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray}
2600a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
2612b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#else // not HAVE_ANDROID_OS
2622b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis
2632b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_INIT()
2642b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_GET_ENABLED_TAGS()
2652b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_ENABLED()
2662b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_BEGIN(name)
2672b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_END()
2682b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_ASYNC_BEGIN(name, cookie)
2692b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_ASYNC_END(name, cookie)
2702b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#define ATRACE_INT(name, value)
2712b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis
2722b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis#endif // not HAVE_ANDROID_OS
2732b68e0675b3e3e2f45001e4597872609d26956aeJamie Gennis
2740a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray__END_DECLS
2750a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray
2760a34643160890eb50f7d8e016b4ec93d9db2aa27Alex Ray#endif // _LIBS_CUTILS_TRACE_H
277