The kthread Table Originally, HP-UX managed jobs only at the process level, and the proc table contained all information relating to the execution of a process by the kernel. HP-UX 10.0 introduced the kthread structure as a first step toward implementation of a fully threaded kernel environment. Although this was only a first step toward a true multithreaded environment, it initiated the division of static process-related parameters and dynamic thread related values into separate structures. The proc table contains static values and pointers to resources shared equally by all of its threads, while the kthread structure(s) contain dynamic information relating to their execution and runtime environment. First, let's examine the manner in which a proc table entry and its kthreads are linked together. In Figure 5-3, we see this relationship mapped out. The proc table maintains a pointer to the first kthread and last (most recently created) kthread. In addition, a count is kept of all the created threads. Please note that this count is not incremented for the original thread, so a process with a single original thread will show p_created_threads = 0 until the first sibling thread is spawned. Figure 5-3. The kthread Table The kthread structure maintains next/previous links and each sibling kthread has a direct pointer to its parent proc structure entry for quick access. In addition, each kthread has an indirect pointer to a uarea structure via a pregion structure (both of which are discussed later in this chapter). Beginning with HP-UX 11.i, the kthread table is now a dynamic linked list. As with the proc table, entries no longer needed are placed on a free list (as opposed to having their space returned to the kernel memory allocation arena), and new entries are allocated as needed, up to a tunable limit, when the free list is empty. Let's examine the fields of interest in the kthread structure, shown in Listing 5.2. Listing 5.2. q4> fields struct kthread These forward and reverse links are used to place a thread into an appropriate run or sleep queue 0 0 4 0 * kt_link 4 0 4 0 * kt_rlink As we mentioned, each kthread has a direct pointer to its proc structure and its uarea 8 0 4 0 * kt_procp 52 0 4 0 * kt_upreg SMP systems make use of this spinlock to synchronize access to this structure 12 0 4 0 * kt_lock Next we see forward and previous linkage pointers connecting all the active kthreads 16 0 4 0 * kt_factp 20 0 4 0 * kt_pactp All the sibling threads of a single process are linked through these two pointers. 24 0 4 0 * kt_nextp 28 0 4 0 * kt_prevp All kthread structures are linked to a global kthread list 64 0 4 0 * kt_global_kthread Thread status and flag values for the thread (see enum kthread_flag in kthread_private.h) 32 0 4 0 enum4 kt_flag 36 0 4 0 enum4 kt_cntxt_flags 44 0 4 0 enum4 kt_stat 180 0 4 0 enum4 kt_flag2 184 0 4 0 enum4 kt_flag_tl Waiting threads maintain a sleep wait channel pointer and a forward and reverse pointer into a wait list (used by I/O drivers) 48 0 4 0 * kt_wchan 236 0 4 0 * kt_wait_list 240 0 4 0 * kt_rwait_list In addition, a reference count, the most recent user mode priority, the current internal priority, a thread id number, the current scheduling policy, number of ticks left before a voluntary timeslice will be requested, and the mysterious kt_cpu weighting factor (covered later) are maintained 72 0 4 0 int kt_refcnt 76 0 4 0 int kt_deactime 80 0 4 0 int kt_sleeptime 84 0 2 0 u_short kt_usrpri 86 0 2 0 u_short kt_pri 124 0 4 0 int kt_tid 196 0 4 0 u_int kt_schedpolicy 200 0 4 0 int kt_ticksleft 88 0 1 0 u_char kt_cpu There are additional parameters that are used during MP load balancing, signal handling, and IPC services. The next stop on our tour is the vas structure. |