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
3973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info {
4073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int id;
4173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int counters;
4273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int um;
4373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    const char *name;
4473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    const char *explanation;
4573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
4673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
4773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#define CTR(n)  (1<<(n))
485a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
49751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
5073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_arch_perfmon[] = {
5173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/i386/arch_perfmon/events.h"
5273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
5373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
54751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#define MAX_EVENTS 2
55751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beareint min_count[MAX_EVENTS] = {60000, 100000};
5673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
5773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindconst char *default_event = "CPU_CLK_UNHALTED";
5873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif
5973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
6073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__arm__)
6173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if !defined(WITH_ARM_V7_A)
6273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_armv6[] = {
6373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/arm/armv6/events.h"
6473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
6573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
665a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#define MAX_EVENTS 3
671434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint min_count[MAX_EVENTS] = {150000, 200000, 250000};
6873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
695a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#else
7073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_armv7[] = {
7173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/arm/armv7/events.h"
7273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
7373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
741434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng#define MAX_EVENTS 5
75afec5b915f91a233f37047c29de9531be001778aBen Chengint min_count[MAX_EVENTS] = {150000, 20000, 25000, 30000, 35000};
765a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#endif
775a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng
7873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindconst char *default_event = "CPU_CYCLES";
7973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif
8073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
8173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__mips__)
8273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_24K[] = {
8373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/mips/24K/events.h"
8473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
8573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_34K[] = {
8673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/mips/34K/events.h"
8773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
8873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_74K[] = {
8973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/mips/74K/events.h"
9073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
9173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct event_info event_info_1004K[] = {
9273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    #include "../events/mips/1004K/events.h"
9373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
9473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
9573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#define MAX_EVENTS 4
9673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindint min_count[MAX_EVENTS] = {150000, 20000, 25000, 30000};
9773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
9873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindconst char *default_event = "CYCLES";
9973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif /* defined(__mips__) */
10073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
10173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#define ARRAYSZ(x) (sizeof(x)/sizeof((x)[0]))
10273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
10373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct cpuevents {
10473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    const char *cpu;
10573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    struct event_info *event_info;
10673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    unsigned int nevents;
10773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind} cpuevents[] = {
10873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__i386__) || defined(__x86_64__)
10973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"i386/arch_perfmon", event_info_arch_perfmon, ARRAYSZ(event_info_arch_perfmon)},
11073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif /* defined(__i386__) || defined(__x86_64__) */
11173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__arm__)
11273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if !defined(WITH_ARM_V7_A)
11373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"arm/armv6", event_info_armv6, ARRAYSZ(event_info_armv6)},
11473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#else
11573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"arm/armv7", event_info_armv7, ARRAYSZ(event_info_armv7)},
11673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif
11773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif /* defined(__arm__) */
11873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__mips__)
11973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"mips/24K", event_info_24K, ARRAYSZ(event_info_24K)},
12073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"mips/34K", event_info_34K, ARRAYSZ(event_info_34K)},
12173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"mips/74K", event_info_74K, ARRAYSZ(event_info_74K)},
12273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    {"mips/1004K", event_info_1004K, ARRAYSZ(event_info_1004K)},
12373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif /* defined(__mips__) */
12473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind};
12573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
12673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindstruct cpuevents *cpuevent;
12773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#define event_info cpuevent->event_info
12873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#define NEVENTS cpuevent->nevents
12973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
130751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beareint verbose_print;
13110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint list_events;
13210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint show_usage;
13310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint setup;
13410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint quick;
135a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Chengint timer;
13610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint num_events;
13710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint start;
13810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint stop;
13910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint reset;
14010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
1415a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengint selected_events[MAX_EVENTS];
1425a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Chengint selected_counts[MAX_EVENTS];
14373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindint max_events;
14410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
145751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Bearechar callgraph[8];
14610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectchar kernel_range[512];
14710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectchar vmlinux[512];
14810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
14910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectstruct option long_options[] = {
15010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"help", 0, &show_usage, 1},
15110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"list-events", 0, &list_events, 1},
15210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"reset", 0, &reset, 1},
15310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"setup", 0, &setup, 1},
15410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"quick", 0, &quick, 1},
155a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    {"timer", 0, &timer, 1},
156751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"callgraph", 1, 0, 'c'},
15710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"event", 1, 0, 'e'},
15810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"vmlinux", 1, 0, 'v'},
15910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"kernel-range", 1, 0, 'r'},
16010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"start", 0, &start, 1},
16110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"stop", 0, &stop, 1},
162751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"dump", 0, 0, 'd'},
16310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"shutdown", 0, 0, 'h'},
16410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {"status", 0, 0, 't'},
165751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    {"verbose", 0, 0, 'V'},
16687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    {"verbose-log", 1, 0, 'l'},
16710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    {0, 0, 0, 0},
16810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project};
16910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
17010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
1711434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengvoid usage()
1721434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
17310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("\nopcontrol: usage:\n"
17410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --list-events    list event types\n"
17510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --help           this message\n"
176751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --verbose        show extra status\n"
17787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown           "   --verbose-log=lvl set daemon logging verbosity during setup\n"
17887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown           "                    levels are: all,sfile,arcs,samples,module,misc\n"
17910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --setup          setup directories\n"
180751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#if defined(__i386__) || defined(__x86_64__)
181751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --quick          setup and select CPU_CLK_UNHALTED:60000\n"
18273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#elif defined(__arm__)
18310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --quick          setup and select CPU_CYCLES:150000\n"
18473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#elif defined(__mips__)
18573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind           "   --quick          setup and select CYCLES:150000\n"
186751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare#endif
187a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng           "   --timer          timer-based profiling\n"
18810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --status         show configuration\n"
18910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --start          start data collection\n"
19010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --stop           stop data collection\n"
19110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --reset          clears out data from current session\n"
19273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind           "   --shutdown       kill the oprofile daemon\n"
193751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare           "   --callgraph=depth callgraph depth\n"
19410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --event=eventspec\n"
19510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "      Choose an event. May be specified multiple times.\n"
19610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "      eventspec is in the form of name[:count], where :\n"
19710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "        name:  event name, see \"opcontrol --list-events\"\n"
19810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "        count: reset counter value\n"
19910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --vmlinux=file   vmlinux kernel image\n"
20010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "   --kernel-range=start,end\n"
20110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "                    kernel range vma address in hexadecimal\n"
20210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project          );
20310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
20410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
20573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindint setup_device(void)
2061434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
20773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (mkdir(OP_DRIVER_BASE, 0755)) {
20873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        if (errno != EEXIST) {
20973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            fprintf(stderr, "Cannot create directory "OP_DRIVER_BASE": %s\n",
21073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind                    strerror(errno));
21173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            return -1;
21273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        }
21373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
21410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
21573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (access(OP_DRIVER_BASE"/stats", F_OK)) {
21673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        if (system("mount -t oprofilefs nodev "OP_DRIVER_BASE)) {
21773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            return -1;
21873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        }
21973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
22073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
22173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    /* Selecting the event information by cpu_type has only been tested on MIPS */
22273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__mips__)
22373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    /* Use cpu_type to select the events */
22473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int fd = open(OP_DRIVER_BASE "/cpu_type", O_RDONLY);
22573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (fd < 0) {
22673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	fprintf(stderr, OP_DRIVER_BASE "/cpu_type: %s\n",
22773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind		strerror(errno));
22873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	return -1;
22973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
23073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
23173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    char buf[512];
23273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int n = read(fd, buf, sizeof(buf)-1);
23373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    close(fd);
23473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (n < 0) {
23573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	fprintf(stderr, OP_DRIVER_BASE "/cpu_type: %s\n",
23673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind		strerror(errno));
23773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	return -1;
23873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
23973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    buf[n] = '\0';
24073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (unsigned int i = 0; i < ARRAYSZ(cpuevents); i++) {
24173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	if (strcmp(buf, cpuevents[i].cpu) == 0) {
24273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	    cpuevent = &cpuevents[i];
24373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	}
24473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
24573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (cpuevent == NULL) {
24673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	fprintf(stderr, "Unrecognised CPU type %s\n", buf);
24773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	return -1;
24810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
24973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (max_events = 0; max_events < MAX_EVENTS; max_events++) {
25073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	snprintf(buf, sizeof(buf), OP_DRIVER_BASE"/%d", max_events);
25173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	if (access(buf, F_OK) < 0)
25273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	    break;
25373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
25473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#else
25573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    max_events = MAX_EVENTS;
25673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    cpuevent = &cpuevents[0];
25773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#endif
25873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    return 0;
25973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind}
26073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
26173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindvoid setup_session_dir()
26273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind{
26373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (access(OP_DATA_DIR, F_OK) == 0)
26473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        system("rm -r "OP_DATA_DIR);
26510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
266d095010b52282f41a483c7780815e0242f1e1629Mike Playle    if (mkdir(OP_DATA_DIR, 0755)) {
26710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot create directory \"%s\": %s\n",
26810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                OP_DATA_DIR, strerror(errno));
26910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
270d095010b52282f41a483c7780815e0242f1e1629Mike Playle    if (mkdir(OP_DATA_DIR"/samples", 0755)) {
27110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot create directory \"%s\": %s\n",
27210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                OP_DATA_DIR"/samples", strerror(errno));
27310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
27410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
27510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
276529d868851ce83328c89429d256e68afe320c51dBen Chengint read_num(const char* file)
277529d868851ce83328c89429d256e68afe320c51dBen Cheng{
278529d868851ce83328c89429d256e68afe320c51dBen Cheng    char buffer[256];
279529d868851ce83328c89429d256e68afe320c51dBen Cheng    int fd = open(file, O_RDONLY);
280529d868851ce83328c89429d256e68afe320c51dBen Cheng    if (fd<0) return -1;
281529d868851ce83328c89429d256e68afe320c51dBen Cheng    int rd = read(fd, buffer, sizeof(buffer)-1);
282529d868851ce83328c89429d256e68afe320c51dBen Cheng    buffer[rd] = 0;
283529d868851ce83328c89429d256e68afe320c51dBen Cheng    close(fd);
284529d868851ce83328c89429d256e68afe320c51dBen Cheng    return atoi(buffer);
285529d868851ce83328c89429d256e68afe320c51dBen Cheng}
286529d868851ce83328c89429d256e68afe320c51dBen Cheng
2871434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint do_setup()
2881434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
28910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char dir[1024];
29010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
291529d868851ce83328c89429d256e68afe320c51dBen Cheng    /*
292529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Kill the old daemon so that setup can be done more than once to achieve
293529d868851ce83328c89429d256e68afe320c51dBen Cheng     * the same effect as reset.
294529d868851ce83328c89429d256e68afe320c51dBen Cheng     */
295529d868851ce83328c89429d256e68afe320c51dBen Cheng    int num = read_num(OP_DATA_DIR"/lock");
296529d868851ce83328c89429d256e68afe320c51dBen Cheng    if (num >= 0) {
297529d868851ce83328c89429d256e68afe320c51dBen Cheng        printf("Terminating the old daemon...\n");
298529d868851ce83328c89429d256e68afe320c51dBen Cheng        kill(num, SIGTERM);
299529d868851ce83328c89429d256e68afe320c51dBen Cheng        sleep(5);
300529d868851ce83328c89429d256e68afe320c51dBen Cheng    }
301529d868851ce83328c89429d256e68afe320c51dBen Cheng
30210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    setup_session_dir();
30310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
30473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    return 0;
30573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind}
30687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
30773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindvoid stringify_counters(char *ctr_string, int ctr_mask)
30873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind{
30973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int i, n, len;
31073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    char *p = ctr_string;
31173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
31273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    *p = '\0';
31373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (i=0; i<32; ++i) {
31473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        if (ctr_mask & (1<<i)) {
31573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	    p += sprintf(p, "%d,", i);
31673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	}
31773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
31873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (p != ctr_string) {
31973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        *(p-1) = '\0';  /* erase the final comma */
32010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
32110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
32210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_list_events()
32410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
32510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
32673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    char ctrs[32*3+1];
32710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
32873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    printf("%-12s | %-30s: %s\n", "counter", "name", "meaning");
32910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("----------------------------------------"
33010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project           "--------------------------------------\n");
33173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (i = 0; i < NEVENTS; i++) {
33273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        stringify_counters(ctrs, event_info[i].counters);
33373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        printf("%-12s | %-30s: %s\n", ctrs, event_info[i].name, event_info[i].explanation);
33410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
33510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
33610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3371434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint find_event_idx_from_name(const char *name)
3381434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
33910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
34010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
34173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (i = 0; i < NEVENTS; i++) {
34210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (!strcmp(name, event_info[i].name)) {
34310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return i;
34410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
34510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
34610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return -1;
34710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
34810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
34973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lindconst char * find_event_name_from_id(int id, int mask)
3501434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
35110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
35210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
35373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (i = 0; i < NEVENTS; i++) {
35473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	if (event_info[i].id == id && (event_info[i].counters == 0 || (event_info[i].counters & mask))) {
35510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return event_info[i].name;
35610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
35710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
35873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    return "Undefined Event";
35910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
36010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
3611434507eb3c837aa83306fca335f49d5ad3dec4eBen Chengint process_event(const char *event_spec)
3621434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng{
36310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char event_name[512];
36410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char count_name[512];
36510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    unsigned int i;
3661434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    int event_idx;
36710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int count_val;
36810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
36910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strncpy(event_name, event_spec, 512);
37010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    count_name[0] = 0;
37110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
37210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    /* First, check if the name is followed by ":" */
37310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    for (i = 0; i < strlen(event_name); i++) {
37410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (event_name[i] == 0) {
37510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
37610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
37710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (event_name[i] == ':') {
37810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            strncpy(count_name, event_name+i+1, 512);
37910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            event_name[i] = 0;
38010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
38110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
38210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
3831434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    event_idx = find_event_idx_from_name(event_name);
3841434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    if (event_idx == -1) {
38510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Unknown event name: %s\n", event_name);
38610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        return -1;
38710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
38810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
38973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    /*
39073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind     * check that the named event is valid for this event counter
39173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind     * 'num_events' represents the cpu internal counter number
39273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind     */
39373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    verbose("idx: %d, name: %s, mask: %02x, ctr#: %d\n",
39473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            event_idx, event_info[event_idx].name,
39573f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            event_info[event_idx].counters, num_events);
39673f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (event_info[event_idx].counters != 0 &&
39773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	(event_info[event_idx].counters & CTR(num_events)) == 0) {
39873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	fprintf(stderr, "Bad event name: %s for counter %d, see --list\n",
39973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind		event_name, num_events);
40073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind	return -1;
40173f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    }
40273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
40387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    /* Use default count */
40410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (count_name[0] == 0) {
40510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        count_val = min_count[0];
40610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    } else {
40710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        count_val = atoi(count_name);
40810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
40910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
4101434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    selected_events[num_events] = event_idx;
41110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    selected_counts[num_events++] = count_val;
4121434507eb3c837aa83306fca335f49d5ad3dec4eBen Cheng    verbose("event_id is %d\n", event_info[event_idx].id);
41310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("count_val is %d\n", count_val);
41410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return 0;
41510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
41610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
41710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint echo_dev(const char* str, int val, const char* file, int counter)
41810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
41910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char fullname[512];
42010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char content[128];
42110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int fd;
42210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
42310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (counter >= 0) {
42410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        snprintf(fullname, 512, OP_DRIVER_BASE"/%d/%s", counter, file);
42510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
42610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
42710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        snprintf(fullname, 512, OP_DRIVER_BASE"/%s", file);
42810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
42910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    fd = open(fullname, O_WRONLY);
43010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (fd<0) {
43110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        fprintf(stderr, "Cannot open %s: %s\n", fullname, strerror(errno));
43210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        return fd;
43310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
43410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (str == 0) {
43510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(content, "%d", val);
43610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
43710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
43810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        strncpy(content, str, 128);
43910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
44010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("Configure %s (%s)\n", fullname, content);
44110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    write(fd, content, strlen(content));
44210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    close(fd);
44310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    return 0;
44410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
44510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
44610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_status()
44710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
44810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int num;
44910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    char fullname[512];
45010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int i;
45110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
45210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("Driver directory: %s\n", OP_DRIVER_BASE);
45310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    printf("Session directory: %s\n", OP_DATA_DIR);
45473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    for (i = 0; i < max_events; i++) {
45510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(fullname, OP_DRIVER_BASE"/%d/enabled", i);
45610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        num = read_num(fullname);
45710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (num > 0) {
45810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("Counter %d:\n", i);
45910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
46010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* event name */
46110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            sprintf(fullname, OP_DRIVER_BASE"/%d/event", i);
46210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(fullname);
46373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            printf("    name: %s\n", find_event_name_from_id(num, CTR(i)));
46410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
46510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* profile interval */
46610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            sprintf(fullname, OP_DRIVER_BASE"/%d/count", i);
46710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(fullname);
46810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("    count: %d\n", num);
46910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
47010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        else {
47110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("Counter %d disabled\n", i);
47210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
47310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
47410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
47510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    num = read_num(OP_DATA_DIR"/lock");
47610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (num >= 0) {
47710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Still needs to check if this lock is left-over */
47810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        sprintf(fullname, "/proc/%d", num);
47973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        if (access(fullname, R_OK) != 0) {
480529d868851ce83328c89429d256e68afe320c51dBen Cheng            printf("OProfile daemon exited prematurely - redo setup"
48110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                   " before you continue\n");
48210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            return;
48310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
48410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        else {
48587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
48610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("oprofiled pid: %d\n", num);
48710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(OP_DRIVER_BASE"/enable");
48887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
48910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            printf("profiler is%s running\n", num == 0 ? " not" : "");
49087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
49187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            DIR* dir = opendir(OP_DRIVER_BASE"/stats");
49287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            if (dir) {
49387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                for (struct dirent* dirent; !!(dirent = readdir(dir));) {
49487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    if (strlen(dirent->d_name) >= 4 && memcmp(dirent->d_name, "cpu", 3) == 0) {
49587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        char cpupath[256];
49687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(cpupath, OP_DRIVER_BASE"/stats/");
49787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(cpupath, dirent->d_name);
49887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
49987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
50087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_received");
50187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
50287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples received\n", dirent->d_name, num);
50387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
50487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
50587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_lost_overflow");
50687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
50787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples lost overflow\n", dirent->d_name, num);
50887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
50987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
51087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/sample_invalid_eip");
51187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
51287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u samples invalid eip\n", dirent->d_name, num);
51387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
51487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcpy(fullname, cpupath);
51587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        strcat(fullname, "/backtrace_aborted");
51687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        num = read_num(fullname);
51787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        printf("  %s %9u backtrace aborted\n", dirent->d_name, num);
51887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    }
51987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                }
52087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                closedir(dir);
52187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            }
522751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
52310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            num = read_num(OP_DRIVER_BASE"/backtrace_depth");
524529d868851ce83328c89429d256e68afe320c51dBen Cheng            printf("backtrace_depth: %u\n", num);
52510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
52610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
52710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    else {
52810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        printf("oprofiled is not running\n");
52910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
53010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
53110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
53210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectvoid do_reset()
53310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
534529d868851ce83328c89429d256e68afe320c51dBen Cheng    /*
535529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Sending SIGHUP will result in the following crash in oprofiled when
536529d868851ce83328c89429d256e68afe320c51dBen Cheng     * profiling subsequent runs:
537529d868851ce83328c89429d256e68afe320c51dBen Cheng     * Stack Trace:
538529d868851ce83328c89429d256e68afe320c51dBen Cheng     * RELADDR   FUNCTION                         FILE:LINE
539529d868851ce83328c89429d256e68afe320c51dBen Cheng     *   00008cd8  add_node+12                    oprofilelibdb/db_insert.c:32
540529d868851ce83328c89429d256e68afe320c51dBen Cheng     *   00008d69  odb_update_node_with_offset+60 oprofilelibdb/db_insert.c:102
541529d868851ce83328c89429d256e68afe320c51dBen Cheng     *
542529d868851ce83328c89429d256e68afe320c51dBen Cheng     * However without sending SIGHUP oprofile cannot be restarted successfully.
543529d868851ce83328c89429d256e68afe320c51dBen Cheng     * As a temporary workaround, change do_reset into a no-op for now and kill
544529d868851ce83328c89429d256e68afe320c51dBen Cheng     * the old daemon in do_setup to start all over again as a heavy-weight
545529d868851ce83328c89429d256e68afe320c51dBen Cheng     * reset.
546529d868851ce83328c89429d256e68afe320c51dBen Cheng     */
547529d868851ce83328c89429d256e68afe320c51dBen Cheng#if 0
54873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    int pid = read_num(OP_DATA_DIR"/lock");
54973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (pid >= 0)
55073f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        kill(pid, SIGHUP);  /* HUP makes oprofiled close its sample files */
551529d868851ce83328c89429d256e68afe320c51dBen Cheng
55273f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    if (access(OP_DATA_DIR"/samples/current", R_OK) == 0)
55373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind      system("rm -r "OP_DATA_DIR"/samples/current");
554529d868851ce83328c89429d256e68afe320c51dBen Cheng#endif
55510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
55610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
55710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Projectint main(int argc, char * const argv[])
55810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project{
55910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    int option_index;
56087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    bool show_status = false;
56187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    char* verbose_log = NULL;
56210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
56310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    /* Initialize default strings */
56410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strcpy(vmlinux, "--no-vmlinux");
56510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    strcpy(kernel_range, "");
56610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
56773f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind    setup_device();
56873f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind
56910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    while (1) {
57087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        int c = getopt_long(argc, argv, "c:e:v:r:dhVtl:", long_options, &option_index);
57110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (c == -1) {
57210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            break;
57310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
57410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        switch (c) {
57510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 0:
57610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
577751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --callgraph */
578751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'c':
57987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                strncpy(callgraph, optarg, sizeof(callgraph));
580751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
58110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --event */
58210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'e':
5835a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                if (num_events == MAX_EVENTS) {
5845a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                    fprintf(stderr, "More than %d events specified\n",
5855a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng                            MAX_EVENTS);
58610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    exit(1);
58710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
58810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (process_event(optarg)) {
58910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    exit(1);
59010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
59110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
59210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --vmlinux */
59310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'v':
59410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                sprintf(vmlinux, "-k %s", optarg);
59510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
59610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --kernel-range */
59710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'r':
59810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                sprintf(kernel_range, "-r %s", optarg);
59910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
600751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'd':
601751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --dump */ {
602751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                int pid = read_num(OP_DATA_DIR"/lock");
603751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                echo_dev("1", 0, "dump", -1);
604751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
605751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            }
60610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --shutdown */
60710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 'h': {
60810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int pid = read_num(OP_DATA_DIR"/lock");
60910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (pid >= 0) {
610751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    kill(pid, SIGHUP); /* Politely ask the daemon to close files */
611751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    sleep(1);
612751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    kill(pid, SIGTERM);/* Politely ask the daemon to die */
613751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                    sleep(1);
61410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    kill(pid, SIGKILL);
61587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                }
61610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                setup_session_dir();
61710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
61810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
619751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            /* --verbose */
620751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            case 'V':
621751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                verbose_print++;
622751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                break;
62387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            /* --verbose-log */
62487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            case 'l':
62587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                verbose_log = strdup(optarg);
62687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                break;
62710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* --status */
62810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            case 't':
62987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                show_status = true;
63010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                break;
63110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            default:
63210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                usage();
63310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
63410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
63510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
63610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("list_events = %d\n", list_events);
63710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    verbose("setup = %d\n", setup);
63810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
63910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (list_events) {
64010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        do_list_events();
64110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
64210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
64310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (quick) {
64473f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind        process_event(default_event);
64510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        setup = 1;
64610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
64710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
648a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    if (timer) {
649a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        setup = 1;
650a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    }
651a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng
65210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (reset) {
65310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        do_reset();
65410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
65510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
65610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (show_usage) {
65710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        usage();
65810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
65910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
66010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (setup) {
66110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (do_setup()) {
66210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            fprintf(stderr, "do_setup failed");
66310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            exit(1);
66410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
66510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
66610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
667751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    if (strlen(callgraph)) {
668751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare        echo_dev(callgraph, 0, "backtrace_depth", -1);
669751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare    }
670751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare
671a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng    if (num_events != 0 || timer != 0) {
67287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        char command[1024];
67310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        int i;
67410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
67587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        strcpy(command, argv[0]);
67687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        char* slash = strrchr(command, '/');
67787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        strcpy(slash ? slash + 1 : command, "oprofiled --session-dir="OP_DATA_DIR);
67810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
67973f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind#if defined(__arm__) && !defined(WITH_ARM_V7_A)
68010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Since counter #3 can only handle CPU_CYCLES, check and shuffle the
68110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         * order a bit so that the maximal number of events can be profiled
68210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         * simultaneously
68310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project         */
68410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (num_events == 3) {
68510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            for (i = 0; i < num_events; i++) {
68610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int event_idx = selected_events[i];
68710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
68810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                if (event_info[event_idx].id == 0xff) {
68910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                    break;
69010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                }
69110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
69210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
69310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* No CPU_CYCLES is found */
69410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (i == 3) {
69510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "You can only specify three events if one of "
69610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                                "them is CPU_CYCLES\n");
69710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
69810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
69910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* Swap CPU_CYCLES to counter #2 (starting from #0)*/
70010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            else if (i != 2) {
70110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                int temp;
70210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
70310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                temp = selected_events[2];
70410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_events[2] = selected_events[i];
70510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_events[i] = temp;
70610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
70710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                temp = selected_counts[2];
70810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_counts[2] = selected_counts[i];
70910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                selected_counts[i] = temp;
71010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
71110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
7125a4eb4eb367eccd4b976d1feae96cea96d2c50f2Ben Cheng#endif
71310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
71410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        /* Configure the counters and enable them */
71510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        for (i = 0; i < num_events; i++) {
71610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            int event_idx = selected_events[i];
71710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            int setup_result = 0;
71810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
71910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (i == 0) {
72087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                snprintf(command + strlen(command), sizeof(command) - strlen(command),
72187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                        " --events=");
72287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            } else {
72387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                snprintf(command + strlen(command), sizeof(command) - strlen(command), ",");
72410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
72510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            /* Compose name:id:count:unit_mask:kernel:user, something like
72610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project             * --events=CYCLES_DATA_STALL:2:0:200000:0:1:1,....
72710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project             */
72887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
729751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     "%s:%d:%d:%d:%d:1:1",
73010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     event_info[event_idx].name,
73110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     event_info[event_idx].id,
73210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                     i,
733751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     selected_counts[i],
734751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare                     event_info[event_idx].um);
73510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
73610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "user", i);
73710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "kernel", i);
738751a4435c3ef705b0e31faa14c75b9e2fd859959Bruce Beare            setup_result |= echo_dev(NULL, event_info[event_idx].um, "unit_mask", i);
73910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev("1", 0, "enabled", i);
74010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev(NULL, selected_counts[i], "count", i);
74110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            setup_result |= echo_dev(NULL, event_info[event_idx].id,
74210e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                                     "event", i);
74310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            if (setup_result) {
74410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "Counter configuration failed for %s\n",
74510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                        event_info[event_idx].name);
74610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                fprintf(stderr, "Did you do \"opcontrol --setup\" first?\n");
74710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project                exit(1);
74810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project            }
74910e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
75010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
751a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        if (timer == 0) {
752a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            /* If not in timer mode, disable unused counters */
75373f45fe6aeb2ac4c67c405c6cd4cfe97f0b07b72Paul Lind            for (i = num_events; i < max_events; i++) {
754a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng                echo_dev("0", 0, "enabled", i);
755a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            }
756a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng        } else {
757a9404b820caf434bba3c3c54c5e786a0eb9ebedbBen Cheng            /* Timer mode uses empty event list */
75887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
75987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " --events=");
76010e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
76110e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
76287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        snprintf(command + strlen(command), sizeof(command) - strlen(command),
76387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                " %s", vmlinux);
76410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        if (kernel_range[0]) {
76587866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
76687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " %s", kernel_range);
76710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        }
76887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
76987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (verbose_log) {
77087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            snprintf(command + strlen(command), sizeof(command) - strlen(command),
77187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown                    " --verbose=%s", verbose_log);
77287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
77387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
77487866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        printf("Starting oprofiled...\n");
77510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        verbose("command: %s\n", command);
77687866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
77787866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        int rc = system(command);
77887866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        if (rc) {
77987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            fprintf(stderr, "Failed, oprofile returned exit code: %d\n", rc);
78087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        } else {
78187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            sleep(2);
78287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown            printf("Ready\n");
78387866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        }
78410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
78510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
78610e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (start) {
78710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        echo_dev("1", 0, "enable", -1);
788529d868851ce83328c89429d256e68afe320c51dBen Cheng        int num = read_num(OP_DATA_DIR"/lock");
789529d868851ce83328c89429d256e68afe320c51dBen Cheng
790529d868851ce83328c89429d256e68afe320c51dBen Cheng        if (num >= 0) {
791529d868851ce83328c89429d256e68afe320c51dBen Cheng            kill(num, SIGUSR1);
792529d868851ce83328c89429d256e68afe320c51dBen Cheng        }
79310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
79410e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project
79510e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    if (stop) {
796afec5b915f91a233f37047c29de9531be001778aBen Cheng        echo_dev("1", 0, "dump", -1);
79710e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project        echo_dev("0", 0, "enable", -1);
79810e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project    }
79987866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown
80087866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    if (show_status) {
80187866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown        do_status();
80287866d93bd7de46ffe9333437e5230c6eda58448Jeff Brown    }
80310e23eebca4175a8dfe3a788b2bebacb1fcfce54The Android Open Source Project}
804