Document revision date: 19 July 1999
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Programming Concepts Manual


Previous Contents Index

3.8.3.4 Initiating Image Rundown for Another Process

The Force Exit (SYS$FORCEX) system service provides a way for a process to initiate image rundown for another process. For example, the following call to SYS$FORCEX causes the image executing in the process CYGNUS to exit:


        $DESCRIPTOR(prcnam,"CYGNUS"); 
   .
   .
   .
        status = SYS$FORCEX(0,                  /* pidadr - Process id */ 
                                &prcnam,        /* prcnam - Process name */ 
                        0);                     /* code - Completion code */ 

Because the SYS$FORCEX system service calls the SYS$EXIT system service, any exit handlers declared for the image are executed before image rundown. Thus, if the process is using the command interpreter, the process is not deleted and can run another image. Because the SYS$FORCEX system service uses the AST mechanism, an exit cannot be performed if the process being forced to exit has disabled the delivery of ASTs. AST delivery and how it is disabled and reenabled is described in Chapter 5.

The following program segment shows an example of an exit-handling routine:


#include <stdio> 
#include <ssdef> 
 
 
/* Exit control block */ 
 
struct { 
        unsigned int *desblk; 
        unsigned int (*exh)(); 
        unsigned int argcount; 
        unsigned int *cond_value;              (1) 
}exitblock = {0, &exitrtn, 1, 0}; 
 
main() { 
 
        unsigned int status; 
 
/* Declare the exit handler */ 
        
        status = SYS$DCLEXH(&exitblock);        (2)
        if ((status & 1) != 1) 
                LIB$SIGNAL(status); 
} 
 
int exitrtn (int condition ) {                  (3)                   
        if ((status & 1) != 1) 
        { 
        /* Clean up */ 
   .
   .
   .
                return 1; 
        } 
        else 
        /* Normal exit */ 
 
                return 0; 
 
} 

  1. EXITBLOCK is the exit control block for the exit handler EXITRTN. The third longword indicates the number of arguments to be passed. In this example, only one argument is passed: the address of a longword for the system to store the return status code. This argument must be provided in an exit control block.
  2. The SYS$DCLEXH system service call designates the address of the exit control block, thus declaring EXITRTN as an exit handler.
  3. The EXITRTN exit handler checks the status code. If this is a normal exit, EXITRTN returns control. Otherwise, it handles the error condition.

3.8.4 Deleting a Process

Process deletion completely removes a process from the system. A process can be deleted by any of the following events:

When the system is called to delete a process as a result of any of these conditions, it first locates all subprocesses, and searches hierarchically. No process can be deleted until all the subprocesses it has created have been deleted.

The lowest subprocess in the hierarchy is a subprocess that has no descendant subprocesses of its own. When that subprocess is deleted, its parent subprocess becomes a subprocess that has no descendant subprocesses and it can be deleted as well. The topmost process in the hierarchy becomes the parent process of all the other subprocesses.

The system performs each of the following procedures, beginning with the lowest process in the hierarchy and ending with the topmost process:

Figure 3-1 illustrates the flow of events from image exit through process deletion.

Figure 3-1 Image Exit and Process Deletion


3.8.4.1 Deleting a Process By Using System Services

A process can delete itself or another process at any time, depending on the restrictions outlined in Section 3.1.1. Any one of the following system services can be used to delete a subprocess or a detached process. Some services terminate execution of the image in the process; others terminate the process itself.

3.8.4.2 Terminating Mailboxes

A termination mailbox provides a process with a way of determining when, and under what conditions, a process that it has created was deleted. The Create Process (SYS$CREPRC) system service accepts the unit number of a mailbox as an argument. When the process is deleted, the mailbox receives a termination message.

The first word of the termination message contains the symbolic constant, MSG$_DELPROC, which indicates that it is a termination message. The second longword of the termination message contains the final status value of the image. The remainder of the message contains system accounting information used by the job controller and is identical to the first part of the accounting record sent to the system accounting log file. The description of the SYS$CREPRC system service in the OpenVMS System Services Reference Manual provides the complete format of the termination message.

If necessary, the creating process can determine the process identification of the process being deleted from the I/O status block (IOSB) posted when the message is received in the mailbox. The second longword of the IOSB contains the process identification of the process being deleted.

A termination mailbox cannot be located in memory shared by multiple processors.

The following example illustrates a complete sequence of process creation, with a termination mailbox:


#include <stdio.h> 
#include <descrip.h> 
#include <ssdef.h> 
#include <msgdef.h> 
#include <dvidef.h> 
#include <iodef.h> 
#include <accdef.h> 
 
unsigned short unitnum; 
unsigned int pidadr; 
 
/* Create a buffer to store termination info */ 
 
struct accdef exitmsg; 
 
/* Define and initialize the item list for $GETDVI */ 
 
static struct {                                        (1)
        unsigned short buflen,item_code; 
        void *bufaddr; 
        void *retlenaddr; 
        unsigned int terminator; 
}mbxinfo = { 4, DVI$_UNIT, &unitnum, 0, 0}; 
 
 
/* I/O Status Block for QIO */ 
 
