| 
     
 
 
  
 
  
 
  
 
  
 
  
 
  
 
          | 
     
| Updated: 11 December 1998 | 
 
 
OpenVMS Programming Concepts Manual
| Previous | Contents | Index | 
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; 
 
} 
 | 
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
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.
      
$DESCRIPTOR(prcnam,"CYGNUS"); 
   .
   .
   .
status = SYS$EDLPRC(0,                 /* Process id */ 
                    &prcnam);          /* Process name */    
 | 
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; 
} 
 | 
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.
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:
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:
SMP supports the following goals:
| Previous | Next | Contents | Index | 
 
 
 
  
 
  
 
  
 
  
 
  
 
  
      | 
 
           |  
     
|  
              
 
              
            Copyright © Compaq Computer Corporation 1998. All rights reserved. Legal |  
     
 
           
           
5841PRO_012.HTML
           
           
          |