int cthd_cdev_rapl_msr::update()
{
	int ret;

	if (!rapl.pkg_domain_present())
		return THD_ERROR;

	if (!rapl.pp0_domain_present())
		return THD_ERROR;

	if (rapl.get_power_unit() < 0)
		return THD_ERROR;

	if (rapl.get_time_unit() < 0)
		return THD_ERROR;

	ret = rapl.get_pkg_power_info(&thermal_spec_power, &max_power, &min_power, &max_time_window);
	if (ret < 0)
		return ret;
	thd_log_debug("Pkg Power Info: Thermal spec %f watts, max %f watts, min %f watts, max time window %f seconds\n", thermal_spec_power, max_power, min_power, max_time_window);

	max_state = 0;

	if (thermal_spec_power > 0)
		phy_max = (int)thermal_spec_power * 1000; // change to milliwatts
	else if(max_power > 0)
		phy_max = (int)max_power * 1000; // // change to milliwatts
	else
		return THD_ERROR;

	set_inc_dec_value(phy_max * (float)rapl_power_dec_percent/100);

	if (inc_dec_val == 0)
		set_inc_dec_value(phy_max * (float)rapl_power_dec_percent*2/100);

	if (inc_dec_val == 0) // power limit is too small
		inc_dec_val = 1;


	max_state = phy_max - ((float)phy_max * rapl_low_limit_percent/100);

	thd_log_debug("RAPL phy_max %d max_state %d inc_dec %d \n", phy_max, max_state, inc_dec_val);

	return THD_SUCCESS;
}
bool cthd_sysfs_cdev_rapl::calculate_phy_max() {
	if (dynamic_phy_max_enable) {
		unsigned int curr_max_phy;
		curr_max_phy = thd_engine->rapl_power_meter.rapl_action_get_power(
				PACKAGE);
		thd_log_debug("curr_phy_max = %u \n", curr_max_phy);
		if (curr_max_phy < rapl_min_default_step)
			return false;
		if (phy_max < curr_max_phy) {
			phy_max = curr_max_phy;
			set_inc_dec_value(phy_max * (float) rapl_power_dec_percent / 100);
			max_state = phy_max;
			max_state -= (float) max_state * rapl_low_limit_percent / 100;
			thd_log_debug("PHY_MAX %lu, step %d, max_state %d\n", phy_max,
					inc_dec_val, max_state);
		}
	}

	return true;
}
int cthd_sysfs_cdev_rapl::update() {
	int i;
	std::stringstream temp_str;
	int _index = -1;
	unsigned long constraint_phy_max;
	bool ppcc = false;
	std::string domain_name;

	for (i = 0; i < rapl_no_time_windows; ++i) {
		temp_str << "constraint_" << i << "_name";
		if (cdev_sysfs.exists(temp_str.str())) {
			std::string type_str;
			cdev_sysfs.read(temp_str.str(), type_str);
			if (type_str == "long_term") {
				_index = i;
				break;
			}
		}
	}
	if (_index < 0) {
		thd_log_info("powercap RAPL no long term time window\n");
		return THD_ERROR;
	}

	cdev_sysfs.read("name", domain_name);
	if (domain_name == "package-0")
		ppcc = read_ppcc_power_limits();

	if (ppcc) {
		phy_max = pl0_max_pwr;
		set_inc_dec_value(pl0_step_pwr);
		max_state = pl0_max_pwr - pl0_min_pwr;
	} else {
		temp_str.str(std::string());
		temp_str << "constraint_" << _index << "_max_power_uw";
		if (!cdev_sysfs.exists(temp_str.str())) {
			thd_log_info("powercap RAPL no max power limit range %s \n",
					temp_str.str().c_str());
			return THD_ERROR;
		}
		if (cdev_sysfs.read(temp_str.str(), &phy_max) < 0) {
			thd_log_info("powercap RAPL invalid max power limit range \n");
			thd_log_info("Calculate dynamically phy_max \n");
			phy_max = 0;
			thd_engine->rapl_power_meter.rapl_start_measure_power();
			max_state = rapl_min_default_step;
			set_inc_dec_value(rapl_min_default_step);
			dynamic_phy_max_enable = true;
			return THD_SUCCESS;
		}

		std::stringstream temp_power_str;
		temp_power_str.str(std::string());
		temp_power_str << "constraint_" << _index << "_power_limit_uw";
		if (!cdev_sysfs.exists(temp_power_str.str())) {
			thd_log_info("powercap RAPL no  power limit uw %s \n",
					temp_str.str().c_str());
			return THD_ERROR;
		}
		if (cdev_sysfs.read(temp_power_str.str(), &constraint_phy_max) <= 0) {
			thd_log_info("powercap RAPL invalid max power limit range \n");
			constraint_phy_max = 0;
		}
		if (constraint_phy_max > phy_max) {
			thd_log_info(
					"Default constraint power limit is more than max power %lu:%lu\n",
					constraint_phy_max, phy_max);
			phy_max = constraint_phy_max;
		}
		thd_log_info("powercap RAPL max power limit range %lu \n", phy_max);

		set_inc_dec_value(phy_max * (float) rapl_power_dec_percent / 100);
		max_state = phy_max;
		max_state -= (float) max_state * rapl_low_limit_percent / 100;
	}
	std::stringstream time_window;
	temp_str.str(std::string());
	temp_str << "constraint_" << _index << "_time_window_us";
	if (!cdev_sysfs.exists(temp_str.str())) {
		thd_log_info("powercap RAPL no time_window_us %s \n",
				temp_str.str().c_str());
		return THD_ERROR;
	}
	if (pl0_min_window)
		time_window << pl0_min_window;
	else
		time_window << def_rapl_time_window;
	cdev_sysfs.write(temp_str.str(), time_window.str());

	std::stringstream enable;
	temp_str.str(std::string());
	temp_str << "enabled";
	if (!cdev_sysfs.exists(temp_str.str())) {
		thd_log_info("powercap RAPL no enabled %s \n", temp_str.str().c_str());
		return THD_ERROR;
	}
	cdev_sysfs.write(temp_str.str(), "0");

	thd_log_debug("RAPL max limit %d increment: %d\n", max_state, inc_dec_val);
	constraint_index = _index;
	set_pid_param(1000, 100, 10);

	return THD_SUCCESS;
}