• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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