thermal-hal: Update the common data object with the status

thermal-hal has a hash map storing all the sensor instances. Use the same
instance to read and update the temperature, update the severity and
determine the next threshold based on severity. Not using the same
instance can lead to a situation where the information is updated in the
local copy rather than in the global copy in the hash map.

Also change the return signature of the estimateseverity function to
return the new severity value if it is changed. Otherwise it will return
-1. This provided a mechanism for the caller's to know if there is any
change in severity for that sensor.

Change-Id: I34c2a271b505fea969db6f4a04321e63c0181ea7
diff --git a/thermalCommon.cpp b/thermalCommon.cpp
index 2a3ec38..638b3b6 100644
--- a/thermalCommon.cpp
+++ b/thermalCommon.cpp
@@ -113,14 +113,14 @@
 	return -1;
 }
 
-static int readLineFromFile(std::string_view path, std::string *out)
+static int readLineFromFile(std::string_view path, std::string& out)
 {
 	char *fgets_ret;
 	FILE *fd;
 	int rv;
 	char buf[MAX_LENGTH];
 
-	out->clear();
+	out.clear();
 
 	fd = fopen(std::string(path).c_str(), "r");
 	if (fd == NULL) {
@@ -132,19 +132,19 @@
 	fgets_ret = fgets(buf, MAX_LENGTH, fd);
 	if (NULL != fgets_ret) {
 		rv = (int)strlen(buf);
-		out->append(buf, rv);
+		out.append(buf, rv);
 	} else {
 		rv = ferror(fd);
 	}
 
 	fclose(fd);
-	out->erase(std::remove(out->begin(), out->end(), '\n'), out->end());
-	LOG(DEBUG) << "Path:" << std::string(path) << " Val:" << *out << std::endl;
+	out.erase(std::remove(out.begin(), out.end(), '\n'), out.end());
+	LOG(DEBUG) << "Path:" << std::string(path) << " Val:" << out << std::endl;
 
 	return rv;
 }
 
-int ThermalCommon::readFromFile(std::string_view path, std::string *out)
+int ThermalCommon::readFromFile(std::string_view path, std::string& out)
 {
 	return readLineFromFile(path, out);
 }
@@ -183,7 +183,7 @@
 
 		snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
 				tdirent->d_name, TZ_TYPE);
-		ret = readLineFromFile(std::string_view(name), &buf);
+		ret = readLineFromFile(std::string_view(name), buf);
 		if (ret <= 0) {
 			LOG(ERROR) <<
 				"get_tzn: sensor name read error for tz:" <<
@@ -211,7 +211,7 @@
 	return found;
 }
 
-int ThermalCommon::initialize_sensor(struct target_therm_cfg cfg, int sens_idx)
+int ThermalCommon::initialize_sensor(struct target_therm_cfg& cfg, int sens_idx)
 {
 	struct therm_sensor sensor;
 	int idx = 0;
@@ -270,7 +270,7 @@
 	return 0;
 }
 
-int ThermalCommon::initializeCpuSensor(struct target_therm_cfg cpu_cfg)
+int ThermalCommon::initializeCpuSensor(struct target_therm_cfg& cpu_cfg)
 {
 	int cpu = 0;
 
@@ -282,7 +282,7 @@
 	return 0;
 }
 
-int ThermalCommon::initThermalZones(std::vector<struct target_therm_cfg> cfg)
+int ThermalCommon::initThermalZones(std::vector<struct target_therm_cfg>& cfg)
 {
 	std::vector<struct target_therm_cfg>::iterator it;
 
@@ -342,7 +342,7 @@
 
 		snprintf(name, MAX_PATH, "%s%s/%s", THERMAL_SYSFS,
 				tdirent->d_name, TZ_TYPE);
-		ret = readLineFromFile(std::string_view(name), &buf);
+		ret = readLineFromFile(std::string_view(name), buf);
 		if (ret <= 0) {
 			LOG(ERROR) <<
 				"init_cdev: cdev type read error for cdev:" <<
@@ -357,7 +357,7 @@
 		cdevInst.c.name = it->first;
 		cdevInst.c.type = it->second;
 		cdevInst.cdevn = cdevn;
-		read_cdev_state(&cdevInst);
+		read_cdev_state(cdevInst);
 		cdev.push_back(cdevInst);
 	}
 
@@ -368,7 +368,7 @@
 	return cdev.size();
 }
 