struct { 
        unsigned short iostat, mblen; 
        unsigned int mbpid; 
}mbxiosb; 
 
 
main() { 
 
        void exitast(void); 
        unsigned short exchan; 
        unsigned int status,maxmsg=84,bufquo=240,promsk=0; 
        unsigned int func=IO$_READVBLK; 
        $DESCRIPTOR(image,"LYRA"); 
 
/* Create a mailbox */ 
        status = SYS$CREMBX(0,      /* prmflg (permanent or temporary) */ (2)
                      &exchan,      /* channel */ 
                      maxmsg,       /* maximum message size */ 
                      bufquo,       /* no. of bytes used for buffer */ 
                      promsk,       /* protection mask */ 
                      0,0,0,0); 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
/* Get the mailbox unit number */ 
        status = SYS$GETDVI(0,                  /* efn - event flag */      (3)
                      exchan,           /* chan - channel */ 
                      0,                /* devnam - device name */ 
                      &mbxinfo,         /* item list */ 
                      0,0,0,0); 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
/* Create a subprocess */ 
        status = SYS$CREPRC(&pidadr,    /* process id */ 
                        &image,         /* image to be run */ 
                        0,0,0,0,0,0,0,0, 
                        unitnum,        /* mailbox unit number */ 
                0);                     /* options flags */ 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
/* Read from mailbox */ 
        status = SYS$QIOW(0,            /* efn - event flag */           (4)
                        exchan,         /* chan - channel number */ 
                        func,           /* function modifier */ 
                        &mbxiosb,       /* iosb - I/O status block */ 
                        &exitast,       /* astadr - astadr AST routine */ 
                0,                      /* astprm - astprm AST parameter */ 
                        &exitmsg,       /* p1 - buffer to receive message*/ 
                        ACC$K_TERMLEN,  /* p2 - length of buffer */ 
                0,0,0,0);               /* p3, p4, p5, p6 */ 
 
        if ((status & 1 ) != 1) 
                LIB$SIGNAL( status ); 
 
 
} 
 
void exitast(void) { 
 
     if(mbxiosb.iostat == SS$_NORMAL)                       (5)
     { 
         printf("\nMailbox successfully written..."); 
         if (exitmsg.acc$w_msgtyp == MSG$_DELPROC) 
         { 
              printf("\nProcess deleted..."); 
              if (pidadr == mbxiosb.mbpid) 
              { 
                    printf("\nPIDs are equal..."); 
                    if (exitmsg.acc$l_finalsts == SS$_NORMAL) 
                      printf("\nNormal termination..."); 
                    else 
                     printf("\nAbnormal termination status: %d", 
                            exitmsg.acc$l_finalsts); 
               } 
               else 
                     printf("\nPIDs are not equal"); 
               } 
               else 
                    printf("\nTermination message not received... status: %d", 
                           exitmsg.acc$w_msgtyp); 
        } 
        else 
                printf("\nMailbox I/O status block: %d",mbxiosb.iostat); 
 
        return; 
} 

  1. The item list for the Get Device/Volume Information (SYS$GETDVI) system service specifies that the unit number of the mailbox is to be returned.
  2. The Create Mailbox and Assign Channel (SYS$CREMBX) system service creates the mailbox and returns the channel number at EXCHAN.
  3. The Create Process (SYS$CREPRC) system service creates a process to execute the image LYRA.EXE and returns the process identification at LYRAPID. The mbxunt argument refers to the unit number of the mailbox, obtained from the Get Device/Volume Information (SYS$GETDVI) system service.
  4. The Queue I/O Request (SYS$QIO) system service queues a read request to the mailbox, specifying both an AST service routine to receive control when the mailbox receives a message and the address of a buffer to receive the message. The information in the message can be accessed by the symbolic offsets defined in the $ACCDEF macro. The process continues executing.
  5. When the mailbox receives a message, the AST service routine EXITAST receives control. Because this mailbox can be used for other interprocess communication, the AST routine does the following:
    In this example, the AST service routine performs special action when the subprocess is deleted.

The Create Mailbox and Assign Channel (SYS$CREMBX), Get Device/Volume Information (SYS$GETDVI), and Queue I/O Request (SYS$QIO) system services are described in greater detail in Chapter 11.


Chapter 4
Symmetric Multiprocessing (SMP) Systems

4.1 Introduction to Symmetric Multiprocessing

OpenVMS Alpha supports tightly coupled symmetric multiprocessing (SMP). This chapter presents a brief overview of symmetric multiprocessing terms and characteristics. For more information about SMP concepts and hardware configurations, refer to OpenVMS AXP Internals and Data Structures.

A multiprocessing system consists of two or more CPUs that address common memory and that can execute instructions simultaneously. If all CPUs in the system execute the same copy of the operating system, the multiprocessing system is said to be tightly coupled. If all CPUs have equal access to memory, interrupts, and I/O devices, the system is said to be symmetric.

In most respects the members of an OpenVMS SMP system are symmetric. Each member can perform the following tasks:

4.2 CPU Characteristics of an SMP System

The members of an SMP system are characterized in several ways. One important characteristic is that of primary CPU. During system operation the primary CPU has several unique responsibilities for system timekeeping, writing messages to the console terminal, and accessing any other I/O devices that are not accessible to all members. Although the hardware and software permit device interrupts to be serviced by any processor, in practice all device interrupts are serviced on the primary CPU. An SMP configuration may include some devices that are not accessible from all SMP members. The console terminal, for example, is accessible only from the primary processor.

4.2.1 Booting an SMP System

Booting the system is initiated on a CPU with full access to the console subsystem and terminal, called the BOOT CPU. The BOOT CPU controls the bootstrap sequence and boots the other available CPUs. On OpenVMS Alpha systems, the BOOT CPU and the primary CPU are always the same; the others are called secondary processors.

The booted primary and all currently booted secondary processors are called members of the active set. These processors actively participate in system operations and respond to interprocessor interrupts, which coordinate systemwide events.

4.2.2 Interrupt Requests on SMP System

In an SMP system, each processor services its own software interrupt requests, of which the most significant are the following:

4.3 Symmetric Multiprocessing Goals

SMP supports the following goals:


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
5841PRO_012.HTML