Пример #1
0
int csys_fs::read(const std::string &path, std::string &buf) {
	std::string p = base_path + path;
	int ret = 0;

#ifndef ANDROID
	try {
#endif
		std::ifstream f(p.c_str(), std::fstream::in);
		if (f.fail()) {
			thd_log_warn("sysfs read failed %s\n", path.c_str());
			return -EINVAL;
		}
		f >> buf;
		if (f.bad()) {
			thd_log_warn("sysfs read failed %s\n", path.c_str());
			ret = -EIO;
		}
		f.close();
#ifndef ANDROID
	} catch (const std::ifstream::failure& e) {
		thd_log_warn("csys_fs::read exception %s\n", path.c_str());

		ret = -EIO;
	}
#endif
	return ret;
}
Пример #2
0
int csys_fs::read(const std::string &path, char *buf, int len) {
	std::string p = base_path + path;
	int fd = ::open(p.c_str(), O_RDONLY);
	if (fd < 0) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		return -errno;
	}
	int ret = ::read(fd, buf, len);
	if (ret < 0)
		thd_log_warn("sysfs read failed %s\n", path.c_str());
	close(fd);

	return ret;
}
Пример #3
0
int csys_fs::write(const std::string &path, const std::string &buf) {
	std::string p = base_path + path;
	int fd = ::open(p.c_str(), O_WRONLY);
	if (fd < 0) {
		thd_log_warn("sysfs write failed %s\n", path.c_str());
		return -errno;
	}
	int ret = ::write(fd, buf.c_str(), buf.size());
	if (ret < 0)
		thd_log_warn("sysfs write failed %s\n", path.c_str());
	close(fd);

	return ret;
}
Пример #4
0
static void *temp_thread_loop(void *arg)
{
	cthd_topology *obj = (cthd_topology*)arg;
	cpu_set_t set;
	unsigned char cpu_mask = 0xff;

	cpu_mask &= ~(1 << obj->designated_cpu);
	CPU_ZERO(&set);
	CPU_SET(obj->designated_cpu, &set);
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
	if(sched_setaffinity(gettid(), sizeof(cpu_set_t), &set))
	{
		perror("sched_setaffinity");
		return NULL;
	}
	obj->cal_failed = false;
	for(;;)
	{
		if(obj->terminate_thread)
			break;
		sleep(1);
		if(obj->check_load_for_calibration(cpu_mask) == false)
		{
			obj->cal_failed = true;
			obj->terminate_thread = true;
			thd_log_warn("!unsuitable CPU load \n");
			break;
		}
		obj->temp_function();
	}
	return NULL;
}
Пример #5
0
// signal handler
static void signal_handler(int sig) {
	switch (sig) {
	case SIGHUP:
		thd_log_warn("Received SIGHUP signal. \n");
		break;
	case SIGINT:
	case SIGTERM:
		thd_log_info("Daemon exiting \n");
		daemonShutdown();
		exit(EXIT_SUCCESS);
		break;
	default:
		thd_log_warn("Unhandled signal %s", strsignal(sig));
		break;
	}
}
Пример #6
0
int cthd_msr::set_clock_mod_duty_cycle_per_cpu(int cpu, int state) {
	unsigned long long val;
	int ret;

	// First bit is reserved
	state = state << 1;

	ret = read_msr(cpu, MSR_IA32_THERM_CONTROL, &val);
	if (ret < 0)
		return THD_ERROR;

	if (!state) {
		val &= ~MSR_IA32_CLK_MOD_ENABLE;
	} else {
		val |= MSR_IA32_CLK_MOD_ENABLE;
	}
	val &= ~MSR_IA32_CLK_MOD_DUTY_CYCLE_MASK;
	val |= (state & MSR_IA32_CLK_MOD_DUTY_CYCLE_MASK);

	ret = write_msr(cpu, MSR_IA32_THERM_CONTROL, val);
	if (ret < 0) {
		thd_log_warn("set_clock_mod_duty_cycle current set failed to write\n");
		return THD_ERROR;
	}

	return THD_SUCCESS;
}
Пример #7
0
int cthd_parse::parser_init()
{

	doc = xmlReadFile(filename.c_str(), NULL, 0);
	if (doc == NULL) {
		thd_log_warn("error: could not parse file %s\n", filename.c_str());
		return THD_ERROR;
	}
	root_element = xmlDocGetRootElement(doc);

	if (root_element == NULL) {
		thd_log_warn("error: could not get root element \n");
		return THD_ERROR;
	}

	return THD_SUCCESS;
}
Пример #8
0
int csys_fs::read(const std::string &path, std::string &buf) {
	std::string p = base_path + path;

	std::ifstream f(p.c_str(), std::fstream::in);
	if (f.fail()) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		return -EINVAL;
	}
	int ret = 0;
	f >> buf;
	if (f.bad()) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		ret = -EIO;
	}
	f.close();

	return ret;
}
Пример #9
0
int csys_fs::write(const std::string &path, unsigned int position, unsigned
long long data) {
	std::string p = base_path + path;
	int fd = ::open(p.c_str(), O_WRONLY);
	if (fd < 0) {
		thd_log_warn("sysfs write failed %s\n", path.c_str());
		return -errno;
	}
	if (::lseek(fd, position, SEEK_CUR) == -1) {
		thd_log_warn("sysfs write failed %s\n", path.c_str());
		return -errno;
	}
	int ret = ::write(fd, &data, sizeof(data));
	if (ret < 0)
		thd_log_warn("sysfs write failed %s\n", path.c_str());
	close(fd);

	return ret;
}
Пример #10
0
int csys_fs::read(const std::string &path, unsigned int position, char *buf,
		int len) {
	std::string p = base_path + path;
	int fd = ::open(p.c_str(), O_RDONLY);
	if (fd < 0) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		return -errno;
	}
	if (::lseek(fd, position, SEEK_CUR) == -1) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		return -errno;
	}
	int ret = ::read(fd, buf, len);
	if (ret < 0)
		thd_log_warn("sysfs read failed %s\n", path.c_str());
	close(fd);

	return ret;
}
Пример #11
0
int csys_fs::read(const std::string &path, unsigned long *ptr_val) {
	std::string p = base_path + path;
	char str[32];
	int ret;

	int fd = ::open(p.c_str(), O_RDONLY);
	if (fd < 0) {
		thd_log_warn("sysfs read failed %s\n", path.c_str());
		return -errno;
	}
	ret = ::read(fd, str, sizeof(str));
	if (ret > 0)
		*ptr_val = atol(str);
	else
		thd_log_warn("sysfs read failed %s\n", path.c_str());
	close(fd);

	return ret;
}
Пример #12
0
int csys_fs::read_symbolic_link_value(const std::string &path, char *buf,
		int len) {
	std::string p = base_path + path;
	int ret = ::readlink(p.c_str(), buf, len);
	if (ret < 0) {
		thd_log_warn("read_symbolic_link %s\n", path.c_str());
		return -errno;
	}
	buf[ret] = '\0';
	return 0;
}
Пример #13
0
int cthd_msr::write_msr(int cpu, unsigned int idx, unsigned long long val) {
	int ret = -1;
	std::stringstream file_name_str;
	file_name_str << cpu << "/msr";
	if (msr_sysfs.exists(file_name_str.str())) {
		ret = msr_sysfs.write(file_name_str.str(), idx, val);
	}
	if (ret < 0) {
		thd_log_warn("MSR WRITE Failed \n");
	}

	return ret;
}
Пример #14
0
int cthd_msr::read_msr(int cpu, unsigned int idx, unsigned long long *val) {
	int ret = -1;
	std::stringstream file_name_str;

	file_name_str << cpu << "/msr";
	if (msr_sysfs.exists(file_name_str.str())) {
		ret = msr_sysfs.read(file_name_str.str(), idx, (char*) val,
				sizeof(*val));
	}
	if (ret < 0) {
		thd_log_warn("MSR READ Failed \n");
	}

	return ret;
}
Пример #15
0
cthd_rapl_power_meter::cthd_rapl_power_meter(unsigned int mask) :
		rapl_present(true), rapl_sysfs("/sys/class/powercap/intel-rapl/"), domain_list(
				0), last_time(0), poll_thread(0), measure_mask(mask), enable_measurement(
				false) {

	if (rapl_sysfs.exists()) {
		thd_log_debug("RAPL sysfs present \n");
		rapl_present = true;
		last_time = time(NULL);
		rapl_read_domains(rapl_sysfs.get_base_path());
	} else {
		thd_log_warn("NO RAPL sysfs present \n");
		rapl_present = false;
	}
}
Пример #16
0
int cthd_trip_point::thd_trip_point_add_cdev_index(int _index, int influence) {
	cthd_cdev *cdev = thd_engine->thd_get_cdev_at_index(_index);
	if (cdev) {
		trip_pt_cdev_t thd_cdev;
		thd_cdev.cdev = cdev;
		thd_cdev.influence = influence;
		thd_cdev.sampling_priod = 0;
		thd_cdev.last_op_time = 0;
		trip_cdev_add(thd_cdev);
		return THD_SUCCESS;
	} else {
		thd_log_warn("thd_trip_point_add_cdev_index not present %d\n", _index);
		return THD_ERROR;
	}
}
Пример #17
0
int cthd_zone_surface::read_trip_points() {
	cthd_trip_point *trip_ptr = NULL;
	bool add = false;

	if (!sensor)
		return THD_ERROR;

	for (unsigned int j = 0; j < trip_points.size(); ++j) {
		if (trip_points[j].get_trip_type() == PASSIVE) {
			thd_log_debug("updating existing trip temp \n");
			trip_points[j].update_trip_temp(passive_trip_temp);
			trip_points[j].update_trip_hyst(passive_trip_hyst);
			trip_ptr = &trip_points[j];
			break;
		}
	}
	if (!trip_ptr) {
		trip_ptr = new cthd_trip_point(trip_points.size(), PASSIVE,
				passive_trip_temp, passive_trip_hyst, index,
				sensor->get_index(), SEQUENTIAL);
		if (!trip_ptr) {
			thd_log_warn("Mem alloc error for new trip \n");
			return THD_ERROR;
		}
		add = true;
	}

	cthd_cdev *cdev = thd_engine->search_cdev("rapl_controller");
	if (cdev) {
		trip_ptr->thd_trip_point_add_cdev(*cdev,
				cthd_trip_point::default_influence, surface_sampling_period);
	}
	cdev = thd_engine->search_cdev("intel_powerclamp");
	if (cdev) {
		trip_ptr->thd_trip_point_add_cdev(*cdev,
				cthd_trip_point::default_influence, surface_sampling_period);
	}

	if (add) {
		trip_points.push_back(*trip_ptr);
	}

	return THD_SUCCESS;
}
Пример #18
0
int cthd_kobj_uevent::kobj_uevent_open() {
	memset(&nls, 0, sizeof(struct sockaddr_nl));

	nls.nl_family = AF_NETLINK;
	nls.nl_pid = getpid();
	nls.nl_groups = -1;

	fd = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_KOBJECT_UEVENT);
	if (fd < 0)
		return fd;

	if (bind(fd, (struct sockaddr*) &nls, sizeof(struct sockaddr_nl))) {
		thd_log_warn("kob_uevent bin failed \n");
		close(fd);
		return -1;
	}

	return fd;
}
Пример #19
0
int cthd_msr::set_clock_mod_duty_cycle(int state) {
	int cpu_count = get_no_cpus();
	unsigned long long val;
	int ret;

	thd_log_info("Set T stated %d \n", state);
	// First bit is reserved
	state = state << 1;

	for (int i = 0; i < cpu_count; ++i) {
		ret = read_msr(i, MSR_IA32_THERM_CONTROL, &val);
		if (ret < 0) {
			thd_log_debug("set_clock_mod_duty_cycle current MSR read failed\n");
			return THD_ERROR;
		}

		thd_log_debug("set_clock_mod_duty_cycle current %x\n",
				(unsigned int) val);

		if (!state) {
			val &= ~MSR_IA32_CLK_MOD_ENABLE;
		} else {
			val |= MSR_IA32_CLK_MOD_ENABLE;
		}

		val &= ~MSR_IA32_CLK_MOD_DUTY_CYCLE_MASK;
		val |= (state & MSR_IA32_CLK_MOD_DUTY_CYCLE_MASK);

		thd_log_debug("set_clock_mod_duty_cycle current set to %x\n",
				(unsigned int) val);
		ret = write_msr(i, MSR_IA32_THERM_CONTROL, val);
		if (ret < 0) {
			thd_log_warn(
					"set_clock_mod_duty_cycle current set failed to write\n");
			return THD_ERROR;
		}
	}

	return THD_SUCCESS;
}
Пример #20
0
bool cthd_trip_point::thd_trip_point_check(int id, unsigned int read_temp,
		int pref, bool *reset) {
	int on = -1;
	int off = -1;
	bool apply = false;

	*reset = false;

	if (depend_cdev && read_temp >= temp) {
		int _state = depend_cdev->get_curr_state();
		int valid = 0;

		switch (depend_cdev_state_rel) {
		case EQUAL:
			if (_state == depend_cdev_state)
				valid = 1;
			break;
		case GREATER:
			if (_state > depend_cdev_state)
				valid = 1;
			break;
		case LESSER:
			if (_state < depend_cdev_state)
				valid = 1;
			break;
		case LESSER_OR_EQUAL:
			if (_state <= depend_cdev_state)
				valid = 1;
			break;
		case GREATER_OR_EQUAL:
			if (_state >= depend_cdev_state)
				valid = 1;
			break;
		default:
			break;
		}

		if (!valid) {
			thd_log_info("constraint failed %s:%d:%d:%d \n",
					depend_cdev->get_cdev_type().c_str(), _state, depend_cdev_state_rel,
					depend_cdev_state);
			return false;
		}
	}

	if (sensor_id != DEFAULT_SENSOR_ID && sensor_id != id)
		return false;

	if (read_temp == 0) {
		thd_log_debug("TEMP == 0 pref: %d\n", pref);
	}

	if (type == CRITICAL) {
		int ret = -1;

		if (read_temp >= temp) {
			thd_log_warn("critical temp reached \n");
			sync();
#ifdef ANDROID
			ret = property_set("sys.powerctl", "shutdown,thermal");
#else
			reboot(RB_POWER_OFF);
#endif
			if (ret != 0)
				thd_log_warn("power off failed ret=%d err=%s\n",
					     ret, strerror(errno));
			else
				thd_log_warn("power off initiated\n");

			return true;
		}
	}
	if (type == HOT) {
		if (read_temp >= temp) {
			thd_log_warn("Hot temp reached \n");
			csys_fs power("/sys/power/");
			power.write("state", "mem");
			return true;
		}
	}

	if (type == POLLING && sensor_id != DEFAULT_SENSOR_ID) {
		cthd_sensor *sensor = thd_engine->get_sensor(sensor_id);
		if (sensor) {
			if (!poll_on && read_temp >= temp) {
				thd_log_debug("polling trip reached, on \n");
				sensor->sensor_poll_trip(true);
				poll_on = true;
				sensor->sensor_fast_poll(true);
				if (sensor->check_async_capable())
					sensor->set_threshold(0, temp);
			} else if (poll_on && read_temp < temp) {
				sensor->sensor_poll_trip(false);
				thd_log_debug("Dropped below poll threshold \n");
				*reset = true;
				poll_on = false;
				sensor->sensor_fast_poll(false);
				if (sensor->check_async_capable())
					sensor->set_threshold(0, temp);
			}
		}
		return true;
	}
	thd_log_debug("pref %d type %d temp %d trip %d \n", pref, type, read_temp,
			temp);
	switch (pref) {
	case PREF_DISABLED:
		return false;
		break;

	case PREF_PERFORMANCE:
		if (type == ACTIVE || type == MAX) {
			apply = true;
			thd_log_debug("Active Trip point applicable \n");
		}
		break;

	case PREF_ENERGY_CONSERVE:
		if (type == PASSIVE || type == MAX) {
			apply = true;
			thd_log_debug("Passive Trip point applicable \n");
		}
		break;

	default:
		break;
	}

	if (apply) {
		if (read_temp >= temp) {
			thd_log_debug("Trip point applicable >  %d:%d \n", index, temp);
			on = 1;
			trip_on = true;
		} else if ((trip_on && (read_temp + hyst) < temp)
				|| (!trip_on && read_temp < temp)) {
			thd_log_debug("Trip point applicable <  %d:%d \n", index, temp);
			off = 1;
			trip_on = false;
		}
	} else
		return false;

	if (on != 1 && off != 1)
		return true;

	int i, ret;
	thd_log_debug("cdev size for this trippoint %lu\n",
			(unsigned long) cdevs.size());
	if (on > 0) {
		for (unsigned i = 0; i < cdevs.size(); ++i) {
			cthd_cdev *cdev = cdevs[i].cdev;

			if (cdevs[i].sampling_priod) {
				time_t tm;
				time(&tm);
				if ((tm - cdevs[i].last_op_time) < cdevs[i].sampling_priod) {
#if defined __x86_64__ && defined __ILP32__
					thd_log_info("Too early to act index %d tm %lld\n",
							cdev->thd_cdev_get_index(),
							tm - cdevs[i].last_op_time);
#else
					thd_log_info("Too early to act index %d tm %ld\n",
							cdev->thd_cdev_get_index(),
							tm - cdevs[i].last_op_time);
#endif
					break;
				}
				cdevs[i].last_op_time = tm;
			}
			thd_log_debug("cdev at index %d:%s\n", cdev->thd_cdev_get_index(),
					cdev->get_cdev_type().c_str());
			/*
			 * When the cdev is already in max state, we skip this cdev.
			 * Also when the target state if any for the current trip is greater
			 * or equal than the current state of the cdev, then also skip.
			 */
			if (cdev->in_max_state()
					|| (cdevs[i].target_state_valid
							&& cdev->cmp_current_state(
									cdev->map_target_state(
											cdevs[i].target_state_valid,
											cdevs[i].target_state)) <= 0)) {
				thd_log_debug("Need to switch to next cdev target %d \n",
						cdev->map_target_state(cdevs[i].target_state_valid,
								cdevs[i].target_state));
				// No scope of control with this cdev
				continue;
			}

			if (cdevs[i].target_state == TRIP_PT_INVALID_TARGET_STATE)
				cdevs[i].target_state = cdev->get_min_state();

			ret = cdev->thd_cdev_set_state(temp, temp, read_temp, (type == MAX), 1, zone_id,
					index, cdevs[i].target_state_valid,
					cdev->map_target_state(cdevs[i].target_state_valid,
							cdevs[i].target_state), &cdevs[i].pid_param,
					cdevs[i].pid, false);
			if (control_type == SEQUENTIAL && ret == THD_SUCCESS) {
				// Only one cdev activation
				break;
			}
		}
	}

	if (off > 0) {
		for (i = cdevs.size() - 1; i >= 0; --i) {

			cthd_cdev *cdev = cdevs[i].cdev;
			thd_log_debug("cdev at index %d:%s\n", cdev->thd_cdev_get_index(),
					cdev->get_cdev_type().c_str());
			if (cdev->in_min_state()) {
				thd_log_debug("Need to switch to next cdev \n");
				// No scope of control with this cdev
				continue;
			}

			if (cdevs[i].target_state == TRIP_PT_INVALID_TARGET_STATE)
				cdevs[i].target_state = cdev->get_min_state();

			cdev->thd_cdev_set_state(temp, temp, read_temp, (type == MAX), 0, zone_id, index,
					cdevs[i].target_state_valid,
					cdev->map_target_state(cdevs[i].target_state_valid,
							cdevs[i].target_state), &cdevs[i].pid_param,
					cdevs[i].pid, false);

			if (control_type == SEQUENTIAL) {
				// Only one cdev activation
				break;
			}
		}
	}

	return true;
}
Пример #21
0
// Setup dbus server
static int thd_dbus_server_proc(gboolean no_daemon) {
	DBusGConnection *bus;
	DBusGProxy *bus_proxy;
	GMainLoop *main_loop;
	GError *error = NULL;
	guint result;
	PrefObject *value_obj;

	thd_engine = NULL;
	// Initialize the GType/GObject system
	g_type_init();

	// Create a main loop that will dispatch callbacks
	g_main_loop = main_loop = g_main_loop_new(NULL, FALSE);
	if (main_loop == NULL) {
		thd_log_error("Couldn't create GMainLoop:");
		return THD_FATAL_ERROR;
	}
	if (dbus_enable) {
		bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
		if (error != NULL) {
			thd_log_error("Couldn't connect to session bus: %s:",
					error->message);
			return THD_FATAL_ERROR;
		}

		// Get a bus proxy instance
		bus_proxy = dbus_g_proxy_new_for_name(bus, DBUS_SERVICE_DBUS,
				DBUS_PATH_DBUS, DBUS_INTERFACE_DBUS);
		if (bus_proxy == NULL) {
			thd_log_error("Failed to get a proxy for D-Bus:");
			return THD_FATAL_ERROR;
		}

		thd_log_debug("Registering the well-known name (%s)\n",
				THD_SERVICE_NAME);
		// register the well-known name
		if (!dbus_g_proxy_call(bus_proxy, "RequestName", &error, G_TYPE_STRING,
				THD_SERVICE_NAME, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT,
				&result, G_TYPE_INVALID)) {
			thd_log_error("D-Bus.RequestName RPC failed: %s\n", error->message);
			return THD_FATAL_ERROR;
		}
		thd_log_debug("RequestName returned %d.\n", result);
		if (result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER) {
			thd_log_error("Failed to get the primary well-known name:");
			return THD_FATAL_ERROR;
		}
		value_obj = (PrefObject*) g_object_new(PREF_TYPE_OBJECT, NULL);
		if (value_obj == NULL) {
			thd_log_error("Failed to create one Value instance:");
			return THD_FATAL_ERROR;
		}

		thd_log_debug("Registering it on the D-Bus.\n");
		dbus_g_connection_register_g_object(bus, THD_SERVICE_OBJECT_PATH,
				G_OBJECT(value_obj));
	}
	if (!no_daemon) {
		printf("Ready to serve requests: Daemonizing.. %d\n", thd_daemonize);
		thd_log_info(
				"thermald ver %s: Ready to serve requests: Daemonizing..\n",
				TD_DIST_VERSION);

		if (daemon(0, 1) != 0) {
			thd_log_error("Failed to daemonize.\n");
			return THD_FATAL_ERROR;
		}
	}

	thd_engine = new cthd_engine_default();
	if (exclusive_control)
		thd_engine->set_control_mode(EXCLUSIVE);

	// Initialize thermald objects
	thd_engine->set_poll_interval(thd_poll_interval);
	if (thd_engine->thd_engine_start(ignore_cpuid_check) != THD_SUCCESS) {
		thd_log_error("THD engine start failed: ");
		closelog();
		exit(1);
	}

	// Start service requests on the D-Bus
	thd_log_debug("Start main loop\n");
	g_main_loop_run(main_loop);
	thd_log_warn("Oops g main loop exit..\n");
	return THD_SUCCESS;
}
Пример #22
0
bool cthd_trip_point::thd_trip_point_check(int id, unsigned int read_temp,
		int pref, bool *reset) {
	int on = -1;
	int off = -1;
	bool apply = false;

	*reset = false;

	if (sensor_id != DEFAULT_SENSOR_ID && sensor_id != id)
		return false;

	if (read_temp == 0) {
		thd_log_warn("TEMP == 0 pref: %d\n", pref);
	}

	if (type == CRITICAL) {
		if (read_temp >= temp) {
			thd_log_warn("critical temp reached \n");
			sync();
			reboot(RB_POWER_OFF);
		}
	}

	if (type == POLLING && sensor_id != DEFAULT_SENSOR_ID) {
		cthd_sensor *sensor = thd_engine->get_sensor(sensor_id);
		if (sensor && sensor->check_async_capable()) {
			if (!poll_on && read_temp >= temp) {
				thd_log_debug("polling trip reached, on \n");
				sensor->sensor_poll_trip(true);
				poll_on = true;
				sensor->set_threshold(0, temp);
			} else if (poll_on && read_temp < temp) {
				thd_log_debug("polling trip reached, off \n");
				sensor->sensor_poll_trip(false);
				thd_log_info("Dropped below poll threshold \n");
				*reset = true;
				poll_on = false;
				sensor->set_threshold(0, temp);
			}
		}
		return true;
	}
	thd_log_debug("pref %d type %d temp %d trip %d \n", pref, type, read_temp,
			temp);
	switch (pref) {
	case PREF_DISABLED:
		return false;
		break;

	case PREF_PERFORMANCE:
		if (type == ACTIVE || type == MAX) {
			apply = true;
			thd_log_debug("Active Trip point applicable \n");
		}
		break;

	case PREF_ENERGY_CONSERVE:
		if (type == PASSIVE || type == MAX) {
			apply = true;
			thd_log_debug("Passive Trip point applicable \n");
		}
		break;

	default:
		break;
	}

	if (apply) {
		if (read_temp >= temp) {
			thd_log_debug("Trip point applicable >  %d:%d \n", index, temp);
			on = 1;
			trip_on = true;
		} else if ((trip_on && (read_temp + hyst) < temp)
				|| (!trip_on && read_temp < temp)) {
			thd_log_debug("Trip point applicable <  %d:%d \n", index, temp);
			off = 1;
			trip_on = false;
		}
	} else
		return false;

	if (on != 1 && off != 1)
		return true;

	int i, ret;
	thd_log_debug("cdev size for this trippoint %lu\n",
			(unsigned long) cdevs.size());
	if (on > 0) {
		for (unsigned i = 0; i < cdevs.size(); ++i) {
			cthd_cdev *cdev = cdevs[i].cdev;

			if (cdevs[i].sampling_priod) {
				time_t tm;
				time(&tm);
				if ((tm - cdevs[i].last_op_time) < cdevs[i].sampling_priod) {
					thd_log_info("Too early to act index %d tm %ld\n",
							cdev->thd_cdev_get_index(),
							tm - cdevs[i].last_op_time);
					continue;
				}
				cdevs[i].last_op_time = tm;
			}
			thd_log_debug("cdev at index %d:%s\n", cdev->thd_cdev_get_index(),
					cdev->get_cdev_type().c_str());
			if (cdev->in_max_state()) {
				thd_log_debug("Need to switch to next cdev \n");
				// No scope of control with this cdev
				continue;
			}
			ret = cdev->thd_cdev_set_state(temp, temp, read_temp, 1, zone_id);
			if (control_type == SEQUENTIAL && ret == THD_SUCCESS) {
				// Only one cdev activation
				break;
			}
		}
	}

	if (off > 0) {
		for (i = cdevs.size() - 1; i >= 0; --i) {

			cthd_cdev *cdev = cdevs[i].cdev;
			thd_log_debug("cdev at index %d:%s\n", cdev->thd_cdev_get_index(),
					cdev->get_cdev_type().c_str());
			if (cdev->in_min_state()) {
				thd_log_debug("Need to switch to next cdev \n");
				// No scope of control with this cdev
				continue;
			}
			cdev->thd_cdev_set_state(temp, temp, read_temp, 0, zone_id);
			if (control_type == SEQUENTIAL) {
				// Only one cdev activation
				break;
			}
		}
	}

	return true;
}
Пример #23
0
int cthd_topology::calibrate()
{
	int ret;
	int i, j;

	// Reset moving average
	memset(temp_data, 0, sizeof(*temp_data) * no_sensors);

	for(i = 0; i < no_cpu; ++i)
	{
		cpu_sensor_rel[i].sensor_id =  - 1;
	}

	for(i = 0; i < no_sensors; ++i)
	{
		sensor_cpu_rel[i].cpu_id =  - 1;
	}

	for(i = 0; i < no_cpu; ++i)
	{
		int max = 0;
		int max_index = 0;
		int diff;

		if(check_load_for_calibration(0xff) == false)
		{
			// Not a right time to do calibration
			// retry at later time
			thd_log_warn("Calibration process aborted because of unsuitable CPU load \n")
	;
			return  - 1;
		}

		designated_cpu = i;
		memset(temp_data, 0, sizeof(*temp_data) *no_sensors);
		pthread_attr_init(&thd_attr);
		pthread_attr_setdetachstate(&thd_attr, PTHREAD_CREATE_DETACHED);
		terminate_thread = false;
		ret = pthread_create(&load_thread, &thd_attr, load_thread_loop, (void*)this);
		ret = pthread_create(&temp_thread, &thd_attr, temp_thread_loop, (void*)this);

		thd_log_info("Started %d seconds sleep on main thread \n", measurment_time);
		sleep(measurment_time);
		thd_log_info("End %d seconds sleep on main thread \n", measurment_time);
		terminate_thread = true;
		sleep(1);
		pthread_cancel(load_thread);
		pthread_cancel(temp_thread);

		if(cal_failed)
		{
			thd_log_warn("Calibration process aborted because of unsuitable CPU load \n")
	;
			return  - 1;
		}

		for(int j = 0; j < no_sensors; ++j)
		{
			diff = temp_data[j].last_moving_average;
			if(diff == 0)
				continue;
			if(max < diff)
			{
				max = diff;
				max_index = j;
			}
			cpu_sensor_rel[i].sensor_id = max_index;
			thd_log_info("cpu %d sensor %d current %d max %d:%d\n", i, j, diff,
	max_index, max);
		}
	}

	// Sanitize
	bool valid = true;
	for(i = 0; i < no_cpu; ++i)
	{
		int count = 0;
		unsigned int mask = 0;
		for(j = 0; j < no_sensors; ++j)
		{
			if(i != j && cpu_sensor_rel[j].sensor_id !=  - 1 &&
	cpu_sensor_rel[i].sensor_id == cpu_sensor_rel[j].sensor_id)
			{
				count++;
				mask |= ((1 << i) | (1 << j));
				sensor_cpu_rel[cpu_sensor_rel[i].sensor_id].cpu_id = mask;
				if(count > 2)
				{
					valid = false;
					break;
				}

			}
		}
	}

	// Check if every CPU is covered
	if(valid)
	{
		for(i = 0; i < no_cpu; ++i)
		{
			if(cpu_sensor_rel[i].sensor_id ==  - 1)
			{
				valid = false;
				break;
			}
		}
	}
	if(valid)
	{
		for(i = 0; i < no_cpu; ++i)
		{
			//if (cpu_sensor_rel[i].sensor_id != -1)
			thd_log_info("cpu_sensor_rel cpu%d sensor %d\n", i,
	cpu_sensor_rel[i].sensor_id);
		}

		for(i = 0; i < no_sensors; ++i)
		{
			if(sensor_cpu_rel[i].cpu_id !=  - 1)
			{
				thd_log_info("sensor_cpu rel sensor %d cpu %x\n", i,
	sensor_cpu_rel[i].cpu_id);
				store_configuration(i, sensor_cpu_rel[i].cpu_id);
			}
		}
	}
	else
	{
		thd_log_info("Can't reliably tie sensor and CPU\n");
	}

	configuration_saved();
	return 0; 
	// calibration process is done, it is possible that we can't do per cpu control
}
Пример #24
0
// Setup dbus server
static int thd_dbus_server_proc(gboolean no_daemon)
{
	DBusGConnection *bus;
	DBusGProxy *bus_proxy;
	GMainLoop *main_loop;
	GError *error = NULL;
	guint result;
	PrefObject *value_obj;

	// Initialize the GType/GObject system
	g_type_init();

	// Create a main loop that will dispatch callbacks
	main_loop = g_main_loop_new(NULL, FALSE);
	if(main_loop == NULL)
	{
		thd_log_error("Couldn't create GMainLoop:");
		return THD_FATAL_ERROR;
	}
	if(dbus_enable)
	{
		bus = dbus_g_bus_get(DBUS_BUS_SYSTEM, &error);
		if(error != NULL)
		{
			thd_log_error("Couldn't connect to session bus: %s:", error->message);
			return THD_FATAL_ERROR;
		}

		// Get a bus proxy instance
		bus_proxy = dbus_g_proxy_new_for_name(bus, DBUS_SERVICE_DBUS, DBUS_PATH_DBUS,
	DBUS_INTERFACE_DBUS);
		if(bus_proxy == NULL)
		{
			thd_log_error("Failed to get a proxy for D-Bus:");
			return THD_FATAL_ERROR;
		}

		thd_log_debug("Registering the well-known name (%s)\n", THD_SERVICE_NAME);
		// register the well-known name
		if(!dbus_g_proxy_call(bus_proxy, "RequestName",  &error, G_TYPE_STRING,
	THD_SERVICE_NAME, G_TYPE_UINT, 0, G_TYPE_INVALID, G_TYPE_UINT,  &result,
	G_TYPE_INVALID))
		{
			thd_log_error("D-Bus.RequestName RPC failed: %s\n", error->message);
			return THD_FATAL_ERROR;
		}
		thd_log_debug("RequestName returned %d.\n", result);
		if(result != DBUS_REQUEST_NAME_REPLY_PRIMARY_OWNER)
		{
			thd_log_error("Failed to get the primary well-known name:");
			return THD_FATAL_ERROR;
		}
		value_obj = (PrefObject*)g_object_new(PREF_TYPE_OBJECT, NULL);
		if(value_obj == NULL)
		{
			thd_log_error("Failed to create one Value instance:");
			return THD_FATAL_ERROR;
		}

		thd_log_debug("Registering it on the D-Bus.\n");
		dbus_g_connection_register_g_object(bus, THD_SERVICE_OBJECT_PATH, G_OBJECT
	(value_obj));
	}
	if(!no_daemon)
	{
		printf("Ready to serve requests: Daemonizing.. %d\n", thd_daemonize);
		thd_log_info("thermald ver %s: Ready to serve requests: Daemonizing..\n", TD_DIST_VERSION);

		if(daemon(0, 1) != 0)
		{
			thd_log_error("Failed to daemonize.\n");
			return THD_FATAL_ERROR;
		}
	}

	if(use_thermal_sys_fs)
		thd_engine = new cthd_engine_therm_sysfs();
	else
	{
		cthd_parse parser;
		bool matched = false;

		// if there is XML config for this platform
		// Use this instead of default DTS sensor and associated cdevs
		if(parser.parser_init() == THD_SUCCESS)
		{
			if(parser.start_parse() == THD_SUCCESS)
			{
				matched = parser.platform_matched();
			}
		}
		if (matched) {
			thd_log_warn("UUID matched, so will load zones and cdevs from thermal-conf.xml\n");
			thd_engine = new cthd_engine_therm_sysfs();
		}
		else
			thd_engine = new cthd_engine_dts();
	}
	// Initialize thermald objects
	if(thd_engine->thd_engine_start() != THD_SUCCESS)
	{
		thd_log_error("THD engine start failed: ");
		closelog();
		exit(1);
	}

	// Start service requests on the D-Bus
	thd_log_debug("Start main loop\n");
	g_main_loop_run(main_loop);
	thd_log_warn("Oops g main loop exit..\n");
	return THD_SUCCESS;
}