-int ThermalCommon::read_cdev_state(struct therm_cdev *cdev)
+int ThermalCommon::read_cdev_state(struct therm_cdev& cdev)
 {
 	char file_name[MAX_PATH];
 	std::string buf;
@@ -376,51 +376,68 @@
 
 	LOG(DEBUG) << "Entering " <<__func__;
 	snprintf(file_name, sizeof(file_name), CDEV_CUR_STATE_PATH,
-			cdev->cdevn);
-	ret = readLineFromFile(std::string(file_name), &buf);
+			cdev.cdevn);
+	ret = readLineFromFile(std::string(file_name), buf);
 	if (ret <= 0) {
 		LOG(ERROR) << "Cdev state read error:"<< ret <<
-			" for cdev: " << cdev->c.name;
+			" for cdev: " << cdev.c.name;
 		return -1;
 	}
-	cdev->c.value = std::stoi(buf);
-	LOG(DEBUG) << "cdev Name:" << cdev->c.name << ". state:" <<
-		cdev->c.value << std::endl;
+	cdev.c.value = std::stoi(buf, nullptr, 0);
+	LOG(DEBUG) << "cdev Name:" << cdev.c.name << ". state:" <<
+		cdev.c.value << std::endl;
 
-	return cdev->c.value;
+	return cdev.c.value;
 }
 
-int ThermalCommon::estimateSeverity(struct therm_sensor *sensor)
+int ThermalCommon::estimateSeverity(struct therm_sensor& sensor)
 {
 	int idx = 0;
 	ThrottlingSeverity severity = ThrottlingSeverity::NONE;
-	float temp = sensor->t.value;
+	float temp = sensor.t.value;
 
 	for (idx = (int)ThrottlingSeverity::SHUTDOWN; idx >= 0; idx--) {
-		if ((sensor->positiveThresh &&
-			!isnan(sensor->thresh.hotThrottlingThresholds[idx]) &&
+		/* If a particular threshold is hit already, check if the
+		 * hysteresis is cleared before changing the severity */
+		if (idx == (int)sensor.t.throttlingStatus) {
+			if ((sensor.positiveThresh &&
+				!isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
+				temp >=
+				(sensor.thresh.hotThrottlingThresholds[idx] -
+				DEFAULT_HYSTERESIS / sensor.mulFactor)) ||
+				(!sensor.positiveThresh &&
+				!isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
+				temp <=
+				(sensor.thresh.coldThrottlingThresholds[idx] +
+				DEFAULT_HYSTERESIS / sensor.mulFactor)))
+				break;
+			continue;
+		}
+		if ((sensor.positiveThresh &&
+			!isnan(sensor.thresh.hotThrottlingThresholds[idx]) &&
 			temp >=
-			sensor->thresh.hotThrottlingThresholds[idx]) ||
-		 	(!sensor->positiveThresh &&
-			!isnan(sensor->thresh.coldThrottlingThresholds[idx]) &&
+			sensor.thresh.hotThrottlingThresholds[idx]) ||
+		 	(!sensor.positiveThresh &&
+			!isnan(sensor.thresh.coldThrottlingThresholds[idx]) &&
 			temp <=
-			sensor->thresh.coldThrottlingThresholds[idx]))
+			sensor.thresh.coldThrottlingThresholds[idx]))
 			break;
 	}
 	if (idx >= 0)
 		severity = (ThrottlingSeverity)(idx);
-	LOG(DEBUG) << "Sensor Name:" << sensor->t.name << ". old severity:" <<
-		(int)sensor->t.throttlingStatus << " New severity:" <<
+	LOG(DEBUG) << "Sensor Name:" << sensor.t.name << ". prev severity:" <<
+		(int)sensor.lastThrottleStatus << ". cur severity:" <<
+		(int)sensor.t.throttlingStatus << " New severity:" <<
 		(int)severity << std::endl;
-	if (severity == sensor->t.throttlingStatus)
-		return 0;
-	sensor->lastThrottleStatus = sensor->t.throttlingStatus;
-	sensor->t.throttlingStatus = severity;
+	if (severity == sensor.t.throttlingStatus)
+		return -1;
+	sensor.lastThrottleStatus = sensor.t.throttlingStatus;
+	sensor.t.throttlingStatus = severity;
 
-	return 0;
+	return (int)severity;
 }
 
