小公司研发总监,既当司令也当兵!
分类: linux
2016-02-17 20:02:26
原文地址:task_struct解析(一) 进程状态 作者:kenvifire
task_struct 是内核用来表示进程的,包含进程的所有信息,该结构体定义在incluce\linux\sched.h里
首先介绍一下状态信息
volatile long state
这个字段存储的是进程当前的状态
=====================================
volatile关键字是一种类型修饰符,用它声明的类型变量表示可以被某些编译器未知的因素更改,比如:操作系统、硬件或者其它线程等。遇到这个关键字声明的变量,编译器对访问该变量的代码就不再进行优化,从而可以提供对特殊地址的稳定访问。
具体参见:
=====================================
/*
* 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语句中时,会导致编译不通过。
具体跟过应用参见
===========================================================
#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值被后面的代码改写
具体内存边界相关内容参见
====================================================================
设置进程当前状态的宏
/*
* 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)
前者不带内存屏障,后者是带内存屏障的,即是前者的指令是串行执行的,后者可能是乱序的
=====================================================================================