欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

【内核原理与实现 004】KPROCESS 结构体属性介绍

程序员文章站 2022-07-13 10:52:00
...
typedef struct _KPROCESS {

    //
    // The dispatch header and profile listhead are fairly infrequently
    // referenced.
    //

    // 存在 DISPATCHER_HEADER 表明 KPROCESS 是分发器对象,可以被“等待”
    // 所谓等待,就是指某个线程可以调用 WaitForSingleObject 函数来等待这个 KPROCESS ,
    // 然后该线程就会处于阻塞(等待)状态。
    // 进程退出时会变成有信号状态,等待就算成功,线程就继续执行了。
    DISPATCHER_HEADER Header;
    
    // 当该进程参与性能分析时,作为一个节点加入到全局性能分析进程列表 KiProfileListHead 中
    LIST_ENTRY ProfileListHead;

    //
    // The following fields are referenced during context switches.
    //

    // 第一项指向页目录表基址;第二项指向超空间(hyper space)的页目录表基址
    ULONG_PTR DirectoryTableBase[2];

#if defined(_X86_)

    KGDTENTRY LdtDescriptor;		// LDT描述符
    KIDTENTRY Int21Descriptor;		// 21号中断描述符,用于兼容dos的系统调用
    USHORT IopmOffset;				// IOPM(I/O权限表)的偏移
    UCHAR Iopl;						// I/O优先级
    BOOLEAN Unused;

#endif

#if defined(_AMD64_)

    USHORT IopmOffset;

#endif

    // 32位整数,表示当前进程正在哪些处理器上运行
    volatile KAFFINITY ActiveProcessors;

    //
    // The following fields are referenced during clock interrupts.
    //

    // 初始为0,仅当一个线程结束时才更新其进程的这两个时间值
    ULONG KernelTime;	// 所属线程在内核模式下花的时间
    ULONG UserTime;		// 所属线程在用户模式下花的时间

    //
    // The following fields are referenced infrequently.
    //

    // 当进程被换出内存后,其所属线程一旦就绪,则被挂到此链表中,并要求换入该进程
    // 然后将 ReadyListHead 中的所有线程加入到系统全局就绪链表 KiDispatcherReadyListHead 中
    // 这个操作是在 KiInSwapProcesses 函数中完成的
    LIST_ENTRY ReadyListHead;
    
    // 进程换出内存时,通过此域挂入 KiProcessOutSwapListHead 全局链表
    // 进程换入内存时,通过此域挂入 KiProcessInSwapListHead 全局链表
    SINGLE_LIST_ENTRY SwapListEntry;

#if defined(_X86_)

    // 指向处理 Ctrl+C 中断的函数,仅用于VDM(虚拟DOS机)环境下运行的16位程序
    PVOID VdmTrapcHandler;

#else

    PVOID Reserved1;

#endif

    // 存储了当前进程所有子线程的链表
    LIST_ENTRY ThreadListHead;
    
    // 自旋锁对象,用于对进程数据的同步访问
    KSPIN_LOCK ProcessLock;
    
    // 指定了该进程的线程可以在哪些CPU上运行,这是32或64位整数,每个位都对应一个处理器(或核)
    KAFFINITY Affinity;

    //
    // N.B. The following bit number definitions must match the following
    //      bit field.
    //
    // N.B. These bits can only be written with interlocked operations.
    //

#define KPROCESS_AUTO_ALIGNMENT_BIT 0
#define KPROCESS_DISABLE_BOOST_BIT 1
#define KPROCESS_DISABLE_QUANTUM_BIT 2

    union {
        struct {
            LONG AutoAlignment : 1;		// 内存对齐设置,x86不检查此位
            LONG DisableBoost : 1;		// 优先级提升和时限分配相关
            LONG DisableQuantum : 1;	// 优先级提升和时限分配相关
            LONG ReservedFlags : 29;
        };
   
        LONG ProcessFlags;
    };

    SCHAR BasePriority;				// 线程基本优先级,默认是8
    SCHAR QuantumReset;				// 线程基本时限重置值,默认是6,每次时钟中断减3
    
    // 是否在内存中,共有6种可能的状态:
    // ProcessInMemory 、ProcessOutOfMemory 、ProcessInTransition 、
	// ProcessOutTransition、ProcessInSwap 和ProcessOutSwap
    UCHAR State;
    
    // 线程初始化时,用 ThreadSeed 设置其理想的处理器,然后更新 ThreadSeed 以供下一个线程使用
    UCHAR ThreadSeed;
    
    UCHAR PowerState;	// 记录电源状态
    UCHAR IdealNode;	// 优先处理器节点,进程初始化时设定
    BOOLEAN Visited;	// WRK 未使用
    union {
        KEXECUTE_OPTIONS Flags;
        UCHAR ExecuteOptions;		// 内存执行选项,用于支持NX(内存不可执行)
    };

#if !defined(_X86_) && !defined(_AMD64_)

    PALIGNMENT_EXCEPTION_TABLE AlignmentExceptionTable;

#endif

    ULONG_PTR StackCount;
    
    // 当前系统所有活动进程的链表,链表头是 KiProcessListHead / PsActiveProcessHead
    LIST_ENTRY ProcessListEntry;
} KPROCESS, *PKPROCESS, *PRKPROCESS;