191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris/*
291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * Copyright 2013 The Android Open Source Project
391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris *
491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * Licensed under the Apache License, Version 2.0 (the "License");
591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * you may not use this file except in compliance with the License.
691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * You may obtain a copy of the License at
791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris *
891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris *     http://www.apache.org/licenses/LICENSE-2.0
991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris *
1091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * Unless required by applicable law or agreed to in writing, software
1191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * distributed under the License is distributed on an "AS IS" BASIS,
1291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * See the License for the specific language governing permissions and
1491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris * limitations under the License.
1591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris */
1691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
1791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#ifndef __MEMTRACK_H__
1891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#define __MEMTRACK_H__
1991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
2091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#include <sys/types.h>
2191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
2291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#include <map>
2391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#include <string>
2491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#include <vector>
2591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
2691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#define DEFAULT_SLEEP_DELAY_SECONDS 5
2791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#define NS_PER_SEC 1000000000LL
2891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
2991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrisclass FileData {
3091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrispublic:
3191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  FileData(char *filename, char *buffer, size_t buffer_len);
3291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  ~FileData();
3391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
3491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Get the PSS information from the file data. If there are no more
3591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // PSS values to be found, return false.
3691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  bool getPss(size_t *pss);
3791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
3891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Check if there is at least bytes available in the file data.
3991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  bool isAvail(size_t bytes);
4091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
4191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrisprivate:
4291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  int fd_;
4391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  char *data_;
4491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t max_;
4591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t cur_idx_;
4691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t len_;
4791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  bool read_complete_;
4891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris};
4991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
5091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferristypedef struct {
5191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  std::string name;
5291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
5391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t max_num_pids;
5491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
5591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t num_samples;
5691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  double avg_pss_kb;
5791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t min_pss_kb;
5891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t max_pss_kb;
5991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t last_pss_kb;
6091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
6191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  std::vector<int> pids;
6291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris} process_info_t;
6391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferristypedef std::map<std::string, process_info_t> processes_t;
6491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
6591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferristypedef struct {
6691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  size_t pss_kb;
6791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
6891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  std::vector<int> pids;
6991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris} cur_process_info_t;
7091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferristypedef std::map<std::string, cur_process_info_t> cur_processes_t;
7191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
7291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrisclass ProcessInfo {
7391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrispublic:
7491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  ProcessInfo();
7591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  ~ProcessInfo();
7691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
7791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Get the information about a single process.
7891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  bool getInformation(int pid, char *pid_str, size_t pid_str_len);
7991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
8091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Scan all of the running processes.
8191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  void scan();
8291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
8391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Dump the information about all of the processes in the system to the log.
8491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  void dumpToLog();
8591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
8691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferrisprivate:
8791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kBufferLen = 4096;
8891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kCmdNameLen = 1024;
8991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
9091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const char *kProc;
9191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kProcLen = 6;
9291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
9391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const char *kCmdline;
9491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kCmdlineLen = 9;  // Includes \0 at end of string.
9591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
9691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const char *kSmaps;
9791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kSmapsLen = 7;  // Includes \0 at end of string.
9891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
9991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const char *kStatus;
10091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kStatusLen = 8;  // Includes \0 at end of string.
10191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
10291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static const size_t kInitialEntries = 1000;
10391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
10491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  char proc_file_[PATH_MAX];
10591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  char buffer_[kBufferLen];
10691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
10791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  char cmd_name_[kCmdNameLen];
10891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
10991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Minimize a need for a lot of allocations by keeping our maps and
11091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // lists in this object.
11191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  processes_t all_;
11291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  cur_processes_t cur_;
11391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  std::vector<const process_info_t *> list_;
11491f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
11591f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  // Compute a running average.
11691f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  static inline void computeAvg(double *running_avg, size_t cur_avg,
11791f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris                                size_t num_samples) {
11891f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris    *running_avg = (*running_avg/(num_samples+1))*num_samples
11991f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris                   + (double)cur_avg/(num_samples+1);
12091f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris  }
12191f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris};
12291f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris
12391f4410f49f8f701f9001c447b5bc6162c348f6bChristopher Ferris#endif  // __MEMTRACK_H__
124