DosSetPrty

From EDM2
Jump to: navigation, search

This call allows a process to change the priority of all the threads of any process; or all the threads of the current process or a child process, as well as any descendants; or a single thread within the current process. When a process changes the priority of threads in other processes, only default priorities are changed.

Syntax

DosSetPrty (Scope, PriorityClass, PriorityDelta, ID)

Parameters

Scope (USHORT) - input 
The extent of the priority change.
0 - All the threads of any process.
1 - All the threads of a process and any descendants. The indicated process must be the current process or a process created by the current process. Detached processes may not be specified. The indicated process may possibly have terminated.
2 - A single thread of the current process.
PriorityClass (USHORT) - input 
Priority class of a process. The values and descriptions are:
0 - No change, leave as is
1 - Idle-time
2 - Regular
3 - Time-critical.
4 - Fixed-high.
PriorityDelta (SHORT) - input 
Delta priority to apply to the process's current base priority level. This value must range from -31 to +31.
ID (USHORT) - input 
A process ID (scope = 0 or 1) or a thread ID (scope = 2). If this operand is equal to zero, the current process or thread is assumed.

Return Code

rc (USHORT) - return
Return code descriptions are:
  • 0 NO_ERROR
  • 303 ERROR_INVALID_PROCID
  • 304 ERROR_INVALID_PDELTA
  • 305 ERROR_NOT_DESCENDANT
  • 307 ERROR_INVALID_PCLASS
  • 308 ERROR_INVALID_SCOPE
  • 309 ERROR_INVALID_THREADID

Remarks

The OS/2 scheduler has a concept of priority classes and levels. DosSetPrty allows threads to move between classes in response to changes in their execution environments. Within each class, a thread's priority level can vary because of a DosSetPrty request or action taken by the system. System-initiated priority variation is performed as a combination of a specific thread's actions and the overall system activity.

A time-critical thread has the highest priority class and executes before any fixed-high, regular, or idle-time threads. A fixed-high thread has a priority class that is lower than time-critical but executes before any regular or idle-time threads.

Time-critical threads have static priorities that are not varied by OS/2. Threads are scheduled in priority order, with round-robin scheduling of threads of equal priority.

For each of the four priority classes, there are 32 distinct priority levels, 0 to +31. Whenever DosSetPrty is issued with a class specification, but no value is specified for PriorityDelta, the base priority level defaults to zero.

The priority level of a process consists of a computed priority value that is based upon the display status (foreground or background) of the process, its recent I/O and processor time-usage history, and other factors. The signed value specified in PriorityDelta is added to the computed priority to produce the actual priority used by the scheduler. The result is restricted to the valid range, based upon the current priority class.

Specifying a higher priority delta allows a thread to obtain better processor scheduling than it normally would. A lower priority delta gives the thread less processor resource than it normally receives.

When used with PriorityClass to change to a different class, the delta value applies to the base priority. A new base level of 0 is assigned the target thread and any PriorityDelta specified is relative to zero.

A process can change the priority of any thread within its current process. However, when a process changes the priority of threads in another process, only those with default priorities are changed. The priority of any thread in another process that has explicitly changed its priority from the default with DosSetPrty is not changed.

The initial thread of execution for an application is given a regular class priority that varies by the system. A thread started with DosCreateThread inherits the priority of the thread in the process that creates it. A child process started by a DosExecPgm call inherits the priority of the thread in the parent process that creates it.

Example Code

The following example illustrates how to obtain the priority of a thread and how to change the priority. The main thread creates Thread2 and allows it to begin executing. Thread2 iterates through a loop that prints a line and then sleeps, relinquishing its time slice to the main thread. After one or two iterations by Thread2, the main thread obtains Thread2's priority information and prints it. It then raises Thread2's priority to fixed-high, and increments the level by ten. Since Thread2 is now at a high priority, it immediately finishes its remaining iterations before relinquishing control on a long sleep; at this point, the main thread re-examines Thread2's priority and reports its new priority level. In this example, it is helpful to understand how the DosSleep calls are used either to relinquish control of the processor, or to keep a thread alive (see DosTimerAsync or DosTimerStart for alternatives to DosSleep).

#define INCL_DOSPROCESS

#include <os2.h>

