HPlogo HP-UX Process Management: White Paper > Chapter 1 Process Management

Process Management Structures

» 

Technical documentation

Complete book in PDF

 » Table of Contents

The process management system contains the kernel's scheduling subsystem and interprocess communication (IPC) subsystem.

The process management system interacts with the memory management system to make use of virtual memory space. The process control system interacts with the file system when reading files into memory before executing them.

Processes communicate with other processes via shared memory or system calls. Communication between processes (IPC) includes asynchronous signaling of events and synchronous transmission of messages between processes. System calls are requests by a process for some service from the kernel, such as I/O, process coordination, system status, and data exchange.

The effort of coordinating the aspects of a process in and out of execution is handled by a complex of process management structures in the kernel. Every process has an entry in a kernel process table and a uarea structure, which contains private data such as control and status information. The context of a process is defined by all the unique elements identifying it -- the contents of its user and kernel stacks, values of its registers, data structures, and variables -- and is tracked in the process management structures.

Process management code is divided into external interface and internal implementation parts. The proc_iface.h defines the interface, contains the utility and access functions, external interface types, utility macros. The proc_private.h defines the implementation, contains internal functions, types, and macros.

Kernel threads code is similarly organized into kthread_iface.h and kthread_private.h.

The next figure shows process management structures. In the table that follows, the structures are identified and summarized. In the sections that follow, we will examine the most important characteristics of each structure

Figure 1-19 Process structure, virtual layout overview

[Process structure, virtual layout overview]

Table 1-12 Principal structures of process management

StructurePurpose
proc tableAllocated at boot time; remains resident in memory (non-swappable). For every process contains an entry of the process's status, signal, and size information, as well as per-process data that is shared by the kernel thread
kthread structureOne of two structures representing the kernel thread (the other is the user structure). Contains the scheduling, priority, state, CPU usage information of a kernel thread. Remains resident in memory.
vasThe vas structure contains all the information about a process's virtual space. It is dynamically allocated as needed and is memory resident.
pregionContains process and thread information about use of virtual address space for text, data, stack, and shared memory, including page count, protections, and starting addresses of each.
uareaUser structure contains the per-thread data that is swappable.

 

proc Table

The proc table is comprised of identifying and functional information about every individual process. Each active process has a proc table entry, which includes information on process identification, process threads, process state, process priority and process signal handling. The table resides in memory and may not be swapped, as it must be accessable by the kernel at all times.

Definitions for the proc table are found in the proc_private.h header file.

Figure 1-20 The proc Table

[The proc Table]

Table 1-13 Principal fields in the proc structure

Type of FieldName and Purpose
Process identification

Process ID ( p_pid)

Parent process ID ( p_ppid)

Read user ID ( p_uid) used to direct tty signals

Process group ID (p_pgrp)

Pointer to the pgroup structure (*p_pgrp_p)

Maximum number of open files allowed (p_max)

Pointer to the region containing the uarea (p_upreg)

threads

Values for first and subsequent threads (p_created_threads)

Pointer to first and last thread in the process (p_firstthreadp, p_lastthreadp)

Number of live threads in the process, excluding zombies (p_livethreads)

List of cached threads (*p_cached_threads)

process state

Current process state (p_stat)

Priority (p_pri)

Per-process flags ( p_flag)

process signaling

Signals pending on the process (p_sig)

Active list of pending signals (*p_ksiactive)

Signals being ignored ( p_sigignore )

Signals being caught by user ( p_sigcatch)

Number of signals recognized by process (p_nsig)

Locking information

Thread lock for all threads (*thread_lock)

Per-process lock(*p_lock)

 

Kernel Thread Structure

Figure 1-21 Kernel threads

[Kernel threads]

Each process has an entry in the proc table; this information is shared by all kernel threads within the process.

One kernel thread structure (kthread) is allocated per active thread. The kthread structure is not swappable. It contains all thread-specific data needed while the thread is swapped out, including process ID, pointer to the process address space, file descriptors, current directory, UID, and GID. Other per-thread data (in user.h) is swapped with the thread.

Information shared by all threads within a process is stored in the proc structure, rather than the kthread structure. The kthread structure contains a pointer to its associated proc structure. (In a multi-threads environment the kthread would point to other threads that make up the process and controlled by a threads listing maintained in the proc table.)

In a threads-based kernel, the run and sleep queues consist of kthreads instead of processes. Each kthread contains forward and backward pointers for traversing these queues. All schedule-related attributes, such as priority and states, are kept at the threads level.

Definitions for the kernel threads structure are found in the kthread_private.h header file include general information, scheduling information, CPU affinity information, state and flag information, and signal information.

Table 1-14 Principal entries in kernel thread structure

