我们在不同的模块之间共享数据或者传递事件通知是会用到全局变量。全局变量使程序运行时速度快,因为内存不需要再分配;但全局变量会占用更多的内存资源,全局变量是可以被本文件中的其他函数所共用。
但是也有缺点比如过度使用全局变量会导致程序结构混乱,模组之间代码耦合度过高。例如两个模块之间存在多个全局变量在相互调度时,会导致代码耦合度过高导致程序崩溃,或模块之间存在太多依赖导致系统编译不过。
另外需要传递事件通知时,使用全局变量没有通知链灵活。例如一个模块的某个函数执行需要通知另一个模块的某个函数的执行。假如用全局变量去实现,在修改代码上实现更复杂。还要考虑模块之间依赖顺序。
通知链:
通知链是一种存在操作系统内核中的使用机制,它用于在不同内核模块之间传递通知消息。通知链是一个单链表,链表上的节点是调用块,每个调用块包含事件相关的回调函数和调用块的优先级。
工作原理:
- 当某个内核模块发生特定事件(例如设备状态改变、系统资源变化等)时,它可以通过通知链发送通知消息。
- 其他对该事件感兴趣的内核模块可以注册到通知链上,当有通知消息传来时,这些注册的模块就会收到通知并进行相应的处理。
- 通知链提供了一种松散耦合的方式来实现内核模块之间的通信,避免了模块之间的直接依赖。
内核模块之间我们经常可以看到通知链的使用,如typec和usb 模块会通过vbus和usb状态来通知usb角色管理,usb和charger模块会通过extcon事件上报来启动充电。lcd和TP模块之间的休眠唤醒调度。
以lcd利用通知链进行tp的suspend和resume举例:
static int sprd_panel_disable(struct drm_panel *p)
{
... ...
if (panel->backlight) {
panel->backlight->props.power = FB_BLANK_POWERDOWN;
panel->backlight->props.state |= BL_CORE_FBBLANK;
backlight_update_status(panel->backlight);
}
}
static int sprd_panel_enable(struct drm_panel *p)
{
... ...
if (panel->backlight) {
panel->backlight->props.power = FB_BLANK_UNBLANK;
panel->backlight->props.state &= ~BL_CORE_FBBLANK;