blob: 14d995fc39fad2507616c05d572ef8f435c1bcea [file] [log] [blame]
Jon Medhurstaaf37a32013-06-11 12:10:56 +01001/**
Jon Medhurst15ce78d2014-04-10 09:02:02 +01002 * Copyright (C) ARM Limited 2010-2014. All rights reserved.
Jon Medhurstaaf37a32013-06-11 12:10:56 +01003 *
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
Jon Medhurstaaf37a32013-06-11 12:10:56 +01009#include "SessionData.h"
Jon Medhurst15ce78d2014-04-10 09:02:02 +010010
11#include <string.h>
Jon Medhurste31266f2014-08-04 15:47:44 +010012#include <sys/mman.h>
Jon Medhurst15ce78d2014-04-10 09:02:02 +010013
Jon Medhurstaaf37a32013-06-11 12:10:56 +010014#include "SessionXML.h"
15#include "Logging.h"
16
17SessionData* gSessionData = NULL;
18
19SessionData::SessionData() {
20 initialize();
21}
22
23SessionData::~SessionData() {
24}
25
26void SessionData::initialize() {
27 mWaitingOnCommand = false;
28 mSessionIsActive = false;
29 mLocalCapture = false;
30 mOneShot = false;
Jon Medhurste31266f2014-08-04 15:47:44 +010031 mSentSummary = false;
32 const size_t cpuIdSize = sizeof(int)*NR_CPUS;
33 // Share mCpuIds across all instances of gatord
34 mCpuIds = (int *)mmap(NULL, cpuIdSize, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANONYMOUS, -1, 0);
35 if (mCpuIds == MAP_FAILED) {
36 logg->logError(__FILE__, __LINE__, "Unable to mmap shared memory for cpuids");
37 handleException();
38 }
39 memset(mCpuIds, -1, cpuIdSize);
Jon Medhurstaaf37a32013-06-11 12:10:56 +010040 readCpuInfo();
41 mConfigurationXMLPath = NULL;
42 mSessionXMLPath = NULL;
43 mEventsXMLPath = NULL;
44 mTargetPath = NULL;
45 mAPCDir = NULL;
46 mSampleRate = 0;
47 mLiveRate = 0;
48 mDuration = 0;
49 mBacktraceDepth = 0;
50 mTotalBufferSize = 0;
51 // sysconf(_SC_NPROCESSORS_CONF) is unreliable on 2.6 Android, get the value from the kernel module
52 mCores = 1;
Jon Medhurst15ce78d2014-04-10 09:02:02 +010053 mPageSize = 0;
Jon Medhurstaaf37a32013-06-11 12:10:56 +010054}
55
56void SessionData::parseSessionXML(char* xmlString) {
57 SessionXML session(xmlString);
58 session.parse();
59
Jon Medhurst34d97692013-12-19 09:23:06 +000060 // Set session data values - use prime numbers just below the desired value to reduce the chance of events firing at the same time
Jon Medhurstaaf37a32013-06-11 12:10:56 +010061 if (strcmp(session.parameters.sample_rate, "high") == 0) {
Jon Medhurst34d97692013-12-19 09:23:06 +000062 mSampleRate = 9973; // 10000
Jon Medhurstaaf37a32013-06-11 12:10:56 +010063 } else if (strcmp(session.parameters.sample_rate, "normal") == 0) {
Jon Medhurst34d97692013-12-19 09:23:06 +000064 mSampleRate = 997; // 1000
Jon Medhurstaaf37a32013-06-11 12:10:56 +010065 } else if (strcmp(session.parameters.sample_rate, "low") == 0) {
Jon Medhurst34d97692013-12-19 09:23:06 +000066 mSampleRate = 97; // 100
Jon Medhurstaaf37a32013-06-11 12:10:56 +010067 } else if (strcmp(session.parameters.sample_rate, "none") == 0) {
68 mSampleRate = 0;
69 } else {
70 logg->logError(__FILE__, __LINE__, "Invalid sample rate (%s) in session xml.", session.parameters.sample_rate);
71 handleException();
72 }
73 mBacktraceDepth = session.parameters.call_stack_unwinding == true ? 128 : 0;
74 mDuration = session.parameters.duration;
75
76 // Determine buffer size (in MB) based on buffer mode
77 mOneShot = true;
78 if (strcmp(session.parameters.buffer_mode, "streaming") == 0) {
79 mOneShot = false;
80 mTotalBufferSize = 1;
81 } else if (strcmp(session.parameters.buffer_mode, "small") == 0) {
82 mTotalBufferSize = 1;
83 } else if (strcmp(session.parameters.buffer_mode, "normal") == 0) {
84 mTotalBufferSize = 4;
85 } else if (strcmp(session.parameters.buffer_mode, "large") == 0) {
86 mTotalBufferSize = 16;
87 } else {
88 logg->logError(__FILE__, __LINE__, "Invalid value for buffer mode in session xml.");
89 handleException();
90 }
91
92 mImages = session.parameters.images;
93 // Convert milli- to nanoseconds
94 mLiveRate = session.parameters.live_rate * (int64_t)1000000;
95 if (mLiveRate > 0 && mLocalCapture) {
96 logg->logMessage("Local capture is not compatable with live, disabling live");
97 mLiveRate = 0;
98 }
99}
100
101void SessionData::readCpuInfo() {
102 char temp[256]; // arbitrarily large amount
103 strcpy(mCoreName, "unknown");
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100104 mMaxCpuId = -1;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100105
Jon Medhurste31266f2014-08-04 15:47:44 +0100106 FILE* f = fopen("/proc/cpuinfo", "r");
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100107 if (f == NULL) {
108 logg->logMessage("Error opening /proc/cpuinfo\n"
109 "The core name in the captured xml file will be 'unknown'.");
110 return;
111 }
112
113 bool foundCoreName = false;
Jon Medhurste31266f2014-08-04 15:47:44 +0100114 int processor = -1;
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100115 while (fgets(temp, sizeof(temp), f)) {
Jon Medhurste31266f2014-08-04 15:47:44 +0100116 const size_t len = strlen(temp);
117
118 if (len == 1) {
119 // New section, clear the processor. Streamline will not know the cpus if the pre Linux 3.8 format of cpuinfo is encountered but also that no incorrect information will be transmitted.
120 processor = -1;
121 continue;
122 }
123
124 if (len > 0) {
125 temp[len - 1] = '\0'; // Replace the line feed with a null
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100126 }
127
128 const bool foundHardware = strstr(temp, "Hardware") != 0;
129 const bool foundCPUPart = strstr(temp, "CPU part") != 0;
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100130 const bool foundProcessor = strstr(temp, "processor") != 0;
131 if (foundHardware || foundCPUPart || foundProcessor) {
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100132 char* position = strchr(temp, ':');
133 if (position == NULL || (unsigned int)(position - temp) + 2 >= strlen(temp)) {
134 logg->logMessage("Unknown format of /proc/cpuinfo\n"
135 "The core name in the captured xml file will be 'unknown'.");
136 return;
137 }
138 position += 2;
139
140 if (foundHardware) {
141 strncpy(mCoreName, position, sizeof(mCoreName));
142 mCoreName[sizeof(mCoreName) - 1] = 0; // strncpy does not guarantee a null-terminated string
143 foundCoreName = true;
144 }
145
146 if (foundCPUPart) {
Jon Medhurste31266f2014-08-04 15:47:44 +0100147 const int cpuId = strtol(position, NULL, 0);
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100148 // 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
Jon Medhurste31266f2014-08-04 15:47:44 +0100149 if (cpuId > mMaxCpuId) {
150 mMaxCpuId = cpuId;
151 }
152 if (processor >= NR_CPUS) {
153 logg->logMessage("Too many processors, please increase NR_CPUS");
154 } else if (processor >= 0) {
155 mCpuIds[processor] = cpuId;
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100156 }
Jon Medhurst15ce78d2014-04-10 09:02:02 +0100157 }
158
159 if (foundProcessor) {
160 processor = strtol(position, NULL, 0);
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100161 }
162 }
163 }
164
165 if (!foundCoreName) {
166 logg->logMessage("Could not determine core name from /proc/cpuinfo\n"
Jon Medhurste31266f2014-08-04 15:47:44 +0100167 "The core name in the captured xml file will be 'unknown'.");
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100168 }
169 fclose(f);
Jon Medhurste31266f2014-08-04 15:47:44 +0100170}
171
172uint64_t getTime() {
173 struct timespec ts;
174#ifndef CLOCK_MONOTONIC_RAW
175 // Android doesn't have this defined but it was added in Linux 2.6.28
176#define CLOCK_MONOTONIC_RAW 4
177#endif
178 if (clock_gettime(CLOCK_MONOTONIC_RAW, &ts) != 0) {
179 logg->logError(__FILE__, __LINE__, "Failed to get uptime");
180 handleException();
181 }
182 return (NS_PER_S*ts.tv_sec + ts.tv_nsec);
183}
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100184
185int getEventKey() {
Jon Medhurst34d97692013-12-19 09:23:06 +0000186 // key 0 is reserved as a timestamp
187 // key 1 is reserved as the marker for thread specific counters
188 // Odd keys are assigned by the driver, even keys by the daemon
Jon Medhurstaaf37a32013-06-11 12:10:56 +0100189 static int key = 2;
190
191 const int ret = key;
192 key += 2;
193 return ret;
194}