Merge tag 'v3.10.46' into linux-linaro-lsk
[firefly-linux-kernel-4.4.55.git] / tools / gator / daemon / SessionData.cpp
1 /**
2  * Copyright (C) ARM Limited 2010-2014. All rights reserved.
3  *
4  * This program is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License version 2 as
6  * published by the Free Software Foundation.
7  */
8
9 #include "SessionData.h"
10
11 #include <string.h>
12
13 #include "SessionXML.h"
14 #include "Logging.h"
15
16 SessionData* gSessionData = NULL;
17
18 SessionData::SessionData() {
19         initialize();
20 }
21
22 SessionData::~SessionData() {
23 }
24
25 void SessionData::initialize() {
26         mWaitingOnCommand = false;
27         mSessionIsActive = false;
28         mLocalCapture = false;
29         mOneShot = false;
30         readCpuInfo();
31         mConfigurationXMLPath = NULL;
32         mSessionXMLPath = NULL;
33         mEventsXMLPath = NULL;
34         mTargetPath = NULL;
35         mAPCDir = NULL;
36         mSampleRate = 0;
37         mLiveRate = 0;
38         mDuration = 0;
39         mBacktraceDepth = 0;
40         mTotalBufferSize = 0;
41         // sysconf(_SC_NPROCESSORS_CONF) is unreliable on 2.6 Android, get the value from the kernel module
42         mCores = 1;
43         mPageSize = 0;
44 }
45
46 void SessionData::parseSessionXML(char* xmlString) {
47         SessionXML session(xmlString);
48         session.parse();
49
50         // Set session data values - use prime numbers just below the desired value to reduce the chance of events firing at the same time
51         if (strcmp(session.parameters.sample_rate, "high") == 0) {
52                 mSampleRate = 9973; // 10000
53         } else if (strcmp(session.parameters.sample_rate, "normal") == 0) {
54                 mSampleRate = 997; // 1000
55         } else if (strcmp(session.parameters.sample_rate, "low") == 0) {
56                 mSampleRate = 97; // 100
57         } else if (strcmp(session.parameters.sample_rate, "none") == 0) {
58                 mSampleRate = 0;
59         } else {
60                 logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
61                 handleException();
62         }
63         mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0;
64         mDuration = session.parameters.duration;
65
66         // Determine buffer size (in MB) based on buffer mode
67         mOneShot = true;
68         if (strcmp(session.parameters.buffer_mode, "streaming") == 0) {
69                 mOneShot = false;
70                 mTotalBufferSize = 1;
71         } else if (strcmp(session.parameters.buffer_mode, "small") == 0) {
72                 mTotalBufferSize = 1;
73         } else if (strcmp(session.parameters.buffer_mode, "normal") == 0) {
74                 mTotalBufferSize = 4;
75         } else if (strcmp(session.parameters.buffer_mode, "large") == 0) {
76                 mTotalBufferSize = 16;
77         } else {
78                 logg->logError(__FILE__, __LINE__, "Invalid value for buffer mode in session xml.");
79                 handleException();
80         }
81
82         mImages = session.parameters.images;
83         // Convert milli- to nanoseconds
84         mLiveRate = session.parameters.live_rate * (int64_t)1000000;
85         if (mLiveRate > 0 && mLocalCapture) {
86                 logg->logMessage("Local capture is not compatable with live, disabling live");
87                 mLiveRate = 0;
88         }
89 }
90
91 void SessionData::readCpuInfo() {
92         char temp[256]; // arbitrarily large amount
93         strcpy(mCoreName, "unknown");
94         memset(&mCpuIds, -1, sizeof(mCpuIds));
95         mMaxCpuId = -1;
96
97         FILE* f = fopen("/proc/cpuinfo", "r");  
98         if (f == NULL) {
99                 logg->logMessage("Error opening /proc/cpuinfo\n"
100                         "The core name in the captured xml file will be 'unknown'.");
101                 return;
102         }
103
104         bool foundCoreName = false;
105         int processor = 0;
106         while (fgets(temp, sizeof(temp), f)) {
107                 if (strlen(temp) > 0) {
108                         temp[strlen(temp) - 1] = 0;     // Replace the line feed with a null
109                 }
110
111                 const bool foundHardware = strstr(temp, "Hardware") != 0;
112                 const bool foundCPUPart = strstr(temp, "CPU part") != 0;
113                 const bool foundProcessor = strstr(temp, "processor") != 0;
114                 if (foundHardware || foundCPUPart || foundProcessor) {
115                         char* position = strchr(temp, ':');
116                         if (position == NULL || (unsigned int)(position - temp) + 2 >= strlen(temp)) {
117                                 logg->logMessage("Unknown format of /proc/cpuinfo\n"
118                                         "The core name in the captured xml file will be 'unknown'.");
119                                 return;
120                         }
121                         position += 2;
122
123                         if (foundHardware) {
124                                 strncpy(mCoreName, position, sizeof(mCoreName));
125                                 mCoreName[sizeof(mCoreName) - 1] = 0; // strncpy does not guarantee a null-terminated string
126                                 foundCoreName = true;
127                         }
128
129                         if (foundCPUPart) {
130                                 mCpuIds[processor] = strtol(position, NULL, 0);
131                                 // If this does not have the full topology in /proc/cpuinfo, mCpuIds[0] may not have the 1 CPU part emitted - this guarantees it's in mMaxCpuId
132                                 if (mCpuIds[processor] > mMaxCpuId) {
133                                         mMaxCpuId = mCpuIds[processor];
134                                 }
135                         }
136
137                         if (foundProcessor) {
138                                 processor = strtol(position, NULL, 0);
139                         }
140                 }
141         }
142
143         if (!foundCoreName) {
144                 logg->logMessage("Could not determine core name from /proc/cpuinfo\n"
145                                                  "The core name in the captured xml file will be 'unknown'.");
146         }
147         fclose(f);
148  }
149
150 int getEventKey() {
151         // key 0 is reserved as a timestamp
152         // key 1 is reserved as the marker for thread specific counters
153         // Odd keys are assigned by the driver, even keys by the daemon
154         static int key = 2;
155
156         const int ret = key;
157         key += 2;
158         return ret;
159 }