您的位置:首页 > 其它

task_struct解析(一) 进程状态

2012-03-11 09:50 204 查看
task_struct
是内核用来表示进程的,包含进程的所有信息,该结构体定义在incluce\linux\Sched.h里

首先介绍一下状态信息

volatile long state

这个字段存储的是进程当前的状态

=====================================
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。

具体参见:http://www.cppblog.com/mzty/archive/2006/08/08/10959.html
=====================================
/*
* 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
#define TASK_STATE_MAX 512

操作状态的宏
/* Convenience macros for the sake of set_task_state */
#define TASK_KILLABLE (TASK_WAKEKILL | TASK_UNINTERRUPTIBLE)
#define TASK_STOPPED (TASK_WAKEKILL | __TASK_STOPPED)
#define TASK_TRACED (TASK_WAKEKILL | __TASK_TRACED)

/* Convenience macros for the sake of wake_up */
#define TASK_NORMAL (TASK_INTERRUPTIBLE | TASK_UNINTERRUPTIBLE)
#define TASK_ALL (TASK_NORMAL | __TASK_STOPPED | __TASK_TRACED)

/* get_task_state() */
#define TASK_REPORT (TASK_RUNNING | TASK_INTERRUPTIBLE | \
TASK_UNINTERRUPTIBLE | __TASK_STOPPED | \
__TASK_TRACED)

#define task_is_traced(task) ((task->state & __TASK_TRACED) != 0)
#define task_is_stopped(task) ((task->state & __TASK_STOPPED) != 0)
#define task_is_dead(task) ((task)->exit_state != 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_FREEZING) == 0)

#define __set_task_state(tsk, state_value) \
do { (tsk)->state = (state_value); } while (0)
==========================================================
这里do{...}while
的作用是防止在把宏用在if...else语句中时,会导致编译不通过。
具体跟过应用参见http://www.cnblogs.com/flying_bat/archive/2008/01/18/1044693.html
===========================================================

#define set_task_state(tsk, state_value) set_mb((tsk)->state, (state_value))
==================================================================
set_mb宏:
#define set_mb(var, value) do { var = value; mb(); } while (0)
mb()宏:
#define mb()
asm volatile("mfence":::"memory")
mb()宏在不同的系统架构中时不同的,这里取的是x86的架构下的代码
mfence是内存边界的意思,这条指令的作用是在mfence指令前的读写操作当必须在mfence指令后的读写操作前完成。
在这里的作用是,保证var=value的操作在其后续指令之前完成,防止value值被后面的代码改写
具体内存边界相关内容参见http://www.cnitblog.com/yuhensong/archive/2007/07/31/30994.aspx
====================================================================

设置进程当前状态的宏

/*
* set_current_state() includes a barrier so that the write of current->state
* is correctly serialised wrt the caller's subsequent test of whether to
* actually sleep:
*
*
set_current_state(TASK_UNINTERRUPTIBLE);
*
if (do_i_need_to_sleep())
*
schedule();
*
* If the caller does not need such serialisation then use __set_current_state()
*/
#define __set_current_state(state_value)
\
do { current->state = (state_value); } while (0)
#define set_current_state(state_value)
\
set_mb(current->state, (state_value))

====================================================================================
这里定义了两个宏:__set_current_state(state_value)和set_current_state(state_value)
前者不带内存屏障,后者是带内存屏障的,即是前者的指令是串行执行的,后者可能是乱序的
=====================================================================================
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: