110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/*
210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Copyright 2008, The Android Open Source Project
310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * you may not use this file except in compliance with the License.
610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * You may obtain a copy of the License at
710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project *
1010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * See the License for the specific language governing permissions and
1410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * limitations under the License.
1510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
1610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
1710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/*
1810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * Binary implementation of the original opcontrol script due to missing tools
1910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * like awk, test, etc.
2010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
2110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
2210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <unistd.h>
2310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <getopt.h>
2410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdio.h>
2510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <stdlib.h>
26d850f374318831902a1386ec329cb3863b373874Jean-Baptiste Queru#include <string.h>
2710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <errno.h>
2810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <fcntl.h>
2910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <signal.h>
3087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown#include <dirent.h>
3110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include <sys/stat.h>
3287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown#include <sys/types.h>
3387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown#include <sys/wait.h>
3410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project#include "op_config.h"
3610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
37751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#define verbose(fmt...) if (verbose_print) printf(fmt)
3810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project/* Experiments found that using a small interval may hang the device, and the
4010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project * more events tracked simultaneously, the longer the interval has to be.
4110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project */
425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
43751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
44751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#define MAX_EVENTS 2
45751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beareint min_count[MAX_EVENTS] = {60000, 100000};
46751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#elif !defined(WITH_ARM_V7_A)
475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#define MAX_EVENTS 3
481434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint min_count[MAX_EVENTS] = {150000, 200000, 250000};
495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#else
501434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng#define MAX_EVENTS 5
51afec5b915f91a233f37047c29de9531be001778aBen Chengint min_count[MAX_EVENTS] = {150000, 20000, 25000, 30000, 35000};
525a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#endif
535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
54751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beareint verbose_print;
5510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint list_events;
5610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint show_usage;
5710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint setup;
5810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint quick;
59a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Chengint timer;
6010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint num_events;
6110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint start;
6210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint stop;
6310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint reset;
6410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
655a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengint selected_events[MAX_EVENTS];
665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengint selected_counts[MAX_EVENTS];
6710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
68751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Bearechar callgraph[8];
6910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectchar kernel_range[512];
7010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectchar vmlinux[512];
7110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
7210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstruct option long_options[] = {
7310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"help", 0, &show_usage, 1},
7410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"list-events", 0, &list_events, 1},
7510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"reset", 0, &reset, 1},
7610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"setup", 0, &setup, 1},
7710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"quick", 0, &quick, 1},
78a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    {"timer", 0, &timer, 1},
79751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"callgraph", 1, 0, 'c'},
8010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"event", 1, 0, 'e'},
8110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"vmlinux", 1, 0, 'v'},
8210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"kernel-range", 1, 0, 'r'},
8310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"start", 0, &start, 1},
8410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"stop", 0, &stop, 1},
85751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"dump", 0, 0, 'd'},
8610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"shutdown", 0, 0, 'h'},
8710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"status", 0, 0, 't'},
88751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"verbose", 0, 0, 'V'},
8987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    {"verbose-log", 1, 0, 'l'},
9010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {0, 0, 0, 0},
9110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project};
9210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
9310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstruct event_info {
9410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int id;
95751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    int um;
9610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    const char *name;
9710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    const char *explanation;
9810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project} event_info[] = {
99751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
100751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* INTEL_ARCH_PERFMON events */
101751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
102751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* 0x3c counters:cpuid um:zero minimum:6000 filter:0 name:CPU_CLK_UNHALTED :
103751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * Clock cycles when not halted
104751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
105751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x3c, 0, "CPU_CLK_UNHALTED",
106751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     "Clock cycles when not halted" },
107751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
108751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0x3c counters:cpuid um:one minimum:6000 filter:2 name:UNHALTED_REFERENCE_CYCLES :
109751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * Unhalted reference cycles
110751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
111751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x3c, 1, "UNHALTED_REFERENCE_CYCLES",
112751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare      "Unhalted reference cycles" },
113751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
114751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0xc0 counters:cpuid um:zero minimum:6000 filter:1 name:INST_RETIRED :
115751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * number of instructions retired
116751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
117751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     {0xc0, 0, "INST_RETIRED",
118751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare       "number of instructions retired"},
119751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
120751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0x2e counters:cpuid um:x41 minimum:6000 filter:5 name:LLC_MISSES :
121751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * Last level cache demand requests from this core that missed the LLC
122751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
123751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     {0x2e, 0x41, "LLC_MISSES",
124751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare       "Last level cache demand requests from this core that missed the LLC"},
125751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
126751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0x2e counters:cpuid um:x4f minimum:6000 filter:4 name:LLC_REFS :
127751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * Last level cache demand requests from this core
128751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
129751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     {0x2e, 0x4f, "LLC_REFS",
130751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare      "Last level cache demand requests from this core"},
131751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
132751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0xc4 counters:cpuid um:zero minimum:500 filter:6 name:BR_INST_RETIRED :
133751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * number of branch instructions retired
134751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
135751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     {0xc4, 0, "BR_INST_RETIRED",
136751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare       "number of branch instructions retired"},
137751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
138751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    /* event:0xc5 counters:cpuid um:zero minimum:500 filter:7 name:BR_MISS_PRED_RETIRED :
139751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     * number of mispredicted branches retired (precise)
140751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     */
141751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare     {0xc5, 0, "BR_MISS_PRED_RETIRED",
142751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare       "number of mispredicted branches retired (precise)"},
143751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
144751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#elif !defined(WITH_ARM_V7_A)
1455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng    /* ARM V6 events */
146751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x00, 0, "IFU_IFETCH_MISS",
14710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "number of instruction fetch misses"},
148751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x01, 0, "CYCLES_IFU_MEM_STALL",
14910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "cycles instruction fetch pipe is stalled"},
150751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x02, 0, "CYCLES_DATA_STALL",
15110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "cycles stall occurs for due to data dependency"},
152751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x03, 0, "ITLB_MISS",
15310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "number of Instruction MicroTLB misses"},
154751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x04, 0, "DTLB_MISS",
15510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "number of Data MicroTLB misses"},
156751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x05, 0, "BR_INST_EXECUTED",
15710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "branch instruction executed w/ or w/o program flow change"},
158751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x06, 0, "BR_INST_MISS_PRED",
15910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "branch mispredicted"},
160751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x07, 0, "INSN_EXECUTED",
16110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "instructions executed"},
162751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x09, 0, "DCACHE_ACCESS",
16310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "data cache access, cacheable locations"},
164751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0a, 0, "DCACHE_ACCESS_ALL",
16510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "data cache access, all locations"},
166751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0b, 0, "DCACHE_MISS",
16710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "data cache miss"},
168751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0c, 0, "DCACHE_WB",
16910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "data cache writeback, 1 event for every half cacheline"},
170751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0d, 0, "PC_CHANGE",
17110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "number of times the program counter was changed without a mode switch"},
172751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0f, 0, "TLB_MISS",
17310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "Main TLB miss"},
174751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x10, 0, "EXP_EXTERNAL",
17510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "Explicit external data access"},
176751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x11, 0, "LSU_STALL",
17710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "cycles stalled because Load Store request queue is full"},
178751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x12, 0, "WRITE_DRAIN",
17910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "Times write buffer was drained"},
180751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0xff, 0, "CPU_CYCLES",
18110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project     "clock cycles counter"},
1825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#else
1835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng    /* ARM V7 events */
184751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x00, 0, "PMNC_SW_INCR",
1855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Software increment of PMNC registers"},
186751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x01, 0, "IFETCH_MISS",
1875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Instruction fetch misses from cache or normal cacheable memory"},
188751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x02, 0, "ITLB_MISS",
1895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Instruction fetch misses from TLB"},
190751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x03, 0, "DCACHE_REFILL",
1915a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Data R/W operation that causes a refill from cache or normal cacheable"
1925a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "memory"},
193751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x04, 0, "DCACHE_ACCESS",
1945a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Data R/W from cache"},
195751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x05, 0, "DTLB_REFILL",
1965a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Data R/W that causes a TLB refill"},
197751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x06, 0, "DREAD",
1985a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Data read architecturally executed (note: architecturally executed = for"
1995a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "instructions that are unconditional or that pass the condition code)"},
200751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x07, 0, "DWRITE",
2015a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Data write architecturally executed"},
202751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x08, 0, "INSTR_EXECUTED",
2035a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "All executed instructions"},
204751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x09, 0, "EXC_TAKEN",
2055a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Exception taken"},
206751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {0x0A, 0, "EXC_EXECUTED",
2075a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Exception return architecturally executed"},
208e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x0B, 0, "CID_WRITE",
2095a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Instruction that writes to the Context ID Register architecturally"
2105a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "executed"},
211e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x0C, 0, "PC_WRITE",
2125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "SW change of PC, architecturally executed (not by exceptions)"},
213e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x0D, 0, "PC_IMM_BRANCH",
2145a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Immediate branch instruction executed (taken or not)"},
215e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x0E, 0, "PC_PROC_RETURN",
2165a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Procedure return architecturally executed (not by exceptions)"},
217e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x0F, 0, "UNALIGNED_ACCESS",
2185a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Unaligned access architecturally executed"},
219e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x10, 0, "PC_BRANCH_MIS_PRED",
2205a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Branch mispredicted or not predicted. Counts pipeline flushes because of"
2215a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "misprediction"},
222e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x12, 0, "PC_BRANCH_MIS_USED",
2235a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng    "Branch or change in program flow that could have been predicted"},
224e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x40, 0, "WRITE_BUFFER_FULL",
2255a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any write buffer full cycle"},
226e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x41, 0, "L2_STORE_MERGED",
2275a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any store that is merged in L2 cache"},
228e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x42, 0, "L2_STORE_BUFF",
2295a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any bufferable store from load/store to L2 cache"},
230e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x43, 0, "L2_ACCESS",
2315a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any access to L2 cache"},
232e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x44, 0, "L2_CACH_MISS",
2335a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any cacheable miss in L2 cache"},
234e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x45, 0, "AXI_READ_CYCLES",
2355a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of cycles for an active AXI read"},
236e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x46, 0, "AXI_WRITE_CYCLES",
2375a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of cycles for an active AXI write"},
238e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x47, 0, "MEMORY_REPLAY",
2395a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any replay event in the memory subsystem"},
240e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x48, 0, "UNALIGNED_ACCESS_REPLAY",
2415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Unaligned access that causes a replay"},
242e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x49, 0, "L1_DATA_MISS",
2435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "L1 data cache miss as a result of the hashing algorithm"},
244e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4A, 0, "L1_INST_MISS",
2455a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "L1 instruction cache miss as a result of the hashing algorithm"},
246e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4B, 0, "L1_DATA_COLORING",
2475a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "L1 data access in which a page coloring alias occurs"},
248e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4C, 0, "L1_NEON_DATA",
2495a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "NEON data access that hits L1 cache"},
250e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4D, 0, "L1_NEON_CACH_DATA",
2515a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "NEON cacheable data access that hits L1 cache"},
252e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4E, 0, "L2_NEON",
2535a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "L2 access as a result of NEON memory access"},
254e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x4F, 0, "L2_NEON_HIT",
2555a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any NEON hit in L2 cache"},
256e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x50, 0, "L1_INST",
2575a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any L1 instruction cache access, excluding CP15 cache accesses"},
258e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x51, 0, "PC_RETURN_MIS_PRED",
2595a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Return stack misprediction at return stack pop"
2605a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "(incorrect target address)"},
261e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x52, 0, "PC_BRANCH_FAILED",
2625a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Branch prediction misprediction"},
263e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x53, 0, "PC_BRANCH_TAKEN",
2645a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any predicted branch that is taken"},
265e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x54, 0, "PC_BRANCH_EXECUTED",
2665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Any taken branch that is executed"},
267e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x55, 0, "OP_EXECUTED",
2685a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of operations executed"
2695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "(in instruction or mutli-cycle instruction)"},
270e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x56, 0, "CYCLES_INST_STALL",
2715a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Cycles where no instruction available"},
272e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x57, 0, "CYCLES_INST",
2735a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of instructions issued in a cycle"},
274e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x58, 0, "CYCLES_NEON_DATA_STALL",
2755a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of cycles the processor waits on MRC data from NEON"},
276e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x59, 0, "CYCLES_NEON_INST_STALL",
2775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of cycles the processor waits on NEON instruction queue or"
2785a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "NEON load queue"},
279e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x5A, 0, "NEON_CYCLES",
2805a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of cycles NEON and integer processors are not idle"},
281e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x70, 0, "PMU0_EVENTS",
2825a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of events from external input source PMUEXTIN[0]"},
283e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x71, 0, "PMU1_EVENTS",
2845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of events from external input source PMUEXTIN[1]"},
285e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0x72, 0, "PMU_EVENTS",
2865a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of events from both external input sources PMUEXTIN[0]"
2875a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "and PMUEXTIN[1]"},
288e815c52e5e4dd0bae3113d2409097160f27348c6Mike Lockwood    {0xFF, 0, "CPU_CYCLES",
2895a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng     "Number of CPU cycles"},
2905a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#endif
29110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project};
29210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
2931434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengvoid usage()
2941434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
29510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("\nopcontrol: usage:\n"
29610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --list-events    list event types\n"
29710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --help           this message\n"
298751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --verbose        show extra status\n"
29987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown           "   --verbose-log=lvl set daemon logging verbosity during setup\n"
30087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown           "                    levels are: all,sfile,arcs,samples,module,misc\n"
30110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --setup          setup directories\n"
302751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
303751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --quick          setup and select CPU_CLK_UNHALTED:60000\n"
304751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#else
30510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --quick          setup and select CPU_CYCLES:150000\n"
306751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#endif
307a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng           "   --timer          timer-based profiling\n"
30810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --status         show configuration\n"
30910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --start          start data collection\n"
31010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --stop           stop data collection\n"
31110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --reset          clears out data from current session\n"
31210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --shutdown       kill the oprofile daeman\n"
313751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --callgraph=depth callgraph depth\n"
31410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --event=eventspec\n"
31510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "      Choose an event. May be specified multiple times.\n"
31610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "      eventspec is in the form of name[:count], where :\n"
31710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "        name:  event name, see \"opcontrol --list-events\"\n"
31810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "        count: reset counter value\n"
31910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --vmlinux=file   vmlinux kernel image\n"
32010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --kernel-range=start,end\n"
32110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "                    kernel range vma address in hexadecimal\n"
32210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project          );
32310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
32410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3251434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengvoid setup_session_dir()
3261434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
32710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int fd;
32810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    fd = open(OP_DATA_DIR, O_RDONLY);
33010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (fd != -1) {
33110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        system("rm -r "OP_DATA_DIR);
33210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        close(fd);
33310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
33410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
335d095010b52282f41a483c7780815e0242f1e1629Mike Playle    if (mkdir(OP_DATA_DIR, 0755)) {
33610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot create directory \"%s\": %s\n",
33710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                OP_DATA_DIR, strerror(errno));
33810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
339d095010b52282f41a483c7780815e0242f1e1629Mike Playle    if (mkdir(OP_DATA_DIR"/samples", 0755)) {
34010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot create directory \"%s\": %s\n",
34110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                OP_DATA_DIR"/samples", strerror(errno));
34210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
34310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
34410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
345529d868851ce83328c89429d256e68afe320c51dBen Chengint read_num(const char* file)
346529d868851ce83328c89429d256e68afe320c51dBen Cheng{
347529d868851ce83328c89429d256e68afe320c51dBen Cheng    char buffer[256];
348529d868851ce83328c89429d256e68afe320c51dBen Cheng    int fd = open(file, O_RDONLY);
349529d868851ce83328c89429d256e68afe320c51dBen Cheng    if (fd<0) return -1;
350529d868851ce83328c89429d256e68afe320c51dBen Cheng    int rd = read(fd, buffer, sizeof(buffer)-1);
351529d868851ce83328c89429d256e68afe320c51dBen Cheng    buffer[rd] = 0;
352529d868851ce83328c89429d256e68afe320c51dBen Cheng    close(fd);
353529d868851ce83328c89429d256e68afe320c51dBen Cheng    return atoi(buffer);
354529d868851ce83328c89429d256e68afe320c51dBen Cheng}
355529d868851ce83328c89429d256e68afe320c51dBen Cheng
3561434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint do_setup()
3571434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
35810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char dir[1024];
35910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
360529d868851ce83328c89429d256e68afe320c51dBen Cheng    /*
361529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Kill the old daemon so that setup can be done more than once to achieve
362529d868851ce83328c89429d256e68afe320c51dBen Cheng     * the same effect as reset.
363529d868851ce83328c89429d256e68afe320c51dBen Cheng     */
364529d868851ce83328c89429d256e68afe320c51dBen Cheng    int num = read_num(OP_DATA_DIR"/lock");
365529d868851ce83328c89429d256e68afe320c51dBen Cheng    if (num >= 0) {
366529d868851ce83328c89429d256e68afe320c51dBen Cheng        printf("Terminating the old daemon...\n");
367529d868851ce83328c89429d256e68afe320c51dBen Cheng        kill(num, SIGTERM);
368529d868851ce83328c89429d256e68afe320c51dBen Cheng        sleep(5);
369529d868851ce83328c89429d256e68afe320c51dBen Cheng    }
370529d868851ce83328c89429d256e68afe320c51dBen Cheng
37110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    setup_session_dir();
37210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
373d095010b52282f41a483c7780815e0242f1e1629Mike Playle    if (mkdir(OP_DRIVER_BASE, 0755)) {
37487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (errno != EEXIST) {
37587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            fprintf(stderr, "Cannot create directory "OP_DRIVER_BASE": %s\n",
37687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    strerror(errno));
37787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            return -1;
37887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
37910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
38087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
38187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    if (access(OP_DRIVER_BASE"/stats", F_OK)) {
38287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (system("mount -t oprofilefs nodev "OP_DRIVER_BASE)) {
38387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            return -1;
38487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
38510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
38610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return 0;
38710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
38810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
38910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_list_events()
39010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
39110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
39210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
39310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("%-20s: %s\n", "name", "meaning");
39410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("----------------------------------------"
39510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "--------------------------------------\n");
39610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) {
39710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        printf("%-20s: %s\n", event_info[i].name, event_info[i].explanation);
39810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
39910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
40010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4011434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint find_event_idx_from_name(const char *name)
4021434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
40310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
40410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
40510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) {
40610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (!strcmp(name, event_info[i].name)) {
40710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return i;
40810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
40910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
41010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return -1;
41110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
41210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4131434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengconst char * find_event_name_from_id(int id)
4141434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
41510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
41610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
41710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    for (i = 0; i < sizeof(event_info)/sizeof(struct event_info); i++) {
41810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (event_info[i].id == id) {
41910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return event_info[i].name;
42010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
42110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
42210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return NULL;
42310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
42410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4251434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint process_event(const char *event_spec)
4261434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
42710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char event_name[512];
42810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char count_name[512];
42910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
4301434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    int event_idx;
43110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int count_val;
43210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
43310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strncpy(event_name, event_spec, 512);
43410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    count_name[0] = 0;
43510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
43610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    /* First, check if the name is followed by ":" */
43710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    for (i = 0; i < strlen(event_name); i++) {
43810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (event_name[i] == 0) {
43910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
44010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
44110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (event_name[i] == ':') {
44210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            strncpy(count_name, event_name+i+1, 512);
44310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            event_name[i] = 0;
44410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
44510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
44610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
4471434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    event_idx = find_event_idx_from_name(event_name);
4481434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    if (event_idx == -1) {
44910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Unknown event name: %s\n", event_name);
45010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        return -1;
45110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
45210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
45387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    /* Use default count */
45410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (count_name[0] == 0) {
45510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        count_val = min_count[0];
45610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    } else {
45710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        count_val = atoi(count_name);
45810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
45910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4601434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    selected_events[num_events] = event_idx;
46110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    selected_counts[num_events++] = count_val;
4621434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    verbose("event_id is %d\n", event_info[event_idx].id);
46310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("count_val is %d\n", count_val);
46410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return 0;
46510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
46610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
46710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint echo_dev(const char* str, int val, const char* file, int counter)
46810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
46910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char fullname[512];
47010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char content[128];
47110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int fd;
47210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
47310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (counter >= 0) {
47410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        snprintf(fullname, 512, OP_DRIVER_BASE"/%d/%s", counter, file);
47510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
47610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
47710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        snprintf(fullname, 512, OP_DRIVER_BASE"/%s", file);
47810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
47910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    fd = open(fullname, O_WRONLY);
48010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (fd<0) {
48110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot open %s: %s\n", fullname, strerror(errno));
48210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        return fd;
48310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
48410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (str == 0) {
48510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(content, "%d", val);
48610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
48710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
48810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        strncpy(content, str, 128);
48910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
49010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("Configure %s (%s)\n", fullname, content);
49110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    write(fd, content, strlen(content));
49210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    close(fd);
49310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return 0;
49410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
49510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
49610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_status()
49710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
49810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int num;
49910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char fullname[512];
50010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int i;
50110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
50210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("Driver directory: %s\n", OP_DRIVER_BASE);
50310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("Session directory: %s\n", OP_DATA_DIR);
5045a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng    for (i = 0; i < MAX_EVENTS; i++) {
50510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(fullname, OP_DRIVER_BASE"/%d/enabled", i);
50610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        num = read_num(fullname);
50710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (num > 0) {
50810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("Counter %d:\n", i);
50910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
51010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* event name */
51110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            sprintf(fullname, OP_DRIVER_BASE"/%d/event", i);
51210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(fullname);
51310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("    name: %s\n", find_event_name_from_id(num));
51410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
51510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* profile interval */
51610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            sprintf(fullname, OP_DRIVER_BASE"/%d/count", i);
51710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(fullname);
51810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("    count: %d\n", num);
51910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
52010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        else {
52110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("Counter %d disabled\n", i);
52210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
52310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
52410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
52510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    num = read_num(OP_DATA_DIR"/lock");
52610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (num >= 0) {
52710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        int fd;
52810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Still needs to check if this lock is left-over */
52910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(fullname, "/proc/%d", num);
53010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fd = open(fullname, O_RDONLY);
53110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (fd == -1) {
532529d868851ce83328c89429d256e68afe320c51dBen Cheng            printf("OProfile daemon exited prematurely - redo setup"
53310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                   " before you continue\n");
53410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return;
53510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
53610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        else {
53710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            close(fd);
53887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
53910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("oprofiled pid: %d\n", num);
54010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(OP_DRIVER_BASE"/enable");
54187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
54210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("profiler is%s running\n", num == 0 ? " not" : "");
54387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
54487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            DIR* dir = opendir(OP_DRIVER_BASE"/stats");
54587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            if (dir) {
54687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                for (struct dirent* dirent; !!(dirent = readdir(dir));) {
54787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    if (strlen(dirent->d_name) >= 4 && memcmp(dirent->d_name, "cpu", 3) == 0) {
54887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        char cpupath[256];
54987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(cpupath, OP_DRIVER_BASE"/stats/");
55087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(cpupath, dirent->d_name);
55187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
55287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
55387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_received");
55487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
55587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples received\n", dirent->d_name, num);
55687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
55787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
55887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_lost_overflow");
55987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
56087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples lost overflow\n", dirent->d_name, num);
56187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
56287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
56387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_invalid_eip");
56487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
56587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples invalid eip\n", dirent->d_name, num);
56687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
56787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
56887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/backtrace_aborted");
56987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
57087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u backtrace aborted\n", dirent->d_name, num);
57187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    }
57287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                }
57387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                closedir(dir);
57487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            }
575751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
57610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(OP_DRIVER_BASE"/backtrace_depth");
577529d868851ce83328c89429d256e68afe320c51dBen Cheng            printf("backtrace_depth: %u\n", num);
57810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
57910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
58010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
58110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        printf("oprofiled is not running\n");
58210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
58310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
58410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
58510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_reset()
58610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
587529d868851ce83328c89429d256e68afe320c51dBen Cheng    /*
588529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Sending SIGHUP will result in the following crash in oprofiled when
589529d868851ce83328c89429d256e68afe320c51dBen Cheng     * profiling subsequent runs:
590529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Stack Trace:
591529d868851ce83328c89429d256e68afe320c51dBen Cheng     * RELADDR   FUNCTION                         FILE:LINE
592529d868851ce83328c89429d256e68afe320c51dBen Cheng     *   00008cd8  add_node+12                    oprofilelibdb/db_insert.c:32
593529d868851ce83328c89429d256e68afe320c51dBen Cheng     *   00008d69  odb_update_node_with_offset+60 oprofilelibdb/db_insert.c:102
594529d868851ce83328c89429d256e68afe320c51dBen Cheng     *
595529d868851ce83328c89429d256e68afe320c51dBen Cheng     * However without sending SIGHUP oprofile cannot be restarted successfully.
596529d868851ce83328c89429d256e68afe320c51dBen Cheng     * As a temporary workaround, change do_reset into a no-op for now and kill
597529d868851ce83328c89429d256e68afe320c51dBen Cheng     * the old daemon in do_setup to start all over again as a heavy-weight
598529d868851ce83328c89429d256e68afe320c51dBen Cheng     * reset.
599529d868851ce83328c89429d256e68afe320c51dBen Cheng     */
600529d868851ce83328c89429d256e68afe320c51dBen Cheng#if 0
60110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int fd;
60210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
60310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    fd = open(OP_DATA_DIR"/samples/current", O_RDONLY);
60410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (fd == -1) {
60510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        return;
60610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
60710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    close(fd);
60810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    system("rm -r "OP_DATA_DIR"/samples/current");
609529d868851ce83328c89429d256e68afe320c51dBen Cheng    int num = read_num(OP_DATA_DIR"/lock");
610529d868851ce83328c89429d256e68afe320c51dBen Cheng
611529d868851ce83328c89429d256e68afe320c51dBen Cheng    if (num >= 0) {
612529d868851ce83328c89429d256e68afe320c51dBen Cheng        printf("Signalling daemon...\n");
613529d868851ce83328c89429d256e68afe320c51dBen Cheng        kill(num, SIGHUP);
614529d868851ce83328c89429d256e68afe320c51dBen Cheng    }
615529d868851ce83328c89429d256e68afe320c51dBen Cheng#endif
61610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
61710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
61810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint main(int argc, char * const argv[])
61910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
62010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int option_index;
62187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    bool show_status = false;
62287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    char* verbose_log = NULL;
62310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
62410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    /* Initialize default strings */
62510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strcpy(vmlinux, "--no-vmlinux");
62610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strcpy(kernel_range, "");
62710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
62810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    while (1) {
62987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        int c = getopt_long(argc, argv, "c:e:v:r:dhVtl:", long_options, &option_index);
63010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (c == -1) {
63110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
63210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
63310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        switch (c) {
63410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 0:
63510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
636751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --callgraph */
637751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'c':
63887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                strncpy(callgraph, optarg, sizeof(callgraph));
639751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
64010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --event */
64110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'e':
6425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                if (num_events == MAX_EVENTS) {
6435a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                    fprintf(stderr, "More than %d events specified\n",
6445a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                            MAX_EVENTS);
64510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    exit(1);
64610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
64710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (process_event(optarg)) {
64810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    exit(1);
64910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
65010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
65110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --vmlinux */
65210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'v':
65310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                sprintf(vmlinux, "-k %s", optarg);
65410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
65510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --kernel-range */
65610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'r':
65710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                sprintf(kernel_range, "-r %s", optarg);
65810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
659751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'd':
660751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --dump */ {
661751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                int pid = read_num(OP_DATA_DIR"/lock");
662751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                echo_dev("1", 0, "dump", -1);
663751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
664751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            }
66510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --shutdown */
66610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'h': {
66710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int pid = read_num(OP_DATA_DIR"/lock");
66810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (pid >= 0) {
669751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    kill(pid, SIGHUP); /* Politely ask the daemon to close files */
670751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    sleep(1);
671751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    kill(pid, SIGTERM);/* Politely ask the daemon to die */
672751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    sleep(1);
67310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    kill(pid, SIGKILL);
67487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                }
67510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                setup_session_dir();
67610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
67710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
678751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --verbose */
679751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'V':
680751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                verbose_print++;
681751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
68287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            /* --verbose-log */
68387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            case 'l':
68487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                verbose_log = strdup(optarg);
68587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                break;
68610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --status */
68710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 't':
68887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                show_status = true;
68910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
69010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            default:
69110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                usage();
69210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
69310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
69410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
69510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("list_events = %d\n", list_events);
69610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("setup = %d\n", setup);
69710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
69810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (list_events) {
69910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        do_list_events();
70010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
70110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
70210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (quick) {
703751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
704751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare        process_event("CPU_CLK_UNHALTED");
705751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#else
70610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        process_event("CPU_CYCLES");
707751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#endif
70810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        setup = 1;
70910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
71010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
711a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    if (timer) {
712a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        setup = 1;
713a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    }
714a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng
71510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (reset) {
71610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        do_reset();
71710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
71810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
71910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (show_usage) {
72010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        usage();
72110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
72210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
72310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (setup) {
72410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (do_setup()) {
72510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            fprintf(stderr, "do_setup failed");
72610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            exit(1);
72710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
72810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
72910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
730751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    if (strlen(callgraph)) {
731751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare        echo_dev(callgraph, 0, "backtrace_depth", -1);
732751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    }
733751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
734a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    if (num_events != 0 || timer != 0) {
73587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        char command[1024];
73610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        int i;
73710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
73887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        strcpy(command, argv[0]);
73987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        char* slash = strrchr(command, '/');
74087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        strcpy(slash ? slash + 1 : command, "oprofiled --session-dir="OP_DATA_DIR);
74110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
742751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
743751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare        /* Nothing */
744751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#elif !defined(WITH_ARM_V7_A)
74510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Since counter #3 can only handle CPU_CYCLES, check and shuffle the
74610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         * order a bit so that the maximal number of events can be profiled
74710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         * simultaneously
74810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         */
74910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (num_events == 3) {
75010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            for (i = 0; i < num_events; i++) {
75110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int event_idx = selected_events[i];
75210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
75310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (event_info[event_idx].id == 0xff) {
75410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    break;
75510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
75610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
75710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
75810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* No CPU_CYCLES is found */
75910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (i == 3) {
76010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "You can only specify three events if one of "
76110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                                "them is CPU_CYCLES\n");
76210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
76310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
76410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* Swap CPU_CYCLES to counter #2 (starting from #0)*/
76510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            else if (i != 2) {
76610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int temp;
76710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
76810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                temp = selected_events[2];
76910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_events[2] = selected_events[i];
77010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_events[i] = temp;
77110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
77210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                temp = selected_counts[2];
77310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_counts[2] = selected_counts[i];
77410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_counts[i] = temp;
77510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
77610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
7775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#endif
77810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
77910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Configure the counters and enable them */
78010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        for (i = 0; i < num_events; i++) {
78110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            int event_idx = selected_events[i];
78210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            int setup_result = 0;
78310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
78410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (i == 0) {
78587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                snprintf(command + strlen(command), sizeof(command) - strlen(command),
78687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        " --events=");
78787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            } else {
78887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                snprintf(command + strlen(command), sizeof(command) - strlen(command), ",");
78910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
79010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* Compose name:id:count:unit_mask:kernel:user, something like
79110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project             * --events=CYCLES_DATA_STALL:2:0:200000:0:1:1,....
79210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project             */
79387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
794751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     "%s:%d:%d:%d:%d:1:1",
79510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     event_info[event_idx].name,
79610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     event_info[event_idx].id,
79710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     i,
798751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     selected_counts[i],
799751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     event_info[event_idx].um);
80010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
80110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "user", i);
80210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "kernel", i);
803751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            setup_result |= echo_dev(NULL, event_info[event_idx].um, "unit_mask", i);
80410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "enabled", i);
80510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev(NULL, selected_counts[i], "count", i);
80610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev(NULL, event_info[event_idx].id,
80710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                                     "event", i);
80810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (setup_result) {
80910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "Counter configuration failed for %s\n",
81010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                        event_info[event_idx].name);
81110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "Did you do \"opcontrol --setup\" first?\n");
81210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
81310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
81410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
81510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
816a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        if (timer == 0) {
817a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            /* If not in timer mode, disable unused counters */
818a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            for (i = num_events; i < MAX_EVENTS; i++) {
819a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng                echo_dev("0", 0, "enabled", i);
820a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            }
821a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        } else {
822a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            /* Timer mode uses empty event list */
82387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
82487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " --events=");
82510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
82610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
82787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        snprintf(command + strlen(command), sizeof(command) - strlen(command),
82887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                " %s", vmlinux);
82910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (kernel_range[0]) {
83087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
83187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " %s", kernel_range);
83210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
83387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
83487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (verbose_log) {
83587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
83687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " --verbose=%s", verbose_log);
83787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
83887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
83987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        printf("Starting oprofiled...\n");
84010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        verbose("command: %s\n", command);
84187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
84287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        int rc = system(command);
84387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (rc) {
84487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            fprintf(stderr, "Failed, oprofile returned exit code: %d\n", rc);
84587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        } else {
84687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            sleep(2);
84787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            printf("Ready\n");
84887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
84910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
85010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
85110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (start) {
85210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        echo_dev("1", 0, "enable", -1);
853529d868851ce83328c89429d256e68afe320c51dBen Cheng        int num = read_num(OP_DATA_DIR"/lock");
854529d868851ce83328c89429d256e68afe320c51dBen Cheng
855529d868851ce83328c89429d256e68afe320c51dBen Cheng        if (num >= 0) {
856529d868851ce83328c89429d256e68afe320c51dBen Cheng            kill(num, SIGUSR1);
857529d868851ce83328c89429d256e68afe320c51dBen Cheng        }
85810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
85910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
86010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (stop) {
861afec5b915f91a233f37047c29de9531be001778aBen Cheng        echo_dev("1", 0, "dump", -1);
86210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        echo_dev("0", 0, "enable", -1);
86310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
86487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
86587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    if (show_status) {
86687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        do_status();
86787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    }
86810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
869