syscore.c 源码分析

来源:互联网 发布:下载一亩田软件 编辑:程序博客网 时间:2024/04/30 09:53
AUTHOR: Joseph Yang (杨红刚) <ganggexiongqi@gmail.com>
CONTENT: syscore.c 源码分析
NOTE: linux-3.0
LAST MODIFIED:09-09-2011
-----------------------------------------------------------------------------------------------------------
Distributed and Embedded System Lab (分布式嵌入式系统实验室,兰州大学)
================================================================
   ------  函数列表:
register_syscore_ops
unregister_syscore_ops
syscore_suspend
syscore_resume
syscore_shutdown
 --------- 重要的结构和变量
struct syscore_ops {
    struct list_head node;
    int (*suspend)(void);
    void (*resume)(void);
    void (*shutdown)(void);
};

static LIST_HEAD(syscore_ops_list);
static DEFINE_MUTEX(syscore_ops_lock);
 ------- 具体函数的分析
 1.
 /**
 * register_syscore_ops - Register a set of system core operations.
 * @ops: System core operations to register.
 */
void register_syscore_ops(struct syscore_ops *ops);
功能:
流程:        将ops添加到 syscore_ops_list //list_add_tail

2.
/**
 * unregister_syscore_ops - Unregister a set of system core operations.
 * @ops: System core operations to unregister.
 */
void unregister_syscore_ops(struct syscore_ops *ops);
功能:
流程:        将ops从 syscore_ops_list 中删除//list_del

3.
/**
 * syscore_suspend - Execute all the registered system core suspend callbacks.
 *
 * This function is executed with one CPU on-line and disabled interrupts.
 */
int syscore_suspend(void);
功能:
流程:
          如果有挂起的唤醒中断,则返回错误//check_wakeup_irqs
          如果没有关闭中断,则打印警告信息 //WARN_ONCE
           
           从尾部开始逆向遍历整个双向链表 syscore_ops_list //从这里可以看出,最后注册的操作,先执行
                      如果每个结点的suspend函数域不为空,则运行它
                      如果没有关闭中断,则打印警告信息 //WARN_ONCE
            如果发生了错误,则,从发生错误的结点开始顺序遍历链表,执行每个结点的resume      
 4.
 /**
 * syscore_resume - Execute all the registered system core resume callbacks.
 *
 * This function is executed with one CPU on-line and disabled interrupts.
 */
void syscore_resume(void);
功能:
流程:
           如果有挂起的唤醒中断,则返回错误//check_wakeup_irqs
          如果没有关闭中断,则打印警告信息 //WARN_ONCE
           
           从头部开始顺序遍历整个双向链表 syscore_ops_list  
                      如果每个结点的resume函数域不为空,则运行它
                      如果没有关闭中断,则打印警告信息 //WARN_ONCE             
                      
 5.
 /**    
 * syscore_shutdown - Execute all the registered system core shutdown callbacks.         
 */    
void syscore_shutdown(void);
功能:
流程:
      取得syscore_ops_lock锁 //mutex_lock
            从头部开始顺序遍历整个双向链表 syscore_ops_list  
                      如果每个结点的resume函数域不为空,则运行它
      释放syscore_ops_lock锁 // mutex_unlock     
      
   ------------------ 涉及到的宏的分析   
   #define WARN_ONCE(condition, format...) ({          \ //条件为真时,打印处文件名和行号format
    static bool __warned;                   \
    int __ret_warn_once = !!(condition);            \
                                \
    if (unlikely(__ret_warn_once))              \
        if (WARN(!__warned, format))            \
            __warned = true;            \
    unlikely(__ret_warn_once);              \
 })


#ifndef WARN
#define WARN(condition, format...) ({                       \
    int __ret_warn_on = !!(condition);              \  //执行条件,并取得返回值
    if (unlikely(__ret_warn_on))                    \    //如果__ret_warn_on为真,则打印format和文件名和行号
        __WARN_printf(format);                  \
    unlikely(__ret_warn_on);                    \
})
#endif

#define __WARN_printf(arg...)   warn_slowpath_fmt(__FILE__, __LINE__, arg) //打印文件名和行号
       
extern void warn_slowpath_fmt(const char *file, const int line,
        const char *fmt, ...) __attribute__((format(printf, 3, 4)));
        
 -------------------------------
 
 /**
 * list_for_each_entry_reverse - iterate backwards 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_struct within the struct.
 */
#define list_for_each_entry_reverse(pos, head, member)          \
    for (pos = list_entry((head)->prev, typeof(*pos), member);  \
         &pos->member != (head);    \
         pos = list_entry(pos->member.prev, typeof(*pos), member))

/**
 * list_entry - get the struct for this entry // 得到struct list_head 所在结构体变量的指针
 * @ptr:    the &struct list_head pointer.
 * @type:   the type of the struct this is embedded in.
 * @member: the name of the list_struct within the struct.
 */
#define list_entry(ptr, type, member) \  
    container_of(ptr, type, member)
 -----------------------
 #define irqs_disabled()                 \ //如果中断标志位关闭,则返回“真“
    ({                      \
        unsigned long _flags;           \
        raw_local_save_flags(_flags);       \//获取FLAGS寄存器的内容
        raw_irqs_disabled_flags(_flags);    \ //取得flags中中断位取返后的值
    })      
    
#define raw_local_save_flags(flags)         \
    do {                        \
        typecheck(unsigned long, flags);    \
        flags = arch_local_save_flags();    \ //获取FLAGS寄存器的内容
    } while (0)

#define raw_irqs_disabled_flags(flags)          \
    ({                      \
        typecheck(unsigned long, flags);    \
        arch_irqs_disabled_flags(flags);    \ //取得flags中中断位取返后的值
    })
static inline int arch_irqs_disabled_flags(unsigned long flags) //取得flags中中断位取返后的值
{
    return !(flags & X86_EFLAGS_IF);
}

原创粉丝点击