//sched.h
---------------------------------------
以下代码是关于task_struct->state的:
*
* Task state bitmask. NOTE! These bits are also
* encoded in fs/proc/array.c: get_task_state().
*
* We have two separate sets of flags: task->state
* is about runnability, while task->exit_state are
* about the task exiting. Confusing, but this way
* modifying one set can't modify the other one by
* mistake.
*/
#define TASK_RUNNING 0
#define TASK_INTERRUPTIBLE 1
#define TASK_UNINTERRUPTIBLE 2
#define __TASK_STOPPED 4
#define __TASK_TRACED 8
/* in tsk->exit_state */
#define EXIT_ZOMBIE 16
#define EXIT_DEAD 32
/* in tsk->state again */
#define TASK_DEAD 64
#define TASK_WAKEKILL 128
#define TASK_WAKING 256 //在wake_up_process()后会置这种状态
#define TASK_STATE_MAX 512
/*
* The task state array is a strange "bitmap" of
* reasons to sleep. Thus "running" is zero, and
* you can test for combinations of others with
* simple bit tests.
*/
//从这里可以看出字符串对应的state
static const char * const task_state_array[] = {
"R (running)", /* 0 */
"S (sleeping)", /* 1 */
"D (disk sleep)", /* 2 */
"T (stopped)", /* 4 */
"t (tracing stop)", /* 8 */
"Z (zombie)", /* 16 */
"X (dead)", /* 32 */
"x (dead)", /* 64 */
"K (wakekill)", /* 128 */
"W (waking)", /* 256 */
};
static inline const char *get_task_state(struct task_struct *tsk)
{
unsigned int state = (tsk->state & TASK_REPORT) | tsk->exit_state;
const char * const *p = &task_state_array[0];
BUILD_BUG_ON(1 + ilog2(TASK_STATE_MAX) != ARRAY_SIZE(task_state_array));
while (state) {
p++;
state >>= 1;
}
return *p;
}
--------------------
WCHAN部分指:进程正在睡眠的内核函数名称
-------------------
task_struct->prio 小于100就是RT进程(realtime),见rt_task()
--------------------
检查睡眠的task有没有收到信号的代码,通常如下:
while (t->task && !signal_pending(current))
;
static inline int signal_pending(struct task_struct *p)
{
return unlikely(test_tsk_thread_flag(p,TIF_SIGPENDING));
//#define TIF_SIGPENDING 0 //验证struct thread_info->flags中的第0位是否是1,如果是1,则说明该task收到信号
}
--------------------------
从struct thread_info->cpu的值可以知道这个task当前驻留在哪个CPU上
-----------
在当前函数的任何地方调用__builtin_return_address(0)并printk返回值,在运行后得到返回值0xc1234568,再用这个值从目标文件中查找到对应的符号(arm-linux-addr2line 0xc1234568 -e vmlinux -f),此符号即为调用当前函数的调用者的函数名。
进程切换
context_switch()