Document revision date: 30 March 2001

## OpenVMS Programming Concepts Manual

Previous | Contents | Index

#### 4.5.1.5 The Suspend Sub-Command

The format for the Suspend sub-command is as follows:

    SYSMAN>class_schedule suspend "class name"

The Suspend sub-command suspends the specified scheduling class. All processes that are part of this scheduling class remain as part of this scheduling class but are granted unlimited CPU time.

#### 4.5.1.6 The Resume Sub-Command

The format of the Resume sub-command is as follows:

    SYSMAN>class_schedule resume "class name"

The Resume sub-command complements the suspend command. You use this command to resume a scheduling class that is currently suspended.

### 4.5.2 The Class Scheduler Database

The class scheduler database is a permanent database that allows OpenVMS to class schedule processes automatically after a system has been booted and rebooted. This database resides on the system disk in SYS$SYSTEM: VMS$CLASS_SCHEDULE.DATA. SYSMAN creates this file as an RMS indexed file when the first scheduling class is created by the SYSMAN command, class_schedule add.

#### 4.5.2.1 The Class Scheduler Database and Process Creation

By using a permanent class scheduler, a process is placed into a scheduling class, if appropriate, at process creation time. When a new process is created, it needs to be determined whether this process belongs to a scheduling class. Since to determine this relies upon data in the SYSUAF file, and the Loginout image already has the process' information from this file, Loginout class schedules the process if it determines that the process belongs to a scheduling class.

There are two other types of processes to consider during process creation: subprocess and detached process. A subprocess becomes part of the same scheduling class as the parent process, even though it may not match the class's criteria. That is, its user and account name and/or UIC may not be part of the class's record. A detached process only joins a scheduling class if it executes the Loginout image (Loginout.exe) during process creation.

Though a process can join a scheduling class at process creation time, you can change or modify its scheduling class during runtime with the SET PROCESS/SCHEDULING_CLASS command.

### 4.5.3 Determining If a Process Is Class Scheduled

You can determine whether a process is class scheduled by the following:

- The SHOW SYSTEM DCL command
- The SYS$GETJPI system service
- The Authorize utility

The SHOW SYSTEM DCL Command

The DCL command, SHOW SYSTEM, with the qualifier, /CLASS = "name", displays processes that belong to a specific scheduling class, or if no name is specified, it displays all class scheduled processes and the name of their scheduling class. The SHOW SYSTEM/FULL command shows the scheduling class name of all processes that are class scheduled.

For more information about the DCL command SHOW SYSTEM, see OpenVMS DCL Dictionary: N--Z.

The SYS$GETJPI System Service

The SYS$GETJPI system service item code, JPI$_CLASS_NAME, returns the name of the scheduling class, as a character string, that this process belongs to. If the process is not class scheduled, then a return length of zero (0) is returned to the caller.

For more information about the SYS$GETJPI system service, see the OpenVMS System Services Reference Manual: A--GETUAI.

The Authorize Utility

When a new user is added to the SYSUAF file, or when a user's record is modified, Authorize searches the class scheduler database file to determine if this user is a member of a scheduling class. If it is, then Authorize displays the following message: UAF-I-SCHEDCLASS, which indicates that the user is a member of a scheduling class.

### 4.5.4 The SYS$SCHED System Service

The SYS$SCHED system service allows you to create a temporary class scheduling database. The processes are class-scheduled by PID, after the process has been created. The SYSMAN interface creates a separate and permanent class scheduling database that schedules you at process creation time. A process cannot belong to both databases, the SYS$SCHED and SYSMAN database. Therefore, the SYS$SCHED system service checks to see if the process to be inserted into a scheduling class is already class scheduled before it attempts to place the specified process into a scheduling class. If it is already class scheduled, then the error message, SS$_INSCHEDCLASS, is returned from SYS$SCHED.

For more information about the SYS$SCHED system service, see the OpenVMS System Services Reference Manual: GETUTC--Z.

## 4.6 Changing Process Name

Use the system service SYS$SETPRN to change the name of your process. SYS$SETPRN can be used only on the calling process. Changing process names might be useful when a lengthy image is being executed. You can change names at significant points in the program; then monitor program execution through the change in process names. You can obtain a process name by calling a SYS$GETJPI routine from within a controlling process, either by pressing the Ctrl/T key sequence if the image is currently executing in your process, or by entering the DCL command SHOW SYSTEM if the program is executing in a detached process.

The following program segment calculates the tax status for a number of households, sorts the households according to tax status, and writes the results to a report file. Because this is a time-consuming process, the program changes the process name at major points so that progress can be monitored.

       .
       .
       .
    ! Calculate approximate tax rates
    STATUS = SYS$SETPRN ('INCTAXES')
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    STATUS = TAX_RATES (TOTAL_HOUSES,
    2                   PERSONS_HOUSE,
    2                   ADULTS_HOUSE,
    2                   INCOME_HOUSE,
    2                   TAX_PER_HOUSE)
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    ! Sort
    STATUS = SYS$SETPRN ('INCSORT')
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
    STATUS = TAX_SORT (TOTAL_HOUSES,
    2                  TAX_PER_HOUSE)
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))

    ! Write report
    STATUS = SYS$SETPRN ('INCREPORT')
    IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
       .
       .
       .