#define      PRTYC_FIXEDHIGH   4       /* Priority class: fixed-high */
#define      PRTY_DELTA        10      /* Priority delta: increase by 10 */
#define      SEGSIZE           4000    /* Number of bytes requested in segment */
#define      ALLOCFLAGS        0       /* Segment allocation flags - no sharing */
#define      SLEEPSHORT        0L      /* Sleep interval -  5 milliseconds */
#define      SLEEPLONG         20L     /* Sleep interval - 75 milliseconds */
#define      RETURN_CODE       0       /* Return code for DosExit() */


VOID APIENTRY Thread2()
{
  USHORT     i;

  /* Loop with four iterations */
  for(i=1; i<5; i++)
  {
    printf("In Thread2, i is now %d\n", i);

    /** Sleep to relinquish time slice to main thread **/
    DosSleep(SLEEPSHORT);          /* Sleep interval */
  }
  DosExit(EXIT_THREAD,             /* Action code - end a thread */
          RETURN_CODE);            /* Return code */
}

main()
{
  USHORT     Priority;            /* Thread priority */
  USHORT     Class;               /* Priority class */
  USHORT     Level;               /* Priority level */
  SEL        ThreadStackSel;      /* Segment selector for thread stack */
  PBYTE      StackEnd;            /* Ptr. to end of thread stack */
  USHORT     rc;

  /* Allocate segment for thread stack; this is better than just */
  /* declaring an array of bytes to use as a stack.  Make pointer eos. */
  rc = DosAllocSeg(SEGSIZE,                    /* Number of bytes requested */
                   &ThreadStackSel,            /* Segment selector (returned) */
                   ALLOCFLAGS);                /* Allocation flags */
  StackEnd = MAKEP(ThreadStackSel, SEGSIZE-1);

  /* Start Thread2 */
  if(!(DosCreateThread((PFNTHREAD) Thread2,    /* Thread address */
                       &ThreadID,              /* Thread ID (returned) */
                       StackEnd)))             /* End of thread stack */
    printf("Thread2 created.\n");

  /** Sleep to allow Thread2 to execute **/
  if(!(DosSleep(SLEEPLONG)))                       /* Sleep interval */
    printf("Slept a little to let Thread2 execute.\n");

  /** Obtain Thread2's priority information and report it **/
  if(!(rc=DosGetPrty(PRTYS_THREAD,                /* Scope - single thread */
                     &Priority,                   /* Address to put priority */
                     ThreadID)))                  /* ID - thread ID */
  {
    /* Extract priority class and level information */
    Class = HIBYTE(Priority);
    Level = LOBYTE(Priority);
    printf("Thread2: ID is %d, Priority Class is %d and Level is %d\n",
           ThreadID, Class, Level);
  }
  /** Raise Thread2's priority **/
  if(!(rc=DosSetPrty(PRTYS_THREAD,             /* Scope - single thread */
                     PRTYC_FIXEDHIGH,          /* Prty class - fixed-high */
                     PRTY_DELTA,               /* Prty delta - increase by 10 */
                     ThreadID)))               /* ID - thread ID */
  {
    /* Obtain Thread2' new priority information and report it */
    rc=DosGetPrty(PRTYS_THREAD,                /* Scope - single thread */
                  &Priority,                   /* Address to put priority */
                  ThreadID);                   /* ID - thread ID */

    /* Extract priority class and level information */
    Class = HIBYTE(Priority);
    Level = LOBYTE(Priority);
    printf("Thread2: ID is %d, New Priority Class is %d and Level is %d\n",
           ThreadID, Class, Level);
  }
}

Bindings

C

#define INCL_DOSPROCESS

USHORT  rc = DosSetPrty(Scope, PriorityClass, PriorityDelta, ID);

USHORT  Scope;         /* Indicate scope of change */
USHORT  PriorityClass; /* Priority class to set */
SHORT   PriorityDelta; /* Priority delta to apply */
USHORT  ID;            /* Process or thread ID */

USHORT  rc;            /* return code */

MASM

EXTRN  DosSetPrty:FAR
INCL_DOSPROCESS     EQU 1

PUSH   WORD    Scope         ;Indicate scope of change
PUSH   WORD    PriorityClass ;Priority class to set
PUSH   WORD    PriorityDelta ;Priority delta to apply
PUSH   WORD    ID            ;Process or thread ID
CALL   DosSetPrty

Returns WORD