1 /*
2 * Copyright (C) 2019 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #define LOG_TAG "perfstatsd"
18
19 #include <perfstatsd.h>
20 #include <perfstatsd_service.h>
21
22 enum MODE { DUMP_HISTORY, SET_OPTION };
23
24 android::sp<Perfstatsd> perfstatsdSp;
25
perfstatsdMain(void *)26 void *perfstatsdMain(void *) {
27 LOG(INFO) << "main thread started";
28 perfstatsdSp = new Perfstatsd();
29
30 while (true) {
31 perfstatsdSp->refresh();
32 perfstatsdSp->pause();
33 }
34 return NULL;
35 }
36
help(char ** argv)37 void help(char **argv) {
38 std::string usage = argv[0];
39 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
startService(void)48 int startService(void) {
49 pthread_t perfstatsdMainThread;
50 errno = pthread_create(&perfstatsdMainThread, NULL, perfstatsdMain, NULL);
51 if (errno != 0) {
52 PLOG(ERROR) << "Failed to create main thread";
53 return -1;
54 } else {
55 pthread_setname_np(perfstatsdMainThread, "perfstatsd_main");
56 }
57
58 android::ProcessState::initWithDriver("/dev/vndbinder");
59
60 if (PerfstatsdPrivateService::start() != android::OK) {
61 PLOG(ERROR) << "Failed to start perfstatsd service";
62 return -1;
63 } else
64 LOG(INFO) << "perfstatsd_pri_service started";
65
66 android::ProcessState::self()->startThreadPool();
67 android::IPCThreadState::self()->joinThreadPool();
68 pthread_join(perfstatsdMainThread, NULL);
69 return 0;
70 }
71
serviceCall(int mode,const std::string & key,const std::string & value)72 int serviceCall(int mode, const std::string &key, const std::string &value) {
73 android::ProcessState::initWithDriver("/dev/vndbinder");
74
75 android::sp<IPerfstatsdPrivate> perfstatsdPrivateService = getPerfstatsdPrivateService();
76 if (perfstatsdPrivateService == NULL) {
77 PLOG(ERROR) << "Cannot find perfstatsd service.";
78 fprintf(stdout, "Cannot find perfstatsd service.\n");
79 return -1;
80 }
81
82 switch (mode) {
83 case DUMP_HISTORY: {
84 std::string history;
85 LOG(INFO) << "dump perfstats history.";
86 if (!perfstatsdPrivateService->dumpHistory(&history).isOk() || history.empty()) {
87 PLOG(ERROR) << "perf stats history is not available";
88 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:
95 LOG(INFO) << "set option: " << key << " , " << value;
96 if (!perfstatsdPrivateService
97 ->setOptions(std::forward<const std::string>(key),
98 std::forward<const std::string>(value))
99 .isOk()) {
100 PLOG(ERROR) << "fail to set options";
101 fprintf(stdout, "fail to set options\n");
102 return -1;
103 }
104 break;
105 }
106 return 0;
107 }
108
serviceCall(int mode)109 int serviceCall(int mode) {
110 std::string empty("");
111 return serviceCall(mode, empty, empty);
112 }
113
main(int argc,char ** argv)114 int main(int argc, char **argv) {
115 android::base::InitLogging(argv, android::base::LogdLogger(android::base::SYSTEM));
116
117 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) {
127 std::string key(argv[2]);
128 std::string value(argv[3]);
129 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 }
142