## 4.7 Accessing Another Process's Context

On OpenVMS VAX systems, a system programmer must sometimes develop code that performs various actions (such as performance monitoring) on behalf of a given process, executing in that process's context. To do so, a programmer typically creates a routine consisting of position-independent code and data, allocates sufficient space in nonpaged pool, and copies the routine to it. On OpenVMS VAX systems, such a routine can execute correctly no matter where it is loaded into memory.

On OpenVMS Alpha systems, the practice of moving code in memory is more difficult and complex. It is not enough to simply copy code from one memory location to another. On OpenVMS Alpha systems, you must relocate both the routine and its linkage section, being careful to maintain the relative distance between them, and then apply all appropriate fixups to the linkage section.

The OpenVMS Alpha system provides two mechanisms to enable one process to access the context of another:

- Code that must read from or write to another process's registers or address space can use the EXE$READ_PROCESS and EXE$WRITE_PROCESS system routines, as described in Section 4.7.1.
- Code that must perform other operations in another process's context (for instance, to execute a system service to raise a target process's quotas) can be written as an OpenVMS Alpha executive image, as described in Section 4.7.2.

### 4.7.1 Reading and Writing in the Address Space of Another Process (Alpha Only)

EXE$READ_PROCESS and EXE$WRITE_PROCESS are OpenVMS Alpha system routines in nonpaged system space. EXE$READ_PROCESS reads data from a target process's address space or registers and writes it to a buffer in the local process's address space. EXE$WRITE_PROCESS obtains data from a local process's address space and transfers it to the target process's context. Both routines must be called from kernel mode at IPL 0.

One of the arguments to these procedures specifies whether or not the procedure is to access memory and registers in the target process. Another argument specifies the memory address or register number. The contents of these arguments are symbolic names (beginning with the prefix EACB$) that are defined by the $PROCESS_READ_WRITE macro in SYS$LIBRARY:LIB.MLB. (They are also defined in LIB.REQ for BLISS programmers.)

#### 4.7.1.1 EXE$READ_PROCESS and EXE$WRITE_PROCESS

The following are descriptions of the callable interfaces to EXE$READ_PROCESS and EXE$WRITE_PROCESS.

## EXE$READ_PROCESS

> Reads data from a target process's address space or registers and writes it to a buffer in the local process's address space.

Module PROC_READ_WRITE

### Format

> status = EXE$READ_PROCESS (ipid, buffer_size, target_address, local_address, target_address_type, ast_counter_address)

### Arguments

> #### ipid

> OpenVMS usage | ipid
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Internal process ID of the target process.

> #### buffer_size

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Number of bytes to transfer. If target_address_type is EACB$K_GENERAL_REGISTER, the values of target_address and buffer_size together determine how many 64-bit registers are written, in numeric order, to the buffer. A partial register is written for any value that is not a multiple of 8.

> If you specify buffer_size to be larger than 8, more than one register is written from the buffer. Registers are written in numeric order, followed by the PC and PS, starting at the register indicated by target_address.

> If target_address_type is EACB$K_GENERAL_REGISTER and the values of buffer_size and target_address would cause a target process read extending beyond R31 (the last available register), EXE$READ_PROCESS returns SS$_ILLSER status.

> #### target_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference (if address); by value (if constant)

> If target_address_type is EACB$K_MEMORY, address in target process at which the transfer is to start.

> If target_address_type is EACB$K_GENERAL_REGISTER, symbolic constant indicating at which general register the transfer should start. Possible constant values include EACB$K_R0 through EACB$K_R29, EACB$K_PC, and EACB$K_PS.

> #### local_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference

> Address of buffer in local process to which data is to be written.

> #### target_address_type

> OpenVMS usage | integer
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Symbolic constant indicating whether the target_address argument is a memory address (EACB$K_MEMORY) or a general register (EACB$K_GENERAL_REGISTER). Floating-point registers are not supported as target addresses.

> #### ast_counter_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference

> Address of a longword used internally as an AST counter by EXE$READ_PROCESS and EXE$WRITE_PROCESS to detect errors. Supply the same address in the ast_counter_address argument for every call to these routines.

### RETURNS

> OpenVMS usage | cond_value
> type | longword (unsigned)
> access | write only
> mechanism | by value

> Status indicating the success or failure of the operation.

### Return Values