Entry in struct kthreadPurpose
*kt_link, *kt_rlinkpointers to forward run/sleep queue link and backward run queue link
*kt_procpPointer to proc structure
kt_fandx, kt_pandxFree active and kthread structure indices
kt_nextp, kt_prevpOther threads in the same process
kt_flag, kt_flag2Per-thread flags
kt_cntxt_flagsthread context flags
kt_fractioncpufraction of cpu during recent p_deactime
kt_wchanEvent thread is sleeping on
*kt_upregpointer to the pregion containing the uarea
kt_deactimeseconds since last deact or react
kt_sleeptimeseconds since last sleep or wakeup
kt_usrpriUser priority (based on kt_cpu and p_nice)
kt_pripriority (lower numbers are stronger)
kt_cpudecaying cpu usage for scheduling
kt_statCurrent thead state
kt_cursignumber of current pending signal, if any
kt_spuSPU number to which thread is assigned
kt_spu_wantedpreference to desired SPU
kt_spu_groupSPU group to which thread is associated
kt_spu_mandatory;kt_sleep_typeAssignment as to whether SPU is mandatory or advisory; directive to wake up all or one SPU
kt_sync_flagReader synchronization flags
kt_interruptibleIs the thread interruptible?
kt_wake_suspendIs a resource waiting for the thread to suspend?
kt_activeIs the thread alive?
kt_haltedIs the thread halted cleanly?
kt_tidunique thread ID
kt_user_suspcnt, kt_user_stopcntuser-initiated suspend and job-control stop counts
kt_suspendcntSuspend count
*kt_krusagepPointer to kernel resource usages

kt_usertime;

kt_systemtime;

kt_interrupttime

Machine cycles spent in user-mode, system mode and handling interrupts.
kt_sigsignals pending to the thread
kt_sigmaskCurrent signal mask
kt_schedpolicyscheduling policy for the thread
kt_ticksleftRound-robin clock ticks left
*kt_timersPointer to thread's timer structures
*kt_slinkPointer to linked list of sleeping threads
*kt_semaHead of per-thread alpha semaphore list
*kt_msem_infoPointer to msemaphore info structure
*kt_chanq_infopPointer to channel queue info structure
kt_dil_signalSignal to use for DIL interrupts
*kt_credPointer to user credentials[1]
*kt_cdir, *kt_rdirCurent and root directories of current thread, as shown in struct vnode
*kt_fpCurrent file pointer to struct file.
*kt_link, *kt_rlinkpointers to forward run/sleep queue link and backward run queue link

[1] UID, GID, and other credentials are pointed to as a snapshot of the process-wide cred structures when the thread enters the kernel. These are only valid when a thread operates in kernel mode. Permanent changes to the cred structure (e.g., setuid()) should be made to the cred structure pointed to by the proc structure element p_cred.

 

vas structure

Figure 1-22 Role of the vas structure

[Role of the vas structure]

Every process has a proc entry containing a pointer (p_vas) to the process's virtual address space. The vas maintains a doubly linked list of pregions that belong to a given process and thread. The vas is always memory resident and provides information based on the process's virtual address space.

NOTE: Do not confuse the vas structure with virtual address space (VAS) in memory. The vas structure is a few bytes; VAS is 4 gigabytes.

The following table (derived from vas.h) shows the principal entries in struct vas.

Table 1-15 Entries in vas structure

Entry in struct vasPurpose
va_llDoubly linked list of pregions
va_refcntNumber of pointers to the vas
va_rss, va_prss, va_dprssCached approximation of shared and private resident set size, and private RSS in memory and on swap
*va_procPointer to existing process in struct proc
va_flagsVarious flags (itemized after this table)
va_wcountnumber of writable memory-mapped files sharing pseudo-vas
va_vaslockfield in struct rw_lock that controls access to vas
*va_credPointer to process credentials in struct ucred
va_hdlvas hardware-dependent information
va_ki_vssTotal virtual memory
va_ki_flagIndication of whether vss has changed
va_ucountTotal virtual memory of user space.

 

The following definitions correspond to va_flags:

VA_HOLES

vas might have holes within pregions

VA_IOMAP

IOMAP pregion within the vas

VA_WRTEXT

writable text

VA_PSEUDO

pseudo vas, not a process vas

VA_MULTITHEADED

vas conected to a multithreaded process

VA_MCL_FUTURE

new pages that must be mlocked

VA_Q2SHARED

quadrant 2 used for shared data

Pregion Structure

Figure 1-23 pregion in context

[pregion in context]

The pregion represents an active part of the process's Virtual Address Space (VAS). This may consist of the text, data, stack, and shared memory. A pregion is memory resident and dynamically allocated as needed. Each process has a number of pregions that describe the regions attached to the process. In this module we will only discuss to the pregion level. The HP-UX Memory Management white paper provides more information about regions.

Table 1-16 pregion types

TypeDefinition
PT_UNUSEDunused pregion
PT_UAREAUser area
PT_TEXTText region
PT_DATAData region
PT_STACKStack region
PT_SHMEMShared memory region
PT_NULLDREFNull pointer dereference
PT_SIGSTACKSignal stack
PT_IOI/O region

 

These pregion types are defined based on the value of p_type within the pregion structure and can be useful to determine characteristics of a given process. This may be accessed via the kt_upreg pointer in the thread table. A process has a minimum of four defined pregions, under normal conditions. The total number of pregion types defined may be identified with the definition PT_NTYPES.