-int ThermalCommon::read_temperature(struct therm_sensor *sensor)
+int ThermalCommon::read_temperature(struct therm_sensor& sensor)
 {
 	char file_name[MAX_PATH];
 	float temp;
@@ -429,21 +446,22 @@
 
 	LOG(DEBUG) << "Entering " <<__func__;
 	snprintf(file_name, sizeof(file_name), TEMPERATURE_FILE_FORMAT,
-			sensor->tzn);
-	ret = readLineFromFile(std::string(file_name), &buf);
+			sensor.tzn);
+	ret = readLineFromFile(std::string(file_name), buf);
 	if (ret <= 0) {
 		LOG(ERROR) << "Temperature read error:"<< ret <<
-			" for sensor " << sensor->t.name;
+			" for sensor " << sensor.t.name;
 		return -1;
 	}
-	sensor->t.value = (float)std::stoi(buf) / (float)sensor->mulFactor;
-	LOG(DEBUG) << "Sensor Name:" << sensor->t.name << ". Temperature:" <<
-		(float)sensor->t.value << std::endl;
+	sensor.t.value = (float)std::stoi(buf, nullptr, 0) / (float)sensor.mulFactor;
+	LOG(DEBUG) << "Sensor Name:" << sensor.t.name << ". Temperature:" <<
+		(float)sensor.t.value << std::endl;
 
-	return estimateSeverity(sensor);
+	estimateSeverity(sensor);
+	return ret;
 }
 
-void ThermalCommon::initThreshold(struct therm_sensor sensor)
+void ThermalCommon::initThreshold(struct therm_sensor& sensor)
 {
 	char file_name[MAX_PATH] = "";
 	std::string buf;
@@ -459,7 +477,7 @@
 	}
 	snprintf(file_name, sizeof(file_name), POLICY_FILE_FORMAT,
 			sensor.tzn);
