这篇博客我们结合thermal-engine与驱动一起分析,如果设置温度传感器的threshold,以及thermal-engine的wait函数如何结束。
一、thermal-engine的流程
之前我们在博客 温控daemon(三)sensor初始化中分析过sensor监控温度的流程,以及在温控daemon(六)Monitor算法这两篇博客结合分析可以知道如何算法结合sensor控制温度。
这里我们再简单梳理下,每个sensor会创建一个thread来执行tsens_uevent函数,来通过poll监听thermal_zone下面的type是否有事件,如果有事件直接broadcast tsens->tsens_condition。
static void *tsens_uevent(void *data)
{
int err = 0;
struct sensor_info *sensor = (struct sensor_info *)data;
struct pollfd fds;
int fd;
char uevent[MAX_PATH] = {0};
char buf[MAX_PATH] = {0};
struct tsens_data *tsens = NULL;
if (NULL == sensor ||
NULL == sensor->data) {
msg("%s: unexpected NULL", __func__);
return NULL;
}
tsens = (struct tsens_data *) sensor->data;
/* Looking for tsens uevent */
snprintf(uevent, MAX_PATH, TZ_TYPE, sensor->tzn);
fd = open(uevent, O_RDONLY);
if (fd < 0) {
msg("Unable to open %s to receive notifications.\n", uevent);
return NULL;
};
while (!tsens->sensor_shutdown) {
fds.fd = fd;
fds.events = POLLERR|POLLPRI;
fds.revents = 0;
err = poll(&fds, 1, -1);
if (err == -1) {
msg("Error in uevent poll.\n");
break;
}
err = read(fd, buf, sizeof(buf));
if (err < 0)
msg("sysfs[%s] read error:%d\n", uevent, errno);
lseek(fd, 0, SEEK_SET);
dbgmsg("%s: %s", __func__, buf);
/* notify the waiting threads */
pthread_mutex_lock(&(tsens->tsens_mutex));
tsens->threshold_reached = 1;
pthread_cond_broadcast(&(tsens->tsens_condition));
pthread_mutex_unlock(&(tsens->tsens_mutex));
}
close(fd);
return NULL;
}
我们再来分析sensor还会创建另一个thread来执行sensor_monitor函数,这个函数会在sensor_wait中阻塞,当阻塞结束会调用notify_clnts来通知各个client来更新sensor的threshold等,最后再broadcast condition,使具体的算法主程序继续往下走。
static void *sensor_monitor(void *vsensor_mgr)
{
struct sensors_mgr_sensor_info *sensor_mgr = vsensor_mgr;
while (sensor_mgr->thread_shutdown != 1) {
/* Wait here until there is actually a request to process */
if (!sensor_mgr->req_active) {
dbgmsg("%s: %s Wait for client request.\n", __func__, sensor_mgr->name);
pthread_mutex_lock(&(sensor_mgr->req_wait_mutex));
while (!sensor_mgr->req_active) {
pthread_cond_wait(&(sensor_mgr->req_wait_cond),
&(sensor_mgr->req_wait_mutex));
}
pthread_mutex_unlock(&(sensor_mgr->req_wait_mutex));
}
dbgmsg("%s: %s Sensor wait.\n", __func__, sensor_mgr->name);
sensor_wait(sensor_mgr);
if (sensor_mgr->get_trip_temperature)
sensor_mgr->last_reading =
sensor_mgr->get_trip_temperature(sensor_mgr);
else
sensor_mgr->last_reading =
sensor_mgr->get_temperature(sensor_mgr);
dbgmsg("%s: %s Reading %d .\n", __func__, sensor_mgr->name,
sensor_mgr->last_reading);
if (!strncmp(sensor_mgr->name, "bcl", 3)) {
thermalmsg(LOG_LVL_DBG, (LOG_LOGCAT | LOG_LOCAL_SOCKET),
"%s:%s:%d