task_struct源码解读

task_struct英文源码原文

以下是中文以及解释:(未完待续,慢慢敲)

1.

/* Used in tsk->state: */
#define TASK_RUNNING            0x0000//进程要么正在执行,要么准备执行,内核中有一个队列,里面都是等待执行的进程。
#define TASK_INTERRUPTIBLE      0x0001 //可中断的睡眠,可以通过一个信号唤醒
#define TASK_UNINTERRUPTIBLE        0x0002//不可中断睡眠,不可以通过信号进行唤醒
#define __TASK_STOPPED          0x0004 //进程停止执行,在进程接收到 SIGTTIN、SIGSTOP、SIGTSTP、STGTTOU信号后会进入此状态
#define __TASK_TRACED           0x0008//进程被追踪,被 debugger 等进程监视。
/* Used in tsk->exit_state: */
#define EXIT_DEAD           0x0010//僵尸状态的进程,表示进程被终止,但是父进程还没有获取它的终止信息,比如进程有没有执行完等信息。 
#define EXIT_ZOMBIE         0x0020//进程的最终状态,进程死亡
#define EXIT_TRACE          (EXIT_ZOMBIE | EXIT_DEAD)
/* Used in tsk->state again: */
#define TASK_PARKED         0x0040//停放状态
#define TASK_DEAD           0x0080//死亡,最终状态
#define TASK_WAKEKILL           0x0100//唤醒并杀死的进程
#define TASK_WAKING         0x0200//唤醒进程
#define TASK_NOLOAD         0x0400//空载状态
#define TASK_NEW            0x0800//新的状态
#define TASK_STATE_MAX          0x1000//任务状态的最大值

2. 

/* 为set_task_state提供便利的宏 */
#define TASK_KILLABLE           (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED            (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_TRACED         (TASK_WAKEKILL | __TASK_TRACED)
 
#define TASK_IDLE           (TASK_UNINTERRUPTIBLE | TASK_NOLOAD)
 
/* 为了方便唤醒而使用的便利宏 */
#define TASK_NORMAL         (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
 
/* get_task_state(): 获取任务的状态*/
#define TASK_REPORT         (TASK_RUNNING | TASK_INTERRUPTIBLE | \
                     TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \
                     __TASK_TRACED | EXIT_DEAD | EXIT_ZOMBIE | \
                     TASK_PARKED)
 
#define task_is_traced(task)        ((task->state & __TASK_TRACED) != 0)
 
#define task_is_stopped(task)       ((task->state & __TASK_STOPPED) != 0)
 
#define task_is_stopped_or_traced(task) ((task->state & (__TASK_STOPPED | __TASK_TRACED)) != 0)
 
#define task_contributes_to_load(task)  ((task->state & TASK_UNINTERRUPTIBLE) != 0 && \
                     (task->flags & PF_FROZEN) == 0 && \
                     (task->state & TASK_NOLOAD) == 0)

3.#ifdef CONFIG_DEBUG_ATOMIC_SLEEP  这个宏的实际含义不大,要是深究的话解释连接在这里

# define might_sleep() do { __might_sleep(__FILE__, __LINE__, 0); might_resched(); } while (0)

在当前CONFIG_DEBUG_ATOMIC_SLEEP选项使能的前提下, 可以看到__might_sleep还是干了不少事情的,最主要的工作是在第一个if语句那里,尤其是preempt_count_equals和 irqs_disabled,都是用来判断当前的上下文是否是一个atomic context,因为我们知道,只要进程获得了spin_lock的任一个变种形式的lock,那么无论是单处理器系统还是多处理器系统,都会导致 preempt_count发生变化,而irq_disabled则是用来判断当前中断是否开启。__might_sleep正是根据这些信息来判断当前正在执行的代码上下文是否是个atomic,如果不是,那么函数就直接返回了,因为一切正常。如果是,那么代码下行。
所以让CONFIG_DEBUG_ATOMIC_SLEEP选项打开,可以捕捉到在一个atomic context中是否发生了sleep,如果你的代码不小心在某处的确出现了这种情形,那么might_sleep会通过后续的printk以及dump_stack来协助你发现这种情形。

extern enum system_states {
    SYSTEM_BOOTING,
    SYSTEM_RUNNING,
    SYSTEM_HALT,
    SYSTEM_POWER_OFF,
    SYSTEM_RESTART,
    SYSTEM_SUSPEND_DISK,
} system_state;

  最常见的状态当然是SYSTEM_RUNNING了,你的系统正常起来之后就处于这个状态。因为跟当前的话题没有直接的关联,这里只提一下好了。

4.设置当前task和特殊task的状态,特殊状态是不使用常规等待循环模式的状态。 参见带有set_special_state()的注释。

#define is_special_task_state(state)                \
    ((state) & (__TASK_STOPPED | __TASK_TRACED | TASK_PARKED | TASK_DEAD))
 
#define __set_current_state(state_value)            \
    do {                            \
        WARN_ON_ONCE(is_special_task_state(state_value));\
        current->task_state_change = _THIS_IP_;      \
        current->state = (state_value);          \
    } while (0)
 
#define set_current_state(state_value)              \
    do {                            \
        WARN_ON_ONCE(is_special_task_state(state_value));\
        current->task_state_change = _THIS_IP_;      \
        smp_store_mb(current->state, (state_value)); \
    } while (0)
 
#define set_special_state(state_value)                  \
    do {                                \
        unsigned long flags; /* may shadow */           \
        WARN_ON_ONCE(!is_special_task_state(state_value));  \
        raw_spin_lock_irqsave(&current->pi_lock, flags); \
        current->task_state_change = _THIS_IP_;          \
        current->state = (state_value);              \
        raw_spin_unlock_irqrestore(&current->pi_lock, flags);    \
    } while (0)

  

posted @ 2019-12-14 19:34  Smah  阅读(1035)  评论(0编辑  收藏  举报