Figure 1-24 Example of four possible pregions

[Example of four possible pregions]

Table 1-17 Entries comprising a pregion

TypePurpose
Structure information

Pointers to next and previous pregions.

Pointer and offset into the region.

Virtual space and offset for region.

Number of pages mapped by the pregion.

Pointer to the VAS.

Flags and typeReferenced by p_flags and p_type.
Scheduling information

Remaining pages to age (p_ageremain).

Indices of next scans for vhand's age and steal hands (p_agescan, p_steadscan).

Best nice value for all processes sharing the region used by the pregion (p_bestnice).

Sleep address for deactivation (p_deactsleep).

Thread information

Value to identify thread, for uarea pregion (p_tid).

 

Traversing pregion Skip List

Pregion linked lists can get quite large if a process is using many discrete memory-mapped pregions. When this happens, the kernel spends a lot of time walking the pregion list. To avoid the list being walked linearly, we use skip lists,[1] which enable HP-UX to use four forward links instead of one. These are found in the beginning of the vas and pregion structures, in the p_ll element.

User Structures (uarea)

The user area is a per-process structure containing data not needed in core when a process is swapped out.

The threads of a process point to the pregion containing the process's user structure, which consists of the uarea and kernel stack. The user structure contains the information necessary to the execution of a system call by a thread. The kernel thread's uarea is special in that it resides in the same address space as the process data, heap, private MMFs, and user stack. In a multi-threaded environment, each kernel thread is given a separate space for its uarea.

Each thread has a separate kernel stack.

Addressing the uarea is analogous to the prior process-based kernel structure. A kernel thread references its own uarea through struct user. However, you cannot index directly into the user structure as is possible into the proc table. The only way into the uarea is through the kt_upreg pointer in the thread table.

Figure 1-25 User area (uarea) in a thread-structured system

[User area (uarea) in a thread-structured system]

Table 1-18 Principal entries in the uarea (struct user)

TypePurpose
user structure pointers

Pointers to proc and thread structures (u_procp, u_kthreadp).

Pointers to saved state and most recent savestate (u_sstatep,u_pfaultssp).

system call fields

Arguments to current system call (u_arg[]).

Pointer to the arglist (u_ap).

Return error code (u_error).

System call return values (r_val(n)).

signal management

Signals to take on sigstack (u_sigonstack).

Saved mask from before sigpause (u_oldmask).

Code to trap (u_code).

 

The user credentials pointer (for uid, gid, etc) has been moved from the uarea and is now accessed through the p_cred() accessor for the proc structure and the kt_cred()accessor for the kthread structure. See comments under the kt_cred() field in kthread.h for details governing usage.

Process Control Block (pcb)

NOTE: HP-UX now handles context switching on a per-thread basis.

A process control block (pcb) is maintained in the user structure of each kernel thread as a repository for thread scheduling information. The pcb contains all the register states of a kernel thread that are saved or restored during a context switch from one threads environment to another.

The context of a current running thread is saved in its associated uarea pcb when a call to swtch() is made. The save() routine saves the current thread state in the pcb on the switch out. The resume() routine maps the user-area of the newly selected thread and restores the process registers from the pcb. When we return from resume(), the selected thread becomes the currently running thread and its uarea is automatically mapped into the virtual memory address of the system's global uarea.

The register's context includes:

  • General-purpose Registers

  • Space registers

  • Control registers

  • Instruction Address Queues (Program Counter)

  • Processor Status Word (PSW)

  • Floating point register

Table 1-19 Contents of theProcess Control Block (pcb)

Context elementPurpose

General registers

pcb_r1 --> pcb_r31

[GR0 - GR31]

Thirty two general registers that provide the central resource for all computation. These are available for programs at all privilege levels.

Space registers

pcb_sr0 --> pcb_sr7

[SR0 - SR7]

Eight space ID registers for virtual addressing.
Control registers
pcb_cr0 --> pcb_cr31
[CR0,CR8 - CR31]
Twenty-five control registers that contain system state information.

Program counters

( pcb_pc)

Two registers that hold the virtual address of the current and next instruction to be executed.

  • The Instruction Address Offset Queue (IAOQ) is 32 bits long. The upper 30 bits contain the work offset of the instruction and the lower 2 bits maintain the privilege level of the corresponding instruction.

  • The Instruction Address Space Queue(IASQ) is 32 bits long in a PA-RISC 2.0 (64-bit) system or 16 bits a PA-RISC 1.x (32-bit) system. Contains the Space ID for instructions

Processor Status Word (pcb_psw)Contains the machine level status that relates to a process as it does operations and computations.
Floating point registers
pcb_fr1 --> pcb_fr32
Maintains the floating point status for the process.

 



[1] Skip lists were developed by William Pugh of the University of Maryland. An article he wrote for CACM can be found at ftp://ftp.cs.umd.edu/pub/skipLists/skiplists.ps.Z.