> SS$_ACCVIO | Unable to write to the location indicated by local_address or ast_counter_address.
> SS$_ILLSER | Routine was called with IPL greater than 0, or an illegal target_address_type was specified. If target_address_type is EACB$K_GENERAL_REGISTER, this status can indicate that the values of buffer_size and target_address would cause a target process read extending beyond R31 (the last available register).
> SS$_INSFMEM | Insufficient memory available for specified buffer.
> SS$_NONEXPR | The ipid argument does not correspond to an existing process.
> SS$_NORMAL | The interprocess read finished successfully.
> SS$_TIMEOUT | The read operation did not finish within a few seconds.

Context The caller of EXE$READ_PROCESS must be executing in kernel mode at IPL 0. Kernel mode ASTs must be enabled.

### Description

> EXE$READ_PROCESS reads data from a target process's address space and writes it to a buffer in the local process's address space.

> EXE$READ_PROCESS allocates nonpaged pool for an AST control block (ACB), an ACB extension, and a buffer of the specified size. It initializes the extended ACB with information describing the data transfer and then delivers an AST to the target process to perform the operation. The data is read in the context of the target process from its address space or registers into nonpaged pool. An AST is then queued to the requesting process to complete the read operation by copying the data from pool to the process's buffer.

> EXE$READ_PROCESS does not return to its caller until the read is completed, an error is encountered, or it has timed out. (The current timeout value is 3 seconds.)

## EXE$WRITE_PROCESS

> Reads data from the local process's address space and writes it either to a target process's registers or a buffer in a target process's address space.

Module PROC_READ_WRITE

### Format

> status = EXE$WRITE_PROCESS (ipid, buffer_size, local_address, target_address, target_address_type, ast_counter_address)

### Arguments

> #### ipid

> OpenVMS usage | ipid
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Internal process ID of the target process.

> #### buffer_size

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Number of bytes to transfer. If target_address_type is EACB$K_GENERAL_REGISTER, the values of target_address and buffer_size together determine how many 64-bit registers are written, in numeric order, from the buffer. A partial register is written for any value that is not a multiple of 8.

> If you specify buffer_size to be larger than 8, more than one register is written from the buffer. Registers are written in numeric order, followed by the PC and PS, starting at the register indicated by target_address.

> If target_address_type is EACB$K_GENERAL_REGISTER and the values of buffer_size and target_address would cause a write extending beyond R31 (the last available register), EXE$WRITE_PROCESS returns SS$_ILLSER status.

> #### local_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference

> Address in local process from which data is to be transferred.

> #### target_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference (if address) by value (if constant)

> If target_address_type is EACB$K_MEMORY, address in target process at which the transfer is to start.

> If target_address_type is EACB$K_GENERAL_REGISTER, symbolic constant indicating at which general register the transfer should start. Possible constant values include EACB$K_R0 through EACB$K_R29, EACB$K_PC, and EACB$K_PS.

> #### target_address_type

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by value

> Symbolic constant indicating whether the target_address argument is a memory address (EACB$K_MEMORY) or a general register (EACB$K_GENERAL_REGISTER). Floating-point registers are not supported as target addresses.

> #### ast_counter_address

> OpenVMS usage | longword_unsigned
> type | longword (unsigned)
> access | read only
> mechanism | by reference

> Address of a longword used internally as an AST counter by EXE$READ_PROCESS and EXE$WRITE_PROCESS to detect errors. Supply the same address in the ast_counter_address argument for every call to these routines.

### RETURNS

> OpenVMS usage | cond_value
> type | longword (unsigned)
> access | write only
> mechanism | by value

> Status indicating the success or failure of the operation.

### Return Values

> SS$_ACCVIO | Unable to read from the location indicated by local_address or write to the location indicated by ast_counter_address.
> SS$_ILLSER | Routine was called with IPL greater than 0, an illegal target_address_type was specified. If target_address_type is EACB$K_GENERAL_REGISTER, this status can indicate that the values of buffer_size and target_address would cause a process write extending beyond R31 (the last available register).
> SS$_INSFMEM | Insufficient memory available for specified buffer.
> SS$_NONEXPR | The ipid argument does not correspond to an existing process.
> SS$_NORMAL | The interprocess write finished successfully.
> SS$_TIMEOUT | The write operation did not finish within a few seconds.

Context The caller of EXE$WRITE_PROCESS must be executing in kernel mode at IPL 0. Kernel mode ASTs must be enabled.

### Description

> EXE$WRITE_PROCESS reads data from the local process's address space and writes it to a target process's registers or a buffer in a target process's address space.

> EXE$WRITE_PROCESS allocates nonpaged pool for an AST control block (ACB), an ACB extension, and a buffer of the specified size. It initializes the extended ACB with information describing the data transfer, copies the data to be written to the target process into the buffer, and then delivers an AST to the target process to perform the operation.

> The AST routine copies the data from pool into the target location and then queues an AST to the requesting process to complete the write operation.

> EXE$WRITE_PROCESS does not return to its caller until the read is completed, an error is encountered, or it has timed out. (The current timeout value is 3 seconds.)

Previous | Next | Contents | Index

| privacy and legal statement |
5841PRO_013.HTML