-	ret = readLineFromFile(std::string(file_name), &buf);
+	ret = readLineFromFile(std::string(file_name), buf);
 	if (ret <= 0) {
 		LOG(ERROR) << "Policy read error:"<< ret <<
 			" for sensor " << sensor.t.name;
diff --git a/thermalCommon.h b/thermalCommon.h
index 4375e1e..6a1b348 100644
--- a/thermalCommon.h
+++ b/thermalCommon.h
@@ -44,14 +44,14 @@
 		ThermalCommon();
 		~ThermalCommon() = default;
 
-		int readFromFile(std::string_view path, std::string *out);
-		int initThermalZones(std::vector<struct target_therm_cfg> cfg);
-		void initThreshold(struct therm_sensor sens);
+		int readFromFile(std::string_view path, std::string& out);
+		int initThermalZones(std::vector<struct target_therm_cfg>& cfg);
+		void initThreshold(struct therm_sensor& sens);
 		int initCdev();
 
-		int read_cdev_state(struct therm_cdev *cdev);
-		int read_temperature(struct therm_sensor *sensor);
-		int estimateSeverity(struct therm_sensor *sensor);
+		int read_cdev_state(struct therm_cdev& cdev);
+		int read_temperature(struct therm_sensor& sensor);
+		int estimateSeverity(struct therm_sensor& sensor);
 		int get_cpu_usages(hidl_vec<CpuUsage>& list);
 
 		std::vector<struct therm_sensor> fetch_sensor_list()
@@ -69,8 +69,8 @@
 		std::vector<struct therm_sensor> sens;
 		std::vector<struct therm_cdev> cdev;
 
-		int initializeCpuSensor(struct target_therm_cfg cpu_cfg);
-		int initialize_sensor(struct target_therm_cfg cfg,
+		int initializeCpuSensor(struct target_therm_cfg& cpu_cfg);
+		int initialize_sensor(struct target_therm_cfg& cfg,
 					int sens_idx);
 };
 
diff --git a/thermalConfig.cpp b/thermalConfig.cpp
index 52d6944..158d5c2 100644
--- a/thermalConfig.cpp
+++ b/thermalConfig.cpp
@@ -564,7 +564,7 @@
 		bool bcl_defined = false;
 		std::string soc_val;
 
-		if (cmnInst.readFromFile(socIDPath, &soc_val) <= 0) {
+		if (cmnInst.readFromFile(socIDPath, soc_val) <= 0) {
 			LOG(ERROR) <<"soc ID fetch error";
 			return;
 		}
diff --git a/thermalUtils.cpp b/thermalUtils.cpp
index 7aaada4..f057e75 100644
--- a/thermalUtils.cpp
+++ b/thermalUtils.cpp
@@ -54,19 +54,19 @@
 {
 	int ret = 0;
 	std::vector<struct therm_sensor> sensorList;
-	std::vector<struct therm_sensor>::iterator it;
+	std::vector<struct target_therm_cfg> therm_cfg = cfg.fetchConfig();
 
 	is_sensor_init = false;
 	is_cdev_init = false;
-	ret = cmnInst.initThermalZones(cfg.fetchConfig());
+	ret = cmnInst.initThermalZones(therm_cfg);
 	if (ret > 0) {
 		is_sensor_init = true;
 		sensorList = cmnInst.fetch_sensor_list();
 		std::lock_guard<std::mutex> _lock(sens_cb_mutex);
-		for (it = sensorList.begin(); it != sensorList.end(); it++) {
-			thermalConfig[it->sensor_name] = *it;
-			cmnInst.read_temperature(&(*it));
-			cmnInst.initThreshold(*it);
+		for (struct therm_sensor sens: sensorList) {
+			thermalConfig[sens.sensor_name] = sens;
+			cmnInst.read_temperature(sens);
+			cmnInst.initThreshold(sens);
 		}
 		monitor.start();
 	}
@@ -79,23 +79,22 @@
 
 void ThermalUtils::ueventParse(std::string sensor_name, int temp)
 {
-	std::unordered_map<std::string, struct therm_sensor>::iterator it;
-	struct therm_sensor sens;
+	int severity = 0;
 
 	LOG(INFO) << "uevent triggered for sensor: " << sensor_name
 		<< std::endl;
-	it = thermalConfig.find(sensor_name);
-	if (it == thermalConfig.end()) {
+	if (thermalConfig.find(sensor_name) == thermalConfig.end()) {
 		LOG(DEBUG) << "sensor is not monitored:" << sensor_name
 			<< std::endl;
 		return;
 	}
-	sens = it->second;
 	std::lock_guard<std::mutex> _lock(sens_cb_mutex);
+	struct therm_sensor& sens = thermalConfig[sensor_name];
 	sens.t.value = (float)temp / (float)sens.mulFactor;
-	cmnInst.estimateSeverity(&sens);
-	if (sens.lastThrottleStatus != sens.t.throttlingStatus) {
-		LOG(INFO) << "sensor: " << sensor_name <<" old: " <<
+	severity = cmnInst.estimateSeverity(sens);
+	if (severity != -1) {
+		LOG(INFO) << "sensor: " << sensor_name <<" temperature: "
+			<< sens.t.value << " old: " <<
 			(int)sens.lastThrottleStatus << " new: " <<
 			(int)sens.t.throttlingStatus << std::endl;
 		cb(sens.t);
@@ -113,13 +112,13 @@
 		return 0;
 	for (it = thermalConfig.begin(); it != thermalConfig.end();
 			it++, idx++) {
-		struct therm_sensor sens = it->second;
+		struct therm_sensor& sens = it->second;
 		Temperature_1_0 _temp;
 
 		/* v1 supports only CPU, GPU, Battery and SKIN */
 		if (sens.t.type > TemperatureType::SKIN)
 			continue;
-		ret = cmnInst.read_temperature(&sens);
+		ret = cmnInst.read_temperature(sens);
 		if (ret < 0)
 			return ret;
 		_temp.currentValue = sens.t.value;
@@ -145,11 +144,11 @@
 	std::vector<Temperature> _temp;
 
 	for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
-		struct therm_sensor sens = it->second;
+		struct therm_sensor& sens = it->second;
 
 		if (filterType && sens.t.type != type)
 			continue;
-		ret = cmnInst.read_temperature(&sens);
+		ret = cmnInst.read_temperature(sens);
 		if (ret < 0)
 			return ret;
 		_temp.push_back(sens.t);
@@ -166,7 +165,7 @@
 	std::vector<TemperatureThreshold> _thresh;
 
 	for (it = thermalConfig.begin(); it != thermalConfig.end(); it++) {
-		struct therm_sensor sens = it->second;
+		struct therm_sensor& sens = it->second;
 
 		if (filterType && sens.t.type != type)
 			continue;
@@ -187,7 +186,7 @@
 
 		if (filterType && cdev.c.type != type)
 			continue;
-		ret = cmnInst.read_cdev_state(&cdev);
+		ret = cmnInst.read_cdev_state(cdev);
 		if (ret < 0)
 			return ret;
 		_cdev.push_back(cdev.c);