|
|
HP-UX Process Management: White Paper > Chapter 1 Process ManagementProcess Scheduling |
|
To understand how threads of a process run, we have to understand how they are scheduled. Although processes appear to the user to run simultaneously, in fact a single processor is executing only one thread of execution at any given moment. Several factors contribute to process scheduling:
HP-UX scheduling is governed by policy that connotes the urgency for which the CPU is needed, as either timeshare or real-time. The following table compares the two policies in very general terms. Table 1-20 Comparison of Timeshare vs Real-time scheduling
The principle behind the distribution of CPU time is called a timeslice. A timeslice is the amount of time a process can run before the kernel checks to see if there is an equal or stronger priority process ready to run.
Scheduling policies act upon sets of thread lists, one thread list for each priority. Any runnable thread may be in any thread list. Multiple scheduling policies are provided. Each nonempty list is ordered, and contains a head (th_link) as one end of its order and a tail (th_rlink) as the other. The purpose of a scheduling policy is to define the allowable operations on this set of lists (for example, moving threads between and within lists). Each thread is controlled by an associated scheduling policy and priority. Applications can specify these parameters by explicitly executing the sched_setscheduler() or sched_setparam() functions. All POSIX real-time priority threads have greater scheduling importance than threads with HP-UX real-time or HP-UX timeshare priority. By comparison, all HP-UX real-time priority threads are of greater scheduling importance than HP-UX timeshare priority threads, but are of lesser importance than POSIX real-time threads. Neither POSIX nor HP-UX real-time threads are subject to degradation. This will be demonstrated in detail shortly. As of release 10.0, HP-UX implements four schedulers, two time-share and two real-time. To choose a scheduler, you can use the user command, rtsched(1), which executes processes with your choice of scheduler and enables you to change the real-time priority of currently executing process ID. rtsched -s scheduler -p priority command [arguments] rtsched [ -s scheduler ] -p priority -P pid Likewise, the system call rtsched(2) provides programmatic access to POSIX real-time scheduling operations. The RTSCHED POSIX-compliant real-time deterministic scheduler provides three scheduling policies, whose characteristics are compared in the following table. Table 1-21 RTSCHED policies
Realtime scheduling policy with nondecaying priorities (like SCHED_FIFO and SCHED_RR) with a priority range between the POSIX real-time policies and the HP-UX policies. For threads executing under this policy, the implementation must use only priorities within the range returned by the functions sched_get_priority_max() and sched_get_priority_min() when SCHED_RTPRIO is provided as the parameter.
The strongest priority in the priority range for SCHED_RTPRIO is weaker than the weakest priority in the priority ranges for any of the POSIX policies, SCHED_FIFO, SCHED_RR, and SCHED_RR2. The SCHED_OTHER policy, also known as SCHED_HPUX and SCHED_TIMESHARE, provides a way for applications to indicate, in a portable way, that they no longer need a real-time scheduling policy. For threads executing under this policy, the implementation can use only priorities within the range returned by the functions sched_get_priority_max() and sched_get_priority_min() when SCHED_OTHER is provided as the parameter. Note that for the SCHED_OTHER scheduling policy, like SCHED_RTPRIO, smaller numbers represent higher (stronger) priorities, which is the opposite of the POSIX scheduling policies. This is done to provide continuing support for existing applications that depend on this priority ordering. However, it is guaranteed that the priority range for the SCHED_OTHER scheduling policy is properly disjoint from the priority ranges of all of the other scheduling policies described and the strongest priority in the priority range for SCHED_OTHER is weaker than the weakest priority in the priority ranges for any of the other policies, SCHED_FIFO, SCHED_RR, and SCHED_RR2. The Process Resource Manager (PRM) is an optional HP-UX product coded into the kernel as fss, or Fair Share Scheduler. This time-share scheduler operates on timeshare processes. Real-time processes (RTPRIO and POSIX real-time) are not affected by the fss, but they do affect it, because the fss allocates portions of the CPU to different groups of processes. Unlike the default SCHED_HPUX scheduler, the Process Resource Manager allows the system administrator to budget CPU time to groups of processes with a high degree of specificity. The remainder of this section will not be dealing with the ramifications of the PRM. All processes have a priority, set when the process is invoked and based on factors such as whether the process is running on behalf of user or system and whether the process is created in a time-share or real-time environment. Associated with each policy is a priority range. The priority ranges foreach policy can (but need not) overlap the priority ranges of other policies. Two separate ranges of priorities exist: a range of POSIX standard priorities and a range of other HP-UX priorities. The POSIX standard priorities are always higher than all other HP-UX priorities. Processes are chosen by the scheduler to execute a time-slice based on priority. Priorities range from highest priority to lowest priority and are classified by need. The thread selected to run is at the head of the highest priority nonempty thread list. With the implementation of the POSIX rtsched, HP-UX priorities are enumerated from two perspectives -- internal and external priority values.
In addition, legacy HP-UX priority values are ranked in opposite sequence from POSIX priority values:
The following macros are defined in pm_rtsched.h to enable a program to convert between POSIX and HP-UX priorities and internal to external values:
A configurable parameter, rtsched_numpri, controls:
Increasing rtsched_numpri provides more scheduling priorities at the cost of increased context switch time, and to a minor degree, increased memory consumption. There are now four sets of thread priorities: (Internal to External View) Table 1-22 Scheduler priority values
The following figure demonstrates the relationship of the three schedulers ranked by priority and strength. The following lists categories of priority, from highest to lowest:
The kernel can alter the priority of time-share priorities (128-255) but not real-time priorities (0-127). The following priority values, internal to the kernel, are defined in param.h:
Priorities stronger (smaller number) than or equal to PZERO cannot be signaled. Priorities weaker (bigger number) than PZERO can be signaled. The following discussion illustrates the HP-UX internal view, based on how the user specifies a priority to the rtsched command. Each available real-time scheduler policy has a range of priorities (default values shown below).
The user may invoke the rtsched(1) command to assign a scheduler policy and priority. For example, rtsched -s SCHED_RR -p 31 ls Within kernel mode sched_setparam() is called to set the scheduling parameters of a process. It (along with sched_setscheduler()) is the mechanism by which a process changes its (or another process') scheduling parameters. Presently the only scheduling parameter is priority, sched_priority. The sched_setparam() and sched_setscheduler() system calls look up the process associated with the user argument pid, and call the internal routine sched_setcommon() to complete the execution. sched_setcommon() is the common code for sched_setparam() and sched_setscheduler(). It modifies the threads scheduling priority and policy. The scheduler information for a thread is kept in its thread structure. It is used by the scheduling code, particularly setrq(), to decide when the thread runs, with respect to the other threads in the system. sched_setcommon() is called with the sched_lock held. sched_setcommon() calls the macro PRI_ExtPOSIXPri_To_IntHpuxPri, defined in pm_rtsched.h. The priority requested is then converted. Since priorities in HP-UX are stronger for smaller values, and the POSIX specification requires the opposite behavior, we merge the two by running the rtsched priorities from ((MAX_RTSCHED_PRI-1) - rtsched_info.rts_numpri) (strongest) to (MAX_RTSCHED_PRI-1) (weakest). Based on the macro definition using the value passed by the user, the internal value seen by the kernel is calculated as follows: ((MAX_RTSCHED_PRI - 1) - (ExtP_pri)) 512 - 1 - 31 = 480 The kernel priority of the user's process is 480. The value of 480 is the strongest priority available to the user. |
|