浩森宇特品牌如何建设一个有效的网站?

摘要:品牌网站建设浩森宇特,一般做网站,如何在手机上制作网站,安卓和网站开发找工作本文部分内容参考Linux Thermal 学习笔记 - 爱码网。特此致谢! 接前一篇文章Linux内核Thermal框架详解四、Th
品牌网站建设浩森宇特,一般做网站,如何在手机上制作网站,安卓和网站开发找工作本文部分内容参考Linux Thermal 学习笔记 - 爱码网。特此致谢#xff01; 接前一篇文章Linux内核Thermal框架详解四、Thermal Core#xff08;3#xff09; 三、相关源码及分析 2. thermal_register_governors 上一回说到这一段代码#xff1a; for (__governor __gove…本文部分内容参考Linux Thermal 学习笔记 - 爱码网。特此致谢 接前一篇文章Linux内核Thermal框架详解四、Thermal Core3 三、相关源码及分析 2. thermal_register_governors 上一回说到这一段代码 for (__governor __governor_thermal_table; \__governor __governor_thermal_table_end; \__governor) {ret thermal_register_governor(*governor);if (ret) {pr_err(Failed to register governor: %s,(*governor)-name);break;}pr_info(Registered thermal governor %s,(*governor)-name); }__governor_thermal_table上一回仔细分析了其来龙去脉现在该关注__governor这个变量了。 __governor这个变量在之前代码中出现过如下 struct thermal_governor **governor; 这是一个二重指针即指向指针的指针。在上述代码中它一开始指向了__governor_thermal_table还记得__governor_thermal_table是怎样定义的吗 在drivers/thermal/thermal_core.h中 extern struct thermal_governor *__governor_thermal_table[]; extern struct thermal_governor *__governor_thermal_table_end[]; 虽然这里是extern但是这比include/asm-generic/vmlinux.lds.h中真正定义__governor_thermal_table的地方好理解。__governor_thermal_table实际上是一个指针数组。所以使用二重指针governor指向它也就合情合理了。 再来回顾一下各种governor策略 step_wise drivers/thermal/gov_step_wise.c中 static struct thermal_governor thermal_gov_step_wise {.name step_wise,.throttle step_wise_throttle, };static struct thermal_governor *__thermal_table_entry_thermal_gov_step_wise \__used __section(__governor_thermal_table) thermal_gov_step_wisepower_allocator drivers/thermal/gov_power_allocator.c中 static struct thermal_governor thermal_gov_power_allocator {.name power_allocator,.bind_to_tz power_allocator_bind,.unbind_from_tz power_allocator_unbind,.throttle power_allocator_throttle, };static struct thermal_governor *__thermal_table_entry_thermal_gov_power_allocator \__used __section(__governor_thermal_table) thermal_gov_power_allocatorfair_share drivers/thermal/gov_fair_share.c中 static struct thermal_governor thermal_gov_fair_share {.name fair_share,.throttle fair_share_throttle, };static struct thermal_governor *__thermal_table_entry_thermal_gov_fair_share \__used __section(__governor_thermal_table) thermal_gov_fair_shareuser_space drivers/thermal/gov_user_space.c中 static struct thermal_governor thermal_gov_user_space {.name user_space,.throttle notify_user_space,.bind_to_tz user_space_bind, };static struct thermal_governor *__thermal_table_entry_thermal_gov_user_space \__used __section(__governor_thermal_table) thermal_gov_user_spacebang_bang drivers/thermal/gov_bang_bang.c中 static struct thermal_governor thermal_gov_bang_bang {.name bang_bang,.throttle bang_bang_control, };static struct thermal_governor *__thermal_table_entry_thermal_gov_bang_bang \__used __section(__governor_thermal_table) thermal_gov_bang_bang弄清楚了以上细节后就能知道本文开头的代码的意义是遍历所有的governor策略并进行注册。注册具体都完成了哪些工作下边接着来看。 2thermal_register_governor thermal_register_governor函数同样在drivers/thermal/thermal_core.c中实现代码如下 int thermal_register_governor(struct thermal_governor *governor) {int err;const char *name;struct thermal_zone_device *pos;if (!governor)return -EINVAL;mutex_lock(thermal_governor_lock);err -EBUSY;if (!__find_governor(governor-name)) {bool match_default;err 0;list_add(governor-governor_list, thermal_governor_list);match_default !strncmp(governor-name,DEFAULT_THERMAL_GOVERNOR,THERMAL_NAME_LENGTH);if (!def_governor match_default)def_governor governor;}mutex_lock(thermal_list_lock);list_for_each_entry(pos, thermal_tz_list, node) {/** only thermal zones with specified tz-tzp-governor_name* may run with tz-govenor unset*/if (pos-governor)continue;name pos-tzp-governor_name;if (!strncasecmp(name, governor-name, THERMAL_NAME_LENGTH)) {int ret;ret thermal_set_governor(pos, governor);if (ret)dev_err(pos-device,Failed to set governor %s for thermal zone %s: %d\n,governor-name, pos-type, ret);}}mutex_unlock(thermal_list_lock);mutex_unlock(thermal_governor_lock);return err; } 函数虽然不算太长但也不算太短还是有一些内容的。逐段来看 一开始是判断并确保入参governor不为空。 接下来加锁mutex_lock(thermal_governor_lock)。thermal_governor_lock在同文件drivers/thermal/thermal_core.c中定义并初始化代码如下 static DEFINE_MUTEX(thermal_governor_lock); 接下来是一个判断if (!__find_governor(governor-name))。__find_governor函数同样在drivers/thermal/thermal_core.c中代码如下 /** Governor section: set of functions to handle thermal governors** Functions to help in the life cycle of thermal governors within* the thermal core and by the thermal governor code.*/static struct thermal_governor *__find_governor(const char *name) {struct thermal_governor *pos;if (!name || !name[0])return def_governor;list_for_each_entry(pos, thermal_governor_list, governor_list)if (!strncasecmp(name, pos-name, THERMAL_NAME_LENGTH))return pos;return NULL; } 要弄清楚这个函数的功能就必须弄清楚list_for_each_entry的含义。list_for_each_entry是一个宏在include/linux/list.h中代码如下 /*** list_for_each_entry - iterate over list of given type* pos: the type * to use as a loop cursor.* head: the head for your list.* member: the name of the list_head within the struct.*/ #define list_for_each_entry(pos, head, member) \for (pos list_first_entry(head, typeof(*pos), member); \!list_entry_is_head(pos, head, member); \pos list_next_entry(pos, member))list_first_entry当然也在include/linux/list.h中代码如下 /*** list_first_entry - get the first element from a list* ptr: the list head to take the element from.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.** Note, that list is expected to be not empty.*/ #define list_first_entry(ptr, type, member) \list_entry((ptr)-next, type, member) list_entry也在include/linux/linux.h中就在list_first_entry宏定义的上边代码如下 /*** list_entry - get the struct for this entry* ptr: the struct list_head pointer.* type: the type of the struct this is embedded in.* member: the name of the list_head within the struct.*/ #define list_entry(ptr, type, member) \container_of(ptr, type, member) 由上list_first_entry展开为 #define list_first_entry container_of((ptr)-next, type, member) list_entry_is_head同样在include/linux/linux.h中代码如下 /*** list_entry_is_head - test if the entry points to the head of the list* pos: the type * to cursor* head: the head for your list.* member: the name of the list_head within the struct.*/ #define list_entry_is_head(pos, head, member) \(pos-member (head))list_next_entry同样在include/linux/linux.h中代码如下 /*** list_next_entry - get the next element in list* pos: the type * to cursor* member: the name of the list_head within the struct.*/ #define list_next_entry(pos, member) \list_entry((pos)-member.next, typeof(*(pos)), member)