温控daemon(七)ss算法

monitor算法是一种静态算法,超过阈值就限制为多少频率,或者做什么处理,ss不一样它是一种动态算法。

下面我们就从代码层面进行分析。也是在main函数中调用了ss_algo_init函数。

1. ss_algo_init

我们来看下这个函数的前半段函数,这里主要先是过滤配置中的setting,然后创建sensor的device的client,然后就是获取devie信息,还有就是将device的各个档位的信息lvl_info放入每个setting的lvl_arr中了。

int ss_algo_init(struct thermal_setting_t *setting)
{
	int ret_val = 0;
	struct device_info dev_info;
	struct setting_info *cfg;
	int err = 0;
	uint8_t i = 0;

	if (setting == NULL) {
		msg("%s: Invalid Argument\n", __func__);
		return -(EINVAL);
	}

	sem_init(&sem_config_set, 0, 1);
	cfg = setting->list;
	/* Import settings */
	while (cfg) {
		err = 0;
		if (clnt_cnt >= MAX_INSTANCES_SUPPORTED) {//最大根数限制
			msg("%s: Max SS instances reached.", __func__);
			break;
		}

		if (cfg->algo_type != SS_ALGO_TYPE) {//类型过滤
			cfg = cfg->next;
			continue;
		}

		if (cfg->err_disable) {//错误过滤
			info("%s: Entry Disabled %s.", __func__,
			    cfg->desc);
			cfg = cfg->next;
			continue;
		}

		if (cfg->data.ss.sampling_period_ms == 0) {//采样率没有配置
			msg("%s: Sampling is not configured, "
			    "disabling entry %s", __func__,  cfg->desc);
			continue;
		}

		algo_clnt[clnt_cnt].sensor_clnt =//为每一个setting创建一个sensor的client
			sensors_manager_reg_clnt(cfg->data.ss.sensor);
		if (algo_clnt[clnt_cnt].sensor_clnt == NULL) {
			msg("%s: Sensor clnt create fail %s\n", __func__,
			    cfg->data.ss.sensor);
			err = EFAULT;
			goto error_handler;
		}

		algo_clnt[clnt_cnt].dev_clnt =//为每个setting创建device的client,这里不像monitor算法,只有有一个device
			devices_manager_reg_clnt(cfg->data.ss.device);
		if (algo_clnt[clnt_cnt].dev_clnt == NULL) {
			msg("%s: Device clnt create fail %s\n", __func__,
			    cfg->data.ss.device);
			err = EFAULT;
			goto error_handler;
		}

		err = devices_manager_get_info(cfg->data.ss.device,
					       &dev_info);//获取device的device_info
		if (err) {
			msg("%s: Can not grab dev info %s\n", __func__,
			    cfg->data.ss.device);
			goto error_handler;
		}

		if (dev_info.dev_type != DEVICE_OP_VALUE_TYPE) {//类型只能是这种,比如cpu、gpu
			msg("%s: Improper dev_type %d\n", __func__,
			    cfg->algo_type);
			err = EFAULT;
			goto error_handler;
		}

		if (dev_info.num_of_levels == 0) {//必须要有多档位,比如cpu、gpu
			msg("%s: No levels supported for this device.\n",
			    __func__);
			err = EFAULT;
			goto error_handler;
		}

		algo_clnt[clnt_cnt].lvl_arr = (struct device_lvl_info *)
			malloc(sizeof(struct device_lvl_info) *
			       dev_info.num_of_levels);

		err = devices_manager_get_lvl_list(cfg->data.ss.device,
						   algo_clnt[clnt_cnt].lvl_arr,
						   &dev_info.num_of_levels);//把每个device的lvl_info传入每个setting的lvl_arr中
		if (err) {
			msg("%s: Can not grab dev lvl list %s\n", __func__,
			    cfg->data.ss.device);
			goto error_handler;
		}

我们再来看下这个函数的后半段代码,我们主要看没有出错的处理

error_handler:
		if (err) {//出错的处理
			/* Clean up and look for next SS cfg */
			if (algo_clnt[clnt_cnt].sensor_clnt)
				sensors_manager_dereg_clnt(
				   algo_clnt[clnt_cnt].sensor_clnt);
			if (algo_clnt[clnt_cnt].dev_clnt)
				devices_manager_dereg_clnt(
				   algo_clnt[clnt_cnt].dev_clnt);
			if (algo_clnt[clnt_cnt].lvl_arr)
				free(algo_clnt[clnt_cnt].lvl_arr);
			memset(&algo_clnt[clnt_cnt], 0x0,
			       sizeof(struct ss_algo_t));
		} else {
			algo_clnt[clnt_cnt].disabled =
				cfg->disable;
			algo_clnt[clnt_cnt].state =
				SS_STATE_STOP_ALGO;//初始的状态
			algo_clnt[clnt_cnt].min_op_lvl =
				dev_info.min_dev_op_value;//最新值
			algo_clnt[clnt_cnt].max_op_lvl =
				dev_info.max_dev_op_value;
			algo_clnt[clnt_cnt].dev_op_lvl =
				dev_info.max_dev_op_value;
			algo_clnt[clnt_cnt].setting = &(cfg->data.ss);
			algo_clnt[clnt_cnt].desc = cfg->desc;
			algo_clnt[clnt_cnt].num_of_lvls =
				dev_info.num_of_levels;
			algo_clnt[clnt_cnt].active_set_point =//触发值
				cfg->data.ss.set_point;
			algo_clnt[clnt_cnt].active_set_point_clr =//清除值
				cfg->data.ss.set_point_clr;
			if (cfg->data.ss.device_mtgn_max_limit == 1)
				algo_clnt[clnt_cnt].dev_mtgn_max_limit = 0;
			else
				algo_clnt[clnt_cnt].dev_mtgn_max_limit =
					cfg->data.ss.device_mtgn_max_limit;
			if (cfg->data.ss.device_perf_floor == 1)
				algo_clnt[clnt_cnt].device_perf_floor = 0;
			else
				algo_clnt[clnt_cnt].device_perf_floor =
					cfg->data.ss.device_perf_floor;
			cfg->data.ss.sampling_period_ms =
				MIN(SAMPLE_PERIOD,
				    cfg->data.ss.sampling_period_ms);
			strlcpy(algo_clnt[clnt_cnt].device_units,
				&dev_info.device_units_name[0], MAX_UNIT_NAME_SIZE);

			dbgmsg("%s: SS ID %s, Sensor %s\n", __func__, cfg->desc,
			       cfg->data.ss.sensor);
			dbgmsg("%s: Device %s, Number of Levels %d\n",
			       __func__, cfg->data.ss.device,
			       algo_clnt[clnt_cnt].num_of_lvls);
			dbgmsg("%s: Set Point %dmC, Set Point Clr %dmC, "
			       "Override %dmC\n", __func__,
			       cfg->data.ss.set_point,
			       cfg->data.ss.set_point_clr,
			       cfg->data.ss.override);
			dbgmsg("%s: MAXFREQ %dkHz, MINFREQ %dkHz, TC %d", __func__,
			       dev_info.max_dev_op_value,
			       dev_info.min_dev_op_value,
			       cfg->data.ss.time_constant);
			if (!cfg->disable)
				print_setting(cfg);

			/* Create sampling groups for similarly configured
			   intervals and save sampling group id of each client
			   on its own algo info */
			for (i = 0; i < MAX_INSTANCES_SUPPORTED &&
			     sampling_groups[i].sampling != 0; i++) {
				if (cfg->data.ss.sampling_period_ms ==
				    sampling_groups[i].sampling) {
					algo_clnt[clnt_cnt].sampling_group_id = i;
					break;
				}
			}

			if (i >= MAX_INSTANCES_SUPPORTED ||
				(sampling_groups[i].sampling == 0 &&
				sampling_group_count >= MAX_INSTANCES_SUPPORTED)) {
				msg("%s: Sampling group count max is reached:%d idx:%d\n",
					__func__, sampling_group_count, i);
				err = -1;
				goto error_handler;
			} else if (sampling_groups[i].sampling == 0) {
				sampling_groups[i].sampling =
					cfg->data.ss.sampling_period_ms;//将每个setting下面的采样率放在sampling_groups数组中
				algo_clnt[clnt_cnt].sampling_group_id = i;
				sampling_group_count++;
			}
			clnt_cnt++;
		}
		cfg = cfg->next;
	}

	if (clnt_cnt == 0) {
		info("%s: No SS's configured.\n", __func__);
		return -(EFAULT);
	}

	ret_val = pthread_create(&thread, NULL, (void *)&algo_monitor,//创建线程执行algo_monitor算法监控
				 NULL);
	if (ret_val != 0)
		msg("Error initializing SS algo monitor\n");
	return ret_val;
}

2. algo_monitor

下面我们来看下algo_monitor函数,这个函数主要是开启线程后去执行是ss算法的主函数。主要通过掩码去执行不同函数,并且函数也会等待condition,直到有condition broadcast之后,才会继续执行。

static void *algo_monitor(void *data)
{
	uint32_t        local_ev_mask &
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值