blob: 16fc20e0bd8807e9bc4c33e90a427a4864b6945d [file] [log] [blame]
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +08001/*
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +08002 * Copyright (C) 2019 The Android Open Source Project
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +08003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17#define LOG_TAG "perfstatsd"
18
19#include <perfstatsd.h>
20#include <perfstatsd_service.h>
21
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080022enum MODE { DUMP_HISTORY, SET_OPTION };
23
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080024android::sp<Perfstatsd> perfstatsdSp;
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080025
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080026void *perfstatsdMain(void *) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -080027 LOG(INFO) << "main thread started";
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080028 perfstatsdSp = new Perfstatsd();
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080029
30 while (true) {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080031 perfstatsdSp->refresh();
32 perfstatsdSp->pause();
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080033 }
34 return NULL;
35}
36
37void help(char **argv) {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080038 std::string usage = argv[0];
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080039 usage = "Usage: " + usage + " [-s][-d][-o]\n" +
40 "Options:\n"
41 " -s, start as service\n"
42 " -d, dump perf stats history for dumpstate_board\n"
43 " -o, set key/value option";
44
45 fprintf(stderr, "%s\n", usage.c_str());
46}
47
48int startService(void) {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080049 pthread_t perfstatsdMainThread;
50 errno = pthread_create(&perfstatsdMainThread, NULL, perfstatsdMain, NULL);
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080051 if (errno != 0) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -080052 PLOG(ERROR) << "Failed to create main thread";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080053 return -1;
54 } else {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080055 pthread_setname_np(perfstatsdMainThread, "perfstatsd_main");
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080056 }
57
58 android::ProcessState::initWithDriver("/dev/vndbinder");
59
60 if (PerfstatsdPrivateService::start() != android::OK) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -080061 PLOG(ERROR) << "Failed to start perfstatsd service";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080062 return -1;
63 } else
Tom Cherry4a2c84c2020-01-10 17:09:45 -080064 LOG(INFO) << "perfstatsd_pri_service started";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080065
66 android::ProcessState::self()->startThreadPool();
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080067 android::IPCThreadState::self()->joinThreadPool();
68 pthread_join(perfstatsdMainThread, NULL);
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080069 return 0;
70}
71
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080072int serviceCall(int mode, const std::string &key, const std::string &value) {
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080073 android::ProcessState::initWithDriver("/dev/vndbinder");
74
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080075 android::sp<IPerfstatsdPrivate> perfstatsdPrivateService = getPerfstatsdPrivateService();
76 if (perfstatsdPrivateService == NULL) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -080077 PLOG(ERROR) << "Cannot find perfstatsd service.";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080078 fprintf(stdout, "Cannot find perfstatsd service.\n");
79 return -1;
80 }
81
82 switch (mode) {
83 case DUMP_HISTORY: {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080084 std::string history;
Tom Cherry4a2c84c2020-01-10 17:09:45 -080085 LOG(INFO) << "dump perfstats history.";
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080086 if (!perfstatsdPrivateService->dumpHistory(&history).isOk() || history.empty()) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -080087 PLOG(ERROR) << "perf stats history is not available";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080088 fprintf(stdout, "perf stats history is not available\n");
89 return -1;
90 }
91 fprintf(stdout, "%s\n", history.c_str());
92 break;
93 }
94 case SET_OPTION:
Tom Cherry4a2c84c2020-01-10 17:09:45 -080095 LOG(INFO) << "set option: " << key << " , " << value;
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +080096 if (!perfstatsdPrivateService
97 ->setOptions(std::forward<const std::string>(key),
98 std::forward<const std::string>(value))
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +080099 .isOk()) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -0800100 PLOG(ERROR) << "fail to set options";
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +0800101 fprintf(stdout, "fail to set options\n");
102 return -1;
103 }
104 break;
105 }
106 return 0;
107}
108
109int serviceCall(int mode) {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +0800110 std::string empty("");
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +0800111 return serviceCall(mode, empty, empty);
112}
113
114int main(int argc, char **argv) {
Tom Cherry4a2c84c2020-01-10 17:09:45 -0800115 android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
116
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +0800117 int c;
118 while ((c = getopt(argc, argv, "sdo:h")) != -1) {
119 switch (c) {
120 case 's':
121 return startService();
122 case 'd':
123 return serviceCall(DUMP_HISTORY);
124 case 'o':
125 // set options
126 if (argc == 4) {
Charles(Yen-Cheng) Chanbe3368a2019-01-10 16:39:54 +0800127 std::string key(argv[2]);
128 std::string value(argv[3]);
Charles(Yen-Cheng) Chan08bfed82019-01-02 12:26:16 +0800129 return serviceCall(SET_OPTION, std::move(key), std::move(value));
130 }
131 FALLTHROUGH_INTENDED;
132 case 'h':
133 // print usage
134 FALLTHROUGH_INTENDED;
135 default:
136 help(argv);
137 return 2;
138 }
139 }
140 return 0;
141}