HP OpenVMS Programming Concepts Manual
HP OpenVMS Programming Concepts Manual
Order Number: AARNSHDTE January 2005 This manual is Volume I of two volumes. It describes the features that the HP OpenVMS operating system provides to programmers in the areas of process and synchronization; interrupts and condition handling; and addressing and memory management.
Revision/Update Information:
This manual supersedes the HP OpenVMS Programming Concepts Manual, Version 7.3-1. OpenVMS I64 Version 8.2 OpenVMS Alpha Version 8.2
Software Version:
Copyright 2005 Hewlett-Packard Development Company, L.P. Condential computer software. Valid license from HP required for possession, use or copying. Consistent with FAR 12.211 and 12.212, Commercial Computer Software, Computer Software Documentation, and Technical Data for Commercial Items are licensed to the U.S. Government under vendors standard commercial license. The information contained herein is subject to change without notice. The only warranties for HP products and services are set forth in the express warranty statements accompanying such products and services. Nothing herein should be construed as constituting an additional warranty. HP shall not be liable for technical or editorial errors or omissions contained herein. Intel and Itanium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries. Microsoft, Windows, and Windows NT are U.S. registered trademarks of Microsoft Corporation. UNIX is a registered trademark of The Open Group. X/Open is a registered trademark, and the X device is a trademark of X/Open Company Ltd. in the UK and other countries. Printed in the US ZK6640 The HP OpenVMS documentation set is available on CD-ROM.
Contents
Preface . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1 Overview of Manuals and Introduction to Development on OpenVMS Systems
1.1 Overview of the Manual . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 Overview of the OpenVMS Operating System . . . . . . . . . . . . . . . . . . . . . . 1.3 Components of the OpenVMS Operating System . . . . . . . . . . . . . . . . . . . . 1.3.1 OpenVMS Systems on Multiple Platforms . . . . . . . . . . . . . . . . . . . . . . 1.3.1.1 System Compatibility and Program Portability Across Platforms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2 OpenVMS Computing Environments . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2.1 Open System Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2.2 Application Portability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.2.2.1 Other Application Portability Features . . . . . . . . . . . . . . . . . . 1.3.3 Distributed Computing Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3.1 Client/Server Style of Computing . . . . . . . . . . . . . . . . . . . . . . . . . . 1.3.3.2 OpenVMS Client/Server Capabilities . . . . . . . . . . . . . . . . . . . . . . . 1.4 The OpenVMS Programming Environment . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1 Programming to Standards . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.4.1.1 Common Environment for Writing Code . . . . . . . . . . . . . . . . . . . . 1.4.1.2 Common Language Environment . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5 OpenVMS Programming Software . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.1 Creating Program Source Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.2 Creating Object Files . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.3 Creating Runnable Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.4 Testing and Debugging Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.5.4.1 Special Modes of Operation for Debugging . . . . . . . . . . . . . . . . . . . 1.5.5 Using Other Program Development Utilities . . . . . . . . . . . . . . . . . . . . 1.5.6 Managing Software Development Tasks . . . . . . . . . . . . . . . . . . . . . . . . 1.6 Using Callable System Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.1 Using the POSIX Threads Library Routines . . . . . . . . . . . . . . . . . . . . 1.6.2 Using OpenVMS Run-Time Library Routines . . . . . . . . . . . . . . . . . . . 1.6.3 Using OpenVMS System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.6.4 Using OpenVMS Utility Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.7 Programming User Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.8 Optional HP Software Development Tools . . . . . . . . . . . . . . . . . . . . . . . . . 1.9 Managing Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.1 RMS Files and Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.9.2 RMS Utilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 12 13 14 14 14 14 15 15 15 15 16 16 18 18 18 18 19 110 111 111 113 113 114 114 114 115 116 117 118 119 119 119 120 xix
iii
3 Process Communication
3.1 Communication Within a Process . . . . . . . . . . . 3.1.1 Using Local Event Flags . . . . . . . . . . . . . . 3.1.2 Using Logical Names . . . . . . . . . . . . . . . . . 3.1.2.1 Creating and Accessing Logical Names . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31 32 32 32
iv
3.1.3 Using Command Language Interpreter Symbols . . . . . 3.1.3.1 Local and Global Symbols . . . . . . . . . . . . . . . . . . . 3.1.3.2 Creating and Using Global Symbols . . . . . . . . . . . . 3.1.4 Using the Common Area . . . . . . . . . . . . . . . . . . . . . . . 3.1.4.1 Creating the Process Common Area . . . . . . . . . . . . 3.1.4.2 Common I/O Routines . . . . . . . . . . . . . . . . . . . . . . 3.1.4.3 Modifying or Deleting Data in the Common Block . 3.1.4.4 Specifying Other Types of Data . . . . . . . . . . . . . . . 3.2 Communication Between Processes . . . . . . . . . . . . . . . . . . 3.2.1 Using Logical Name Tables . . . . . . . . . . . . . . . . . . . . . 3.2.2 Mailboxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2.1 Creating a Mailbox . . . . . . . . . . . . . . . . . . . . . . . . 3.2.2.2 Creating Temporary and Permanent Mailboxes . . . 3.2.2.3 Assigning an I/O Channel Along with a Mailbox . . 3.2.2.4 Reading and Writing Data to a Mailbox . . . . . . . . . 3.2.2.5 Using Synchronous Mailbox I/O . . . . . . . . . . . . . . . 3.2.2.6 Using Immediate Mailbox I/O . . . . . . . . . . . . . . . . 3.2.2.7 Using Asynchronous Mailbox I/O . . . . . . . . . . . . . . 3.3 Intracluster Communication . . . . . . . . . . . . . . . . . . . . . . . 3.3.1 Programming with Intracluster Communications . . . . 3.3.1.1 ICC Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2 Design Considerations . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2.1 Naming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2.2 Message Ordering . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2.3 Flow Control . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2.4 Transfer Sizes and Receiving Data . . . . . . . . . . 3.3.1.2.5 Transfer Sizes and Transceive . . . . . . . . . . . . . 3.3.1.2.6 Disconnection . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.2.7 Error Recovery . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.3 General Programming Considerations . . . . . . . . . . 3.3.1.4 Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.3.1.4.1 Connection Events . . . . . . . . . . . . . . . . . . . . . . 3.3.1.4.2 Disconnection Events . . . . . . . . . . . . . . . . . . . . 3.3.1.5 Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
35 35 35 36 36 36 36 36 37 38 39 39 39 310 311 312 314 318 321 322 322 323 323 323 323 323 324 324 325 325 325 326 326 327
4 Process Control
4.1 Using Process Control for Programming Tasks . . . . . . . . . . . . . . . 4.1.1 Determining Privileges for Process Creation and Control . . . . 4.1.2 Determining Process Identication . . . . . . . . . . . . . . . . . . . . . 4.1.3 Qualifying Process Naming Within Groups . . . . . . . . . . . . . . . 4.2 Obtaining Process Information . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.1 Using the PID to Obtain Information . . . . . . . . . . . . . . . . . . . 4.2.2 Using the Process Name to Obtain Information . . . . . . . . . . . . 4.2.3 Using SYS$GETJPI and LIB$GETJPI . . . . . . . . . . . . . . . . . . . 4.2.3.1 Requesting Information About a Single Process . . . . . . . . . 4.2.3.2 Requesting Information About All Processes on the Local System . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.4 Using SYS$GETJPI with SYS$PROCESS_SCAN . . . . . . . . . . 4.2.4.1 Using SYS$PROCESS_SCAN Item List and Item-Specic Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2.4.2 Requesting Information About Processes That Match One Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 43 43 45 45 46 46 49 49 412 414 416 417
4.2.4.3 4.2.4.4 4.2.5 4.2.5.1 4.2.5.2 4.2.5.3 4.2.6 4.2.6.1 4.2.6.2 4.2.6.3 4.2.6.4 4.2.7 4.2.8 4.3 4.4 4.4.1 4.4.1.1 4.4.2 4.4.3 4.4.4 4.4.5 4.4.5.1 4.4.5.2 4.5 4.5.1 4.5.1.1 4.5.1.2 4.5.1.3 4.5.1.4 4.5.1.5 4.5.1.6 4.5.2 4.5.2.1 4.5.3 4.5.4 4.6 4.7 4.7.1 4.7.1.1
Requesting Information About Processes That Match Multiple Values for One Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Requesting Information About Processes That Match Multiple Criteria . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Specifying a Node as Selection Criterion . . . . . . . . . . . . . . . . . . . . . . . Checking All Nodes on the Cluster for Processes . . . . . . . . . . . . . . Checking Specic Nodes on the Cluster for Processes . . . . . . . . . . Conducting Multiple Simultaneous Searches with SYS$PROCESS_SCAN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Programming with SYS$GETJPI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Item Lists Correctly . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Improving Performance by Using Buffered $GETJPI Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fullling Remote SYS$GETJPI Quota Requirements . . . . . . . . . . Using the SYS$GETJPI Control Flags . . . . . . . . . . . . . . . . . . . . . . Using SYS$GETLKI . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting Process Privileges . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing Process and Kernel Threads Scheduling . . . . . . . . . . . . . . . . . . Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Dening Afnity and Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Afnity and Capabilities with Caution . . . . . . . . . . . . . . . . Types of Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Looking at User Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Capabilities System Services . . . . . . . . . . . . . . . . . . . . . . . . Types of Afnity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Implicit Afnity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Explicit Afnity . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Class Scheduler in CPU Scheduling . . . . . . . . . . . . . . . . . . . . . Specications for the Class_Schedule Command . . . . . . . . . . . . . . . . . The Add Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Delete Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Modify Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Show Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Suspend Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Resume Subcommand . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Class Scheduler Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . The Class Scheduler Database and Process Creation . . . . . . . . . . . Determining If a Process Is Class Scheduled . . . . . . . . . . . . . . . . . . . . The SYS$SCHED System Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . Changing Process Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Accessing Another Processs Context . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reading and Writing in the Address Space of Another Process (Alpha and I64 Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EXE$READ_PROCESS and EXE$WRITE_PROCESS . . . . . . . . . . EXE$READ_PROCESS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . EXE$WRITE_PROCESS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Writing an Executive Image (Alpha and I64 Only) . . . . . . . . . . . . . . . INITIALIZATION_ROUTINE Macro (Alpha and I64 Only) . . . . . . INITIALIZATION_ROUTINE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Linking an Executive Image (Alpha or I64 Only) . . . . . . . . . . . . . . Loading an Executive Image (Alpha or I64 Only) . . . . . . . . . . . . . LDR$LOAD_IMAGE (Alpha or I64 Only) . . . . . . . . . . . . . . . . . . . LDR$LOAD_IMAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
420 421 421 422 422 423 424 424 424 425 426 430 431 432 432 433 433 433 434 434 435 435 436 436 437 437 438 438 439 439 439 440 440 440 441 441 442 442 442 443 446 449 451 451 452 452 453 453
vi
4.7.2.5 4.8 4.8.1 4.8.1.1 4.8.1.2 4.8.2 4.9 4.9.1 4.9.1.1 4.9.1.2 4.9.1.3 4.9.2 4.9.2.1 4.9.2.2 4.9.3 4.9.3.1 4.9.3.2 4.9.3.3 4.9.3.4 4.9.4 4.9.4.1 4.9.4.2 4.9.4.3
LDR$UNLOAD_IMAGE (Alpha or I64 Only) . . . . . . . . . . . . . . . . . LDR$UNLOAD_IMAGE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronizing Programs by Specifying a Time for Program Execution . . . Obtaining the System Time . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Executing a Program at a Specied Time . . . . . . . . . . . . . . . . . . . Executing a Program at Timed Intervals . . . . . . . . . . . . . . . . . . . . Placing Entries in the System Timer Queue . . . . . . . . . . . . . . . . . . . . Controlling Kernel Threads and Process Execution . . . . . . . . . . . . . . . . . . Process Hibernation and Suspension . . . . . . . . . . . . . . . . . . . . . . . . . . Using Process Hibernation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Alternative Methods of Hibernation . . . . . . . . . . . . . . . . . . . Using SYS$SUSPND . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Passing Control to Another Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invoking a Command Image . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Invoking a Noncommand Image . . . . . . . . . . . . . . . . . . . . . . . . . . . Performing Image Exit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Performing Image Rundown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Initiating Rundown . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Performing Cleanup and Rundown Operations . . . . . . . . . . . . . . . Initiating Image Rundown for Another Process . . . . . . . . . . . . . . . Deleting a Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deleting a Process By Using System Services . . . . . . . . . . . . . . . . $DELPRC System Service Can Invoke Exit Handlers (Alpha and I64 only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Terminating Mailboxes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
457 457 459 459 460 461 462 463 463 465 466 467 467 467 468 468 469 469 470 470 471 474 474 476
vii
6.6.2 6.6.3 6.6.3.1 6.6.3.2 6.6.3.3 6.6.3.4 6.6.3.5 6.6.3.6 6.6.3.7 6.6.4 6.6.5 6.6.6 6.6.7 6.6.8 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.7.5 6.7.6 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.8.5.1 6.8.6 6.8.6.1 6.8.6.2 6.8.6.3 6.8.7 6.8.8 6.8.9 6.8.10 6.8.11 6.9
LDx_L and STx_C Instructions (Alpha Only) . . . . . . . . . . . . . . . . . . . . Interlocking Memory References (Alpha Only) . . . . . . . . . . . . . . . . . . . Required Code Checks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the Code Analysis Tool . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Characteristics of Noncompliant Code . . . . . . . . . . . . . . . . . . . . . . Coding Requirements . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compiler Versions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interlocked Memory Sequence Checking for the MACRO32 Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Recompiling Code with ALONONPAGED_INLINE or LAL_REMOVE_FIRST Macros . . . . . . . . . . . . . . . . . . . . . . . . . . . Interlocked Instructions (VAX Only) . . . . . . . . . . . . . . . . . . . . . . . . . . Memory Barriers (Alpha Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Memory Fences (I64 Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . PALcode Routines (Alpha Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . I64 Emulation of PALcode Built-ins . . . . . . . . . . . . . . . . . . . . . . . . . . . Software-Level Synchronization . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronization Within a Process . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronization in Inner Mode (Alpha and I64 Only) . . . . . . . . . . . . . Synchronization Using Process Priority . . . . . . . . . . . . . . . . . . . . . . . . Synchronizing Multiprocess Applications . . . . . . . . . . . . . . . . . . . . . . . Synchronization Using Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Writable Global Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . General Guidelines for Using Event Flags . . . . . . . . . . . . . . . . . . . . . . Introducing Local and Common Event Flag Numbers and Event Flag Clusters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Event Flag Zero (0) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using EFN$C_ENF Local Event Flag . . . . . . . . . . . . . . . . . . . . . . . . . Using Local Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example of Event Flag Services . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Common Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using the name Argument with SYS$ASCEFC . . . . . . . . . . . . . . Temporary Common Event Flag Clusters . . . . . . . . . . . . . . . . . . . Permanent Common Event Flag Clusters . . . . . . . . . . . . . . . . . . . Wait Form Services and SYS$SYNCH . . . . . . . . . . . . . . . . . . . . . . . . . Event Flag Waits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Setting and Clearing Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example of Using a Common Event Flag Cluster . . . . . . . . . . . . . . . . Example of Using Event Flag Routines and Services . . . . . . . . . . . . . . Synchronizing System Services Operations . . . . . . . . . . . . . . . . . . . . . . . .
610 611 612 612 613 614 615 616 617 617 618 619 619 619 619 620 620 621 621 622 622 623 623 624 626 626 626 627 628 629 630 630 632 632 634 634 636 638
viii
7.2.9 7.2.9.1 7.2.9.2 7.2.9.3 7.2.9.4 7.3 7.3.1 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.4.6 7.4.7 7.4.8 7.4.9 7.4.10 7.5 7.6 7.6.1 7.6.2 7.6.2.1 7.6.2.2 7.6.3 7.7
Lock Quotas and Limits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Enqueue Limit Quota (ENQLM) . . . . . . . . . . . . . . . . . . . . . . . . . . Subresources and Sublocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Resource Hash Table . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . LOCKIDTBL System Parameter . . . . . . . . . . . . . . . . . . . . . . . . . . Queuing Lock Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Example of Requesting a Null Lock . . . . . . . . . . . . . . . . . . . . . . . . . . . Advanced Locking Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Synchronizing Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Notication of Synchronous Completion . . . . . . . . . . . . . . . . . . . . . . . . Expediting Lock Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lock Status Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Blocking ASTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lock Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Forced Queuing of Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Parent Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lock Value Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Interoperation with 16-Byte and 64-Byte Value Blocks . . . . . . . . . . . . Dequeuing Locks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Local Buffer Caching with the Lock Management Services . . . . . . . . . . . Using the Lock Value Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using Blocking ASTs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deferring Buffer Writes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Buffer Caching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Choosing a Buffer-Caching Technique . . . . . . . . . . . . . . . . . . . . . . . . . Example of Using Lock Management Services . . . . . . . . . . . . . . . . . . . . .
78 79 79 79 79 79 710 711 711 712 712 712 713 713 714 715 716 717 718 720 720 720 720 721 721 722
ix
91 92 92 94 97 98 914 916 918 918 919 919 919 919 921 924 924 924 925 926 927 930 931 933 936 938 940 942 946 948 949 951 952 953 956 956 960 962 963 963 964 965 965 966 966 967 967 967 967 968
Accessing Modied Messages Without Relinking . . . . . . . . . . . Signaling User-Dened Values and Messages with Global and Local Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.11.4.1 Signaling with Global Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.11.4.2 Signaling with Local Symbols . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.11.4.3 Specifying FAO Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12 Writing a Condition Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.1 Continuing Execution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.2 Resignaling . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.3 Unwinding the Call Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.4 Example of Writing a Condition Handler . . . . . . . . . . . . . . . . . . . . . . . 9.12.4.1 Signal Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.4.2 Mechanism Array . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.4.3 Comparing the Signaled Condition with an Expected Condition .................................................... 9.12.4.4 Exiting from the Condition Handler . . . . . . . . . . . . . . . . . . . . . . . . 9.12.4.5 Returning Control to the Program . . . . . . . . . . . . . . . . . . . . . . . . . 9.12.5 Example of Condition-Handling Routines . . . . . . . . . . . . . . . . . . . . . . 9.13 Debugging a Condition Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.14 Run-Time Library Condition-Handling Routines . . . . . . . . . . . . . . . . . . . . 9.14.1 RTL Jacket Handlers (Alpha and I64 Only) . . . . . . . . . . . . . . . . . . . . . 9.14.2 Converting a Floating-Point Fault to a Floating-Point Trap (VAX Only) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.14.3 Changing a Signal to a Return Status . . . . . . . . . . . . . . . . . . . . . . . . 9.14.4 Changing a Signal to a Stop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.14.5 Matching Condition Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.14.6 Correcting a Reserved Operand Condition (VAX Only) . . . . . . . . . . . . 9.14.7 Decoding the Instruction That Generated a Fault (VAX Only) . . . . . . 9.15 Exit Handlers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.15.1 Establishing an Exit Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.15.2 Writing an Exit Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.15.3 Debugging an Exit Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.15.4 Example of Exit Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9.11.3.1.9 9.11.4
968 968 968 968 969 970 971 971 972 972 972 972 972 973 974 976 977 977 978 978 978 980 980 980 981 981 982 984 985 985
Part III Addressing and Memory Management 10 Overview of Alpha and I64 Virtual Address Space
10.1 10.2 10.3 10.3.1 10.3.2 10.3.3 10.3.4 10.4 10.4.1 10.4.2 10.4.3 Using 64-Bit Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Traditional OpenVMS 32-Bit Virtual Address Space Layout . . . . . OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Process-Private Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Table Space . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Virtual Address Space Size . . . . . . . . . . . . . . . . . . . . . . . . . . . Virtual Regions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Regions Within P0 Space and P1 Space . . . . . . . . . . . . . . . . . . 64-Bit Program Region . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . User-Dened Virtual Regions . . . . . . . . . . . . . . . . . . . . . . . . . . ...... ...... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 101 102 103 104 105 105 106 106 108 108 108
xi
12 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
12.1 Virtual Page Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.2 Levels of Memory Allocation Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3 Using System Services for Memory Allocation . . . . . . . . . . . . . . . . . . . . . . 12.3.1 Increasing and Decreasing Virtual Address Space with 64-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.2 Increasing and Decreasing Virtual Address Space with 32-bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.3 Input Address Arrays and Return Address Arrays for the 64-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.4 Input Address Arrays and Return Address Arrays for the 32-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.5 Allocating Memory in Existing Virtual Address Space on Alpha and I64 Systems Using the 32-Bit System Service . . . . . . . . . . . . . . . . . . . 12.3.6 Page Ownership and Protection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 121 122 124 124 125 127 128 129 1210
xii
Working Set Paging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SYS$ADJWSL System Service . . . . . . . . . . . . . . . . . . . . . . . . . . . . SYS$PURGWS System Service . . . . . . . . . . . . . . . . . . . . . . . . . . . SYS$LKWSET and SYS$LKWSET_64 System Services . . . . . . . . Specifying a Range of Addresses . . . . . . . . . . . . . . . . . . . . . . . . . . Specifying a Range of Addresses In OpenVMS Version 8.1 . . . . . . Specifying a Range of Addresses In OpenVMS Versions Prior to V8.1 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.7.7 Specifying the Access Mode . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.8 Process Swapping . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9 Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.1 Creating Sections with 64-Bit System Services . . . . . . . . . . . . . . . 12.3.9.2 PFN-Mapped Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.3 Creating Sections with 32-Bit System Services . . . . . . . . . . . . . . . 12.3.9.3.1 Opening the Disk File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.3.2 Dening the Section Extents . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.3.3 Dening the Section Characteristics . . . . . . . . . . . . . . . . . . . . 12.3.9.3.4 Dening Global Section Characteristics . . . . . . . . . . . . . . . . . 12.3.9.3.5 Global Section Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.4 Mapping Sections with 32-Bit System Services . . . . . . . . . . . . . . . 12.3.9.5 Mapping Global Sections with 32-Bit Services . . . . . . . . . . . . . . . . 12.3.9.6 Global Page-File Sections with 32-Bit System Services . . . . . . . . . 12.3.9.7 Mapping into a Dened Address Range With 32-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.8 Mapping from an Offset into a Section File With 32-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.9 Section Paging Resulting from SYS$CRMPSC . . . . . . . . . . . . . . . . 12.3.9.10 Reading and Writing Data Sections . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.11 Releasing and Deleting Sections . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.12 Writing Back Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.13 Memory-Resident Global Sections . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.14 Image Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.15 Page Frame Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.9.16 Partial Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.10 Example of Using 32-Bit Memory Management System Services . . . . 12.4 Large Page-File Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12.3.7 12.3.7.1 12.3.7.2 12.3.7.3 12.3.7.4 12.3.7.5 12.3.7.6
1211 1211 1211 1212 1212 1212 1213 1213 1213 1214 1215 1215 1216 1216 1217 1217 1218 1218 1219 1222 1223 1223 1223 1224 1226 1227 1227 1228 1228 1228 1229 1230 1234
xiii
13.5.6 13.5.6.1 13.5.6.2 13.5.6.3 13.5.6.4 13.5.6.5 13.5.6.6 13.5.6.7 13.5.6.8 13.5.6.9 13.5.6.10 13.5.6.11 13.5.6.12 13.5.6.13 13.5.6.14 13.5.6.15 13.5.7
Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Creating Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . Opening the Disk File . . . . . . . . . . . . . . . . . . . . . . . . Dening the Section Extents . . . . . . . . . . . . . . . . . . . Dening the Section Characteristics . . . . . . . . . . . . . Dening Global Section Characteristics . . . . . . . . . . . Global Section Name . . . . . . . . . . . . . . . . . . . . . . . . . Mapping Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . Mapping Global Sections . . . . . . . . . . . . . . . . . . . . . . Global Page-File Sections . . . . . . . . . . . . . . . . . . . . . . Section Paging . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Reading and Writing Data Sections . . . . . . . . . . . . . . Releasing and Deleting Sections . . . . . . . . . . . . . . . . Writing Back Sections . . . . . . . . . . . . . . . . . . . . . . . . Image Sections . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Frame Sections . . . . . . . . . . . . . . . . . . . . . . . . . Example of Using Memory Management System Services
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . .
1313 1314 1314 1315 1315 1316 1317 1318 1319 1320 1320 1322 1323 1323 1323 1324 1325
xiv
15.3 Using Tools for Finding Unaligned Data . . . . . . . . . 15.3.1 The OpenVMS Debugger . . . . . . . . . . . . . . . . . . 15.3.2 The Performance and Coverage AnalyzerPCA 15.3.3 System Services (Alpha and I64 Only) . . . . . . . . 15.3.4 Alignment Fault Utility (Alpha and I64 Only) . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
. . . . .
Part IV Appendixes: Macros and Examples of 64-Bit Programming A C Macros for 64-Bit Addressing
DESCRIPTOR64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $is_desc64 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $is_32bits . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . A1 A2 A2
.. .. ..
xv
Using SYS$GETJPI and SYS$PROCESS_SCAN with Multiple Values for One Criterion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Selecting Processes That Match Multiple Criteria . . . . . . . . . . . . . . . . Searching the Cluster for Process Information . . . . . . . . . . . . . . . . . . . Searching for Process Information on Specic Nodes in the Cluster . . Using a SYS$GETJPI Buffer to Improve Performance . . . . . . . . . . . . . Using SYS$GETJPI Control Flags to Avoid Swapping a Process into the Balance Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Procedure for Obtaining Process Lock Information . . . . . . . . . . . . . . . Executing a Program Using Delta Time . . . . . . . . . . . . . . . . . . . . . . . . Executing a Program at Timed Intervals . . . . . . . . . . . . . . . . . . . . . . . Requesting a Null Lock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Calling the SYS$SETIMR System Service . . . . . . . . . . . . . . . . . . . . . . Monitoring Heap Operations with a User-Dened Zone . . . . . . . . . . . . OpenVMS Debugger Output from SET OUTPUT LOG Command . . . .
420 421 422 423 425 427 430 460 462 711 87 1417 1510
Figures
41 71 72 73 74 91 92 93 94 95 96 97 98 99 910 911 912 913 914 915 916 917 101 102 111 112 113 114 Image Exit and Process Deletion . . . . . . . . . . . . . . . . . . . . . . . . . . . . Model Database . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Three Lock Queues . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Deadlock . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lock Status Block . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SS$_HPARITH Exception Signal Array . . . . . . . . . . . . . . . . . . . . . . . SS$_ALIGN Exception Signal Array . . . . . . . . . . . . . . . . . . . . . . . . . Format of a Condition Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Searching the Stack for a Condition Handler . . . . . . . . . . . . . . . . . . . Sample Stack Scan for Condition Handlers . . . . . . . . . . . . . . . . . . . . Format of the Signal Argument Vector . . . . . . . . . . . . . . . . . . . . . . . Signal Argument Vector for the Reserved Operand Error Conditions ...................................................... Signal Argument Vector for RTL Mathematics Routine Errors . . . . . Format of a VAX Mechanism Argument Vector . . . . . . . . . . . . . . . . . Mechanism Array on Alpha Systems . . . . . . . . . . . . . . . . . . . . . . . . . I64 Mechanism Vector Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Stack After Second Exception Condition Is Signaled . . . . . . . . . . . . Interaction Between Handlers and Default Handlers . . . . . . . . . . . . Unwinding the Call Stack . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Formats of Message Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Using a Condition Handler to Log an Error Message . . . . . . . . . . . . Structure of an Exit Handler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32-Bit Virtual Address Space Layout . . . . . . . . . . . . . . . . . . . . . . . . . 64-Bit Virtual Address Space Layout . . . . . . . . . . . . . . . . . . . . . . . . . General Format of a 32-Bit Descriptor . . . . . . . . . . . . . . . . . . . . . . . . General Format of a 64-Bit Descriptor . . . . . . . . . . . . . . . . . . . . . . . . Item_list_2 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Item_list_3 Format . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473 73 77 78 712 917 918 922 929 933 936 938 938 939 941 944 947 951 955 959 963 982 102 104 113 113 115 115
xvi
115 116 117 118 131 132 133 134 135 141 142 151 152 153
Item_list_64a Format . . . . . . . . . . . . . . . . . . . . . . . . Item_list_64b Format . . . . . . . . . . . . . . . . . . . . . . . . item_list_64a . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . item_list_64b . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Virtual Address Overview on VAX Systems . . . . . . . Layout of VAX Process Virtual Address Space . . . . . Physical Address Space for VAX Systems with XPA . Virtual Address Space for VAX Systems with XVA . Hierarchy of VAX Memory Management Routines . . Memory Fragmentation . . . . . . . . . . . . . . . . . . . . . . Boundary Tags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aligned and Unaligned Structures . . . . . . . . . . . . . . Alignment Using VAX C Compiler . . . . . . . . . . . . . . Alignment Using HP C Compiler . . . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
. . . . . . . . . . . . . .
116 117 1119 1119 132 133 134 135 137 143 149 152 155 155
Tables
11 12 13 14 15 16 17 21 22 41 42 43 44 45 46 47 48 49 410 411 412 413 61 62 63 64 71 Manual Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . OpenVMS Programming Software . . . . . . . . . . . . . . . . . . . . . . . . . Compilers, Interpreters, and Assemblers . . . . . . . . . . . . . . . . . . . . Other OpenVMS Program Development Utilities . . . . . . . . . . . . . . Groups of OpenVMS Run-Time Library Routines . . . . . . . . . . . . . Groups of OpenVMS System Services . . . . . . . . . . . . . . . . . . . . . . OpenVMS Utility Routines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Characteristics of Subprocesses and Detached Processes . . . . . . . . Comparison of LIB$SPAWN, SYS$CREPRC, and C system( ) Call Context Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Routines and Commands for Controlling Processes and Kernel Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Process Identication . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SYS$GETJPI Kernel Threads Item Codes . . . . . . . . . . . . . . . . . . . SYS$PROCESS_SCAN Kernel Threads Item Codes . . . . . . . . . . . Item-Specic Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Capabilities . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . SYSMAN Command: Class_Schedule . . . . . . . . . . . . . . . . . . . . . . Class Name Qualiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Show Subcommand Qualiers . . . . . . . . . . . . . . . . . . . . . . . . . . . . Time Manipulation System Services and Routines . . . . . . . . . . . . Process Hibernation and Suspension . . . . . . . . . . . . . . . . . . . . . . . System Services and Routines Used for Hibernation and Suspension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Contents of $DELPRC Flag Argument . . . . . . . . . . . . . . . . . . . . . . OpenVMS Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Usage Styles of Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Event Flag Routines and Services . . . . . . . . . . . . . . . . . . . . . . . . . Event Flags . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Lock Manager Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 19 110 113 115 116 117 21 23 42 45 415 416 416 433 437 438 439 459 464 464 475 615 623 624 625 72
... . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
xvii
72 73 74 75 81 82 83 91 92 93 94 95 96 97 98 99 910 911 912 913 111 112 121 122 123 131 132 141 142 143 144 151 161
Lock Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Compatibility of Lock Modes . . . . . . . . . . . . . . . . . . . . . . . . . . . Legal QUECVT Conversions . . . . . . . . . . . . . . . . . . . . . . . . . . . Effect of Lock Conversion on Lock Value Block . . . . . . . . . . . . . AST System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . System Services That Use ASTs . . . . . . . . . . . . . . . . . . . . . . . . . AST Arguments for VAX, Alpha, and I64 Systems . . . . . . . . . . . Summary of Exception Conditions . . . . . . . . . . . . . . . . . . . . . . . I64-Specic Exception Conditions . . . . . . . . . . . . . . . . . . . . . . . Architecture-Specic Hardware Exceptions . . . . . . . . . . . . . . . . Exception Summary Argument Fields . . . . . . . . . . . . . . . . . . . . Run-Time Library Condition-Handling Support Routines . . . . . Fields of a Condition Value . . . . . . . . . . . . . . . . . . . . . . . . . . . . Severity of Error Conditions . . . . . . . . . . . . . . . . . . . . . . . . . . . Privilege Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Quota Errors . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . $CHFDEF Symbolic Names and Arguments on VAX Systems . . $CHFDEF2 Symbolic Names and Arguments on Alpha and I64 Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Fields in the Alpha Mechanism Array . . . . . . . . . . . . . . . . . . . Contents of the I64 Argument Mechanism Array (MECH) . . . . . Contents of the General Descriptor Format . . . . . . . . . . . . . . . . 64-Bit System Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Sample Virtual Address Arrays for 64-Bit Services . . . . . . . . . . Page and Byte Offset Within Pages on Alpha and I64 Systems . Sample Virtual Address Arrays on Alpha and I64 Systems . . . . Sample Virtual Address Arrays on VAX Systems . . . . . . . . . . . . Flag Bits to Set for Specic Section Characteristics on VAX Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Overhead for Area Control Blocks . . . . . . . . . . . . . . . . . . . . . . . Possible Values for the Block Size Attribute . . . . . . . . . . . . . . . Attribute Values for the Default Zone . . . . . . . . . . . . . . . . . . . . Allocation Algorithms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Aligned Data Sizes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . Page Table Size Requirements . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
75 76 715 717 82 82 89 99 913 915 917 921 922 923 925 925 930 931 942 945 114 118 128 128 129 1310 1316 1410 1410 1412 1415 152 167
xviii
Preface
Intended Audience
This manual is intended for system and application programmers. It presumes that its readers have some familiarity with the HP OpenVMS programming environment.
Document Structure
The printed copy of the HP OpenVMS Programming Concepts Manual is a two-volume manual. The rst volume contains four parts; the four parts are as follows: Process and Synchronization Interrupts and Condition Handling Addressing and Memory Management Appendixes: Macros and Examples of 64-Bit Programming
Within the parts of Volume I, chapters provide information about the programming features of the OpenVMS operating system. A list of the chapters and a summary of their content follows: Chapter 1 describes the structure of the two-volume manual, and offers an introduction to the OpenVMS operating system and to the tools that are available in the programming environment. Chapter 2 denes the two types of processes, and describes what constitutes the context of a process, and the modes of execution of a process. It also describes kernel threads and the kernel threads process structure. Chapter 3 describes communication within a process and between processes. Chapter 4 describes how to use the creation and control of a process or kernel thread for programming tasks. It also describes how to gather information about a process or kernel thread and how to synchronize a program by using time. Chapter 5 describes overview concepts of symmetric multiprocessing (SMP) systems. Chapter 6 describes synchronization concepts and the differences between synchronization techniques on VAX systems, Alpha systems, and I64 systems. It presents methods of synchronization such as event ags, asynchronous system traps (ASTs), parallel processing RTLs, and process priorities, and the effects of kernel threads upon synchronization. It also describes how to use synchronous and asynchronous system services, and how to write applications in a multiprocessing environment.
xix
Chapter 7 describes the use of the lock manager system services to synchronize access to shared resources. This chapter presents the concept of resources and locks; it also describes the use of the SYS$ENQ and SYS$DEQ system services to queue and dequeue locks. Chapter 8 describes how to use asynchronous system traps (ASTs). It describes access modes and service routines for ASTs and how ASTs are declared and delivered. It also describes the effects of kernel threads on AST delivery. Chapter 9 describes the OpenVMS Condition Handling facility. It describes VAX system, Alpha system, and I64 system exceptions, arithmetic exceptions, and Alpha and I64 system unaligned access traps. It describes the condition value eld, exception dispatcher, signaling, and the argument list passed to a condition handler. Additionally, types of condition handlers and various types of actions performed by them are presented. This chapter also describes how to write and debug a condition handler, and how to use an exit handler. Chapter 10 describes the 32-bit and 64-bit use of virtual address space. Chapter 11 describes all the services, routines, tools, and programs that support 64-bit addressing. Chapter 12 describes system services and RTLs of Alpha and I64 systems to manage memory. It describes the page size and layout of virtual address space on Alpha and I64 systems. This chapter also describes how to add virtual address space, adjust working sets, control process swapping, and create and manage sections on Alpha and I64 systems. Chapter 13 describes the of system services and RTLs of VAX systems to manage memory. It describes the page size and layout of virtual address space on VAX systems. This chapter also describes how to add virtual address space, adjust working sets, control process swapping, and create and manage sections on VAX systems. Chapter 14 describes how to use RTLs to allocate and free pages and blocks of memory, and how to use RTLs to create, manage, and debug virtual memory zones. Chapter 15 describes the importance and techniques of instruction and data alignment. Chapter 16 describes the VLM memory management features, such as the following: Memory-resident global sections Fast I/O and buffer objects for global sections Shared page tables Expandable global page table Reserved memory registry
Appendix A describes the C language macros for manipulating 64-bit addresses, for checking the sign extension of the low 32 bits of 64-bit values, and for checking descriptors for the 64-bit format. Appendix B illustrates writing a program with a 64-bit region that was created and deleted by system services. Appendix C demonstrates the memory management VLM features described in Chapter 16.
xx
Related Documents
For a detailed description of each run-time library and system service routine mentioned in this manual, see the OpenVMS Run-Time Library documentation and the HP OpenVMS System Services Reference Manual. You can nd additional information about calling OpenVMS system services and Run-Time Library routines in your language processor documentation. You may also nd the following documents useful: HP OpenVMS DCL Dictionary OpenVMS Users Manual Guide to OpenVMS File Applications HP OpenVMS Guide to System Security OpenVMS Record Management Services documentation OpenVMS Utility Routines Manual HP OpenVMS I/O Users Reference Manual
For additional information about HP OpenVMS products and services, visit the following World Wide Web address: http://www.hp.com/go/openvms
Readers Comments
HP welcomes your comments on this manual. Please send comments to either of the following addresses:
Internet Postal Mail openvmsdoc@hp.com Hewlett-Packard Company OSSG Documentation Group, ZKO3-4/U08 110 Spit Brook Rd. Nashua, NH 03062-2698
Conventions
The following conventions may be used in this manual:
Ctrl/x A sequence such as Ctrl/x indicates that you must hold down the key labeled Ctrl while you press another key or a pointing device button. A sequence such as PF1 x indicates that you must rst press and release the key labeled PF1 and then press and release another key or a pointing device button.
PF1 x
xxi
Return
In examples, a key name enclosed in a box indicates that you press a key on the keyboard. (In text, a key name is not enclosed in a box.) In the HTML version of this document, this convention appears as brackets, rather than a box.
...
A horizontal ellipsis in examples indicates one of the following possibilities: Additional optional arguments in a statement have been omitted. The preceding item or items can be repeated one or more times. Additional parameters, values, or other information can be entered.
. . . ()
A vertical ellipsis indicates the omission of items from a code example or command format; the items are omitted because they are not important to the topic being discussed. In command format descriptions, parentheses indicate that you must enclose choices in parentheses if you specify more than one. In command format descriptions, brackets indicate optional choices. You can choose one or more items or no items. Do not type the brackets on the command line. However, you must include the brackets in the syntax for OpenVMS directory specications and for a substring specication in an assignment statement. In command format descriptions, vertical bars separate choices within brackets or braces. Within brackets, the choices are optional; within braces, at least one choice is required. Do not type the vertical bars on the command line. In command format descriptions, braces indicate required choices; you must choose at least one of the items listed. Do not type the braces on the command line. Bold type represents the introduction of a new term. It also represents the name of an argument, an attribute, or a reason. Italic type indicates important information, complete titles of manuals, or variables. Variables include information that varies in system output (Internal error number), in command lines (/PRODUCER=name), and in command parameters in text (where dd represents the predened code for the device type). This typeface indicates code examples, command examples, and interactive screen displays. In text, this type also identies URLs, UNIX commands and pathnames, PC-based commands and folders, and certain elements of the C programming language. Uppercase type indicates a command, the name of a routine, the name of a le, or the abbreviation for a system privilege. A hyphen at the end of a command format description, command line, or code line indicates that the command or statement continues on the following line. All numbers in text are assumed to be decimal unless otherwise noted. Nondecimal radixesbinary, octal, or hexadecimalare explicitly indicated.
[]
{}
Example
UPPERCASE TYPE -
numbers
xxii
1
Overview of Manuals and Introduction to Development on OpenVMS Systems
This chapter describes the structure of this two-volume manual. This chapter also provides an overview of the OpenVMS operating system, its components, and the tools in programming software.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.1 Overview of the Manual
Table 11 Manual Description
Volume Volume I Part I Process and Synchronization. Describes the creation, communication, and control of processes. It also describes symmetric multiprocessing (SMP), and the synchronizing of data access, programming operations, and access to resources. Interrupts and Condition Handling. Describes the use of asynchronous system traps (ASTs), and the use of routines and services for handling conditions. Addressing and Memory Management. Describes 32-bit and 64-bit address space, and the support offered for 64-addressing. It also provides guidelines for 64-bit application programming interfaces (APIs); and Alpha, I64, VAX, and VLM memory management with runtime routines for memory management, and alignment on OpenVMS Alpha, VAX, and I64 systems. Appendixes: Macros and Examples of 64Bit Programming. Describes the macros used in 64-bit programming, along with two examples of 64-bit programmming. Part Description
Part II
Part III
Part IV
Volume II Part I OpenVMS Programming Interfaces: Calling a System Routine. Describes the basic calling format for OpenVMS routines and system services. It also describes the STARLET structures and denitions for C programmers. I/O, System and Programming Routines. Describes the I/O operations, and the system and programming routines used by run-time libraries and system services. Generic Macros for Calling System Services. Describes in appendixes the generic macros used for calling system services, OpenVMS data types, and the distributed name services on OpenVMS VAX systems.
Part II
Part III
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.2 Overview of the OpenVMS Operating System
The OpenVMS operating system conguration includes OpenVMS integrated software, services and routines, applications, and networks. The system supports all styles of computing, from timesharing to real-time processing to transaction processing. OpenVMS systems congured with optional software support distributed computing capabilities and can function as servers in multivendor client/server congurations. The OpenVMS operating system is designed to provide software compatibility across all the processors on which it runs. The following sections describe the components of the OpenVMS operating system, give a general overview of the system software, and describe the various styles of computing that OpenVMS software supports. The sections also summarize the basic ways in which OpenVMS software can be congured and connected to other software, and the hardware platforms and processors on which the OpenVMS software runs.
OpenVMS software developed on VAX platforms can migrate easily to Alpha and I64 platforms (see Section 1.3.1.1): Most user-mode OpenVMS VAX sources can be recompiled, relinked, and run on an OpenVMS Alpha and OpenVMS I64 system without modication. Code that explicitly relies on the VAX architecture requires modication. Most OpenVMS Alpha images run under translation on OpenVMS I64. Translation is available for OpenVMS VAX applications without sources or that you do not want to recompile.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.3 Components of the OpenVMS Operating System 1.3.1 OpenVMS Systems on Multiple Platforms
The OpenVMS operating system is available on three hardware platforms: A complex instruction set computer (CISC) architecture based on the VAX architecture A reduced instruction set computer (RISC) architecture based on the Alpha architecture The explicitly parallel instruction computing (EPIC) architecture used by Itanium systems.
1.3.1.1 System Compatibility and Program Portability Across Platforms The OpenVMS Alpha and OpenVMS I64 operating systems are compatible with OpenVMS VAX systems in terms of user, system manager, and programmer environments. For general users and system managers, OpenVMS Alpha and OpenVMS I64 have the same interfaces as OpenVMS VAX. Virtually all OpenVMS VAX system management utilities, command formats, and tasks are identical in the OpenVMS Alpha and OpenVMS I64 environments. Mixedarchitecture and mixed-version clusters that contain both Alpha systems and VAX systems are supported.
OpenVMS software capabilities include both the standardized features of open systems computing and the commercial-strength functionality of traditional OpenVMS systems. System and network management software provides for control of heterogeneous, integrated environments. The following sections describe the capabilities supported in OpenVMS computing environments and summarize the software resources available in each kind of environment. 1.3.2.1 Open System Capabilities OpenVMS offers the benets of an open system environment, which permits both applications and users to move between systems. In addition, applications on different open systems can operate together. The OpenVMS operating system makes available a set of services in an open domain, while still offering its traditional high-integrity computing services. Incorporation of open computing capabilities enhances the traditional feature-rich OpenVMS environment.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.3 Components of the OpenVMS Operating System
Software in the OpenVMS open systems environment enables the development and use of portable applications and consistent user interfaces and also permits systems to operate together. The keys to openness of OpenVMS systems are standard programming interfaces, standardized user interfaces, and standard protocols. 1.3.2.2 Application Portability Application portability is the capability to easily move an application from one system to another. Standard programming interfaces permit application and data portability. Portable applications written strictly to a suite of open specications provide the following benets: Applications can be written once and run on other open platforms that support the standards used in the applications. Users can access the wide range of applications available on open platforms. Applications can be supplied by different vendors.
Applications that are developed on the three supported platforms and conform to open standards can be easily ported to other systems that conform to the same standard interfaces. Applications written in ISO and ANSI languages are portable to other systems. In addition, The Open Group/Motif graphical user interface supports application portability. 1.3.2.2.1 Other Application Portability Features Applications written in ISO/ANSI languages are easily portable to other platforms that support them. OpenVMS VAX, OpenVMS Alpha, and OpenVMS I64 provide support for such languages as C, COBOL, and Fortran.
This style of computing allows each portion of a distributed application to run in its own optimal environment. The whole application does not have to run on one centralized system (such as a mainframe system), but enterprisewide cohesiveness can still be maintained. For example, individuals or local ofces, using their own computers and running software appropriate to their needs,
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.3 Components of the OpenVMS Operating System
can be linked to large computers or OpenVMS Cluster systems in a network. A distributed computing system can function as though it were a single system that connects all parts of an enterprise. The client can have transparent access to the integrated resources of the enterprise. Any system can be a client or a server, and some systems may include both client software for certain applications and server software for other applications. Servers can be connected to many clients, and a client can be connected to more than one server at a time. (Client and server relationships may change frequently: at times it may not be possible to tell which is the client and which is the server.) In some cases, the application is stored on the server and run on the client, using the resources of the client. The user, who does not need to know what system is serving the application, can function in a familiar, local environment. 1.3.3.2 OpenVMS Client/Server Capabilities OpenVMS systems support a wide variety of client/server congurations. Clients requiring resources can be personal computers, workstations, point-of-sale devices, OpenVMS systems, or systems from other vendors that are running the appropriate client software. Users on client systems can use character-cell terminals or windowing desktops. Servers fullling clients requests can be located on OpenVMS systems or other operating systems running appropriate server software. OpenVMS servers, for example, can provide le access, printing, application services, communication services, and computing power as application engines to clients on desktop devices or in laboratories or factories. Client/server congurations permit the commercial-strength capabilities of OpenVMS host systems to be integrated with the personal-computing capabilities of desktop systems. Middleware, which runs on OpenVMS and other systems from multiple vendors, can be used to tie together clients and servers. Middleware integrates various client and server systems through application, communication, data interchange, and multivendor support. Complex information-sharing environments involving PC clients and operating system servers are supported. An essential feature of the OpenVMS operating system is its support of a rich environment for developing software application programs. The programming software integrated in the OpenVMS system provides the tools required to effectively develop new software applications. You also have the option of using additional powerful tools to enhance the productivity of software development in the OpenVMS environment. The following sections summarize the primary program development features available on all three supported platforms. The sections also introduce the OpenVMS programming environment and present brief functional descriptions of the OpenVMS programming tools.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.4 The OpenVMS Programming Environment
In the OpenVMS programming environment, you can use OpenVMS resources to perform the following tasks: Creating, controlling, and deleting processes Communicating with other components Sharing resources Implementing input/output procedures Using security features Managing memory Managing les Synchronizing events Providing for condition handling Calling utility routines
The components of an OpenVMS application are the main program, shared libraries, functional routines, and a user interface. Software tools that support development of applications in the OpenVMS programming environment include: Language compilers, interpreters, and assemblers Linkers and debuggers Text processors and other program development utilities Callable system routines such as run-time routines, system services, and other utility routines Record Management Services (RMS) routines and utilities
Optional software development tools that run on the OpenVMS system enhance programmer productivity, saving programming time and promoting the development of error-free code. OpenVMS supports optional integrated software products that enhance program development capabilities in an organization. These software development products can make use of middleware services that facilitate the development of applications for multivendor networks and for web-enabling tools to help develop client/server applications. Middleware and web-enabling tools allow you to access data and information by using the web. The various middleware and web-enabling tools perform the following: Provide web access to data Provide web access to applications Provide web tools for commercial web servers Provide other web tools including freeware
Middleware products and capabilities include Distributed Computing Environment (DCE), COM for OpenVMS, and HP Reliable Transaction Router for OpenVMS. Web-enabling tools include HP DECforms Web Connector, and TP Web Connector. For more information about middleware and web-enabling tools, go to the following URL: http://h71000.www7.hp.com/solutions/appdev.html
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.4 The OpenVMS Programming Environment 1.4.1 Programming to Standards
Coding of programs for the OpenVMS environment and for other environments involves conforming to software development standards. OpenVMS standards that dene modular programming techniques and procedure calling and condition handling practices pertain to applications specic to OpenVMS. IEEE and international standards apply to applications developed on OpenVMS that are designed to run on other systems as well as on OpenVMS. 1.4.1.1 Common Environment for Writing Code OpenVMS software programmers can write code in a common environment, following standard OpenVMS modular programming practices. This standard approach establishes the minimum criteria necessary to ensure the correct interface at the procedure level between software written by different programmers. If all programmers coding OpenVMS applications follow this standard approach, modular procedures added to a procedure library will not conict with other procedures in the library. Standard modular programming practices apply to OpenVMS programs that have a public entry point. For details of this standard approach, see the Guide to Creating OpenVMS Modular Procedures. 1.4.1.2 Common Language Environment The OpenVMS system supports a common language environment, which permits using a mixture of languages in programming. A program written in any of the programming languages supported by OpenVMS can contain calls to procedures written in other supported languages. Mixed-language programming is possible because all supported languages adhere to the OpenVMS calling standard. This standard describes the techniques used by all supported languages for invoking routines and passing data between them. It also denes the mechanisms that ensure consistency in error and exception handling routines, regardless of the mix of programming languages. Information about the calling standard appears in the HP OpenVMS Calling Standard, and descriptions of how to use the calling interface are given in Chapter 17 and Chapter 18.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software
Table 12 OpenVMS Programming Software
Type of Software Text processors OpenVMS Software Components DEC Text Processing Utility/Extensible Versatile Editor (DECTPU/EVE) EDT editor vi, ed, and ex editors (POSIX) HP Language-Sensitive Editor/Source Code Analyzer Linker OpenVMS Debugger Delta/XDelta Debugger OpenVMS Alpha System-Code Debugger1 Command Denition utility Librarian utility Message utility Patch utility2 SUMSLP utility National Character Set utility System Dump Analyzer POSIX for OpenVMS utilities Run-time library routines System services Utility routines Record Management Services (RMS) routines and utilities
specic.
specic.
The commands used to invoke some of the programming utilities (for example, linker, debugger, LIBRARIAN) vary slightly for the three supported platforms.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software 1.5.2 Creating Object Files
OpenVMS supports a variety of optional language compilers, interpreters, and assemblers that translate source code to object code (in the form of object modules). These language implementations adhere to industry standards, including ISO, ANSI, X/Open standards as well as U.S. Federal Information Processing Standards (FIPS) and Military Standards (MIL-STD), as applicable. Table 13 lists language compilers, interpreters, and assemblers supported in the OpenVMS VAX, OpenVMS Alpha, and OpenVMS I64 environments. Table 13 Compilers, Interpreters, and Assemblers
Language HP Ada Characteristics Complete production-quality implementation of Ada language; fully conforms to ANSI and MIL-STD standards; has Ada validation Interpreter with built-in editor, debugger, le system, communication facility Either an interpreter or a compiler; fully supported by the OpenVMS debugger; fully reentrant code An optimizing compiler; highly compatible with VAX BASIC; no environment or interpreter support; also available on I64. Advanced set of language features supporting development of modular software according to structured programming concepts; also available on I64 Development of modular software support for 64-bit programs; not available on VAX Full implementation of C programming language with added features for performance enhancement in the OpenVMS environment Compliant with ANSI/ISO C International Standard with HP extensions; includes standard-conformance checking and many optional code-quality and portability diagnostics; supports 64-bit virtual addressing; generates optimized and positionindependent code Compliant with ANSI/ISO C++ International Standard with HP extensions; supports the ARM, GNU, and MS dialects; supports 64-bit virtual addressing; generates highly optimized object code; facilitates object-oriented program design Compliant with ANSI-standard COBOL; includes as enhancements screen-handling, le-sharing, and report-writing facilities; is supported on I64 For interactive data processing; includes a compiler, debugger, and utility programs for data handling, data storing, and interprogram communication (continued on next page)
VAX DIBOL
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software
Table 13 (Cont.) Compilers, Interpreters, and Assemblers
Language HP Fortran 77 for OpenVMS VAX Characteristics Extended implementation of full language FORTRAN77, conforming to American National Standard FORTRAN, ANSI X3.9-1978. It includes optional support for programs conforming to ANSI X3.91966 (FORTRAN IV) and meets Federal Information Processing Standard Publication FIPS-69-1 and MILSTD-1753. ANSI-standard Fortran 90 and Fortran 95 optimizing compiler; available on I64 and Alpha systems Assembly language for programming the VAX computer under the OpenVMS operating system; uses all OpenVMS resources; supports large instruction set enabling complex programming statements Available on OpenVMS I64 and Alpha systems to port existing VAX MACRO code to an Alpha or I64 system Available on OpenVMS Alpha systems; a RISC assembly language that provides precise control of instructions and data ANSI-standard Pascal features and language extensions that go beyond the standard; available on VAX, Alpha, and I64
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software
The Delta/XDelta Debugger (DELTA/XDELTA), which debugs code in other modes as well as user mode. (The DELTA debugger has not yet been ported to the OpenVMS I64 operating system.)
The OpenVMS symbolic debugger is more useful than DELTA/XDELTA for most programs: the symbolic commands entered using different interfaces (keypad, command line, or le of commands) display source code lines on the screen, have more descriptive error messages, and provide help information. The debugger command language specied in the HP OpenVMS Debugger Manual provides more than 100 commands to control a debugging session, including these tasks: Control program execution on a line-by-line basis or at a user-specied breakpoint Display breakpoints, tracepoints, watchpoints, active routine calls, stack contents, variables, symbols, source code, and source directory search list Dene symbols Create key denitions Change values in variables Evaluate a language or address expression Create or excute debugger command procedures
The OpenVMS symbolic debugger provides enhanced support for programs that have multiple threads of execution within an OpenVMS process, including any program that uses POSIX Threads Library for developing real-time applications. The debugger has been modied to support debugging of programs that contain 64-bit data addresses. An additional debugger utility is available only on an OpenVMS Alpha system: the OpenVMS Alpha System-Code Debugger, which can be used to debug nonpageable system code and device drivers. The system-code debugger is a symbolic debugger that lets the user employ the familiar OpenVMS Debugger interface to observe and manipulate system code interactively as it executes. The system-code debugger can display the source code where the software is executing and allows the user to advance by source line. Users can perform the following tasks using the system-code debugger: Control the system softwares execution, stopping at points of interest, resuming execution, intercepting fatal exceptions, and so on Trace the execution path of the system software Monitor exception conditions Examine and modify the value of variables In some cases, test the effect of modications without having to edit the source code, recompile, and relink
You can use the OpenVMS Alpha System-Code Debugger to debug code written in the following languages: C, BLISS, and MACRO. Information about using the system-code debugger and how it differs from the OpenVMS Debugger is given in Writing OpenVMS Alpha Device Drivers in C.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software
1.5.4.1 Special Modes of Operation for Debugging The OpenVMS operating system has a number of special modes of operation designed to aid in debugging complex hardware and software problems. In general terms, these special modes enable an extra level of tracing, data recording, and consistency checking that is useful in identifying a failing hardware or software component. These modes of operation are controlled by the following system parameters: MULTIPROCESSING POOLCHECK BUGCHECKFATAL SYSTEM_CHECK
MULTIPROCESSING is useful for debugging privileged code that uses spinlocks, such as device driver code. POOLCHECK is useful for investigating frequent and inexplicable failures in a system. When POOLCHECK is enabled, pool-checking routines execute whenever pool is deallocated or allocated. BUGCHECKFATAL is useful for debugging the executive. SYSTEM_CHECK turns on the previous three system parameters and also activates other software that aids in detecting problems. It enables a number of run-time consistency checks on system operation and records some trace information. If you are using one of these special modes, for example, to debug a device driver or other complex application, under certain conditions generally related to high I/O loads, it is possible to incur a CPUSPINWAIT bugcheck. To prevent a CPUSPINWAIT bugcheck, use either the system default settings for these system parameters, or reduce the loading of the system. If you have reason to change the default settings, you can reduce the likelihood of encountering a problem by setting the SMP_LNGSPINWAIT system parameter to a value of 9000000.
1 PATCH/IMAGE
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.5 OpenVMS Programming Software
Table 14 (Cont.) Other OpenVMS Program Development Utilities
Utility SUMSLP utility Function Supplies batch-oriented editor used to make several updates to a single source le; one update program can be applied to all versions of a le Permits users to dene non-ASCII string collating sequences and to dene conversion functions; allows an RMS indexed le to be collated using user-specied collating sequences Determines the cause of system failures; reads the crash dump le and formats and displays it; also used to diagnose root causes that lead to an error
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.6 Using Callable System Routines
On OpenVMS Alpha and OpenVMS I64 systems, POSIX threads provide support to accept 64-bit parameters. The highly portable POSIX threads interface contains routines grouped in the following functional categories: General threads Object attributes Mutex Condition variable Thread context Thread cancellation Thread priority and scheduling Debugging
For more information about threads, see the Guide to the POSIX Threads Library.
MTH$ routines1 DPML$ routines OTS$ routines SMG$ routines STR$ routines
1 VAX
specic
In addition, language-specic RTL routines support procedures in Ada, BASIC, C, COBOL, Fortran, Pascal, and PL/I (VAX only) as well as in POSIX C. HP C
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.6 Using Callable System Routines
RTL routines support 64-bit programming on OpenVMS Alpha and OpenVMS I64 systems. CXML is a collection of mathematical routines optimized for Alpha systems. These subroutines perform numerically intensive operations that occur frequently in engineering and scientic computing, such as linear algebra and signal processing. CXML can help reduce the cost of computation, enhance portability, and improve productivity.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.6 Using Callable System Routines
Table 16 (Cont.) Groups of OpenVMS System Services
Service Group Condition handling Memory management Change mode Lock management DECdtm services Cluster event notication1
1 Alpha
Function Designates condition-handling procedures that gain control when an exception/condition occurs Permits control of an application programs virtual address space Changes the access mode of a process Permits cooperating processes to synchronize their access to shared resources Provide for complete and consistent execution of distributed transactions and for data integrity Requests notication when an OpenVMS Cluster conguration event occurs
OpenVMS I/O system services perform logical, physical, and virtual I/O and network operations, and queue messages to system processes. The $QIO system service provides a direct interface to the operating systems I/O routines. These services are available from within most programming languages supported by OpenVMS and can be used to perform low-level I/O operations efciently with a minimal amount of system overhead for time-critical applications. On OpenVMS Alpha and OpenVMS I64 systems, new system services provide access to 64-bit virtual address space for process private use. Additionally, new system services are available to provide high CPU performance and improved symmetric multiprocessing (SMP) scaling of I/O operations. These services exhibit high-performance gains over the $QIO service. DECdtm services ensure consistent execution of applications on the OpenVMS operating system. In transaction processing applications, many users may be simultaneously making inquiries and updating a database. The distributed transaction processing environment typically involves communication between networked systems at different locations. DECdtm services coordinate distributed transactions by using the two-phase commit protocol and implementing special logging and communication techniques. DECdtm services ensure that all parts of a transaction are completed or the transaction is aborted.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.6 Using Callable System Routines
Table 17 (Cont.) OpenVMS Utility Routines
Routine CONV$ DCX$ EDT$ FDL$ LBR$ LGI$ MAIL$ NCS$ PSM$ SMB$ SOR$ TPU$ Utility/Facility Convert and Convert/Reclaim utilities (CONVERT and CONVERT/RECLAIM) Data Compression/Expansion facility (DCX) EDT editor File Denition Language utility (FDL) Librarian utility (LIBRARIAN) LOGINOUT routines Mail utility (MAIL) National Character Set utility (NCS) Print Symbiont Modication facility (PSM) Symbiont/Job-Controller Interface facility (SMB) Sort/Merge utility (SORT/MERGE) DEC Text Processing Utility (DECTPU)
You can use an optional, portable library of user-callable routines to perform high-performance sorting on OpenVMS Alpha systems. The high-performance sort supports a subset of the functionality present on the OpenVMS Sort/Merge utility, using the callable interface to the SOR$ routine. The high-performance sort/merge provides better performance for most sort and merge operations.
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.7 Programming User Interfaces
An applications programmer can use the following HP DECwindows Motif for OpenVMS software to construct a graphical user interface: A user interface toolkit composed of graphical user interface objects (widgets and gadgets); widgets provide advanced programming capabilities that permit users to create graphic applications; gadgets, similar to widgets, require less memory to create labels, buttons, and separators A user interface language to describe visual aspects of objects (menus, labels, forms) and to specify changes resulting from user interaction The OSF/Motif Window Manager, which allows users to customize the interface
The HP DECwindows Motif for OpenVMS programming libraries provided include: Standard X Window System libraries such as Xlib and the intrinsics Libraries needed to support the current base of XUI applications OSF/Motif toolkit support for developing applications using the Motif user interface style HP libraries that give users capabilities beyond the standards
Overview of Manuals and Introduction to Development on OpenVMS Systems 1.9 Managing Data
RMS routines assist user programs in processing and managing les and their contents. RMS routines perform these services for application programs: Creating new les, accessing existing les, extending disk space for les, closing les, and obtaining le characteristics Getting, locating, inserting, updating, and deleting records in les
RMS promotes safe and efcient le sharing by providing multiple access modes, automatic record locking when applicable, and optional buffer sharing by multiple processes.
The Analyze/RMS_File utility allows the programmer to analyze the internal structure of an OpenVMS RMS le and generate a report on its structure and use, as well as interactively explore the les structure. The utility can generate an FDL le from an RMS le for use with the Edit/FDL utility to optimize the data le. File Denition Language (FDL) is a special-purpose language for specifying le characteristics; it is useful with higher level languages or for ensuring that les are properly tuned. FDL makes use of RMS control blocks: the le access block (FAB), the record access block (RAB), and the extended attribute block (XAB). The Edit/FDL utility creates a new FDL le according to user specications. The Create/FDL utility uses the specications of an existing FDL le to create a new empty data le. You can use the Convert utility to copy records from one le to another, while changing the record format and le organization, and to append records to an existing le. The Convert/Reclaim utility reclaims empty bucket space in an indexed le to allow new records to be written to it.
Part I
Process and Synchronization
This part describes the creation, communication, and control of processes. It also describes symmetric multiprocessing (SMP), and the synchronizing of data access, programming operations, and access to resources.
2
Process Creation
This chapter describes process creation and the different types of processes. It also describes kernel threads and the kernel threads process structure. This chapter contains the following sections: Section 2.1 denes a process and describes the two types of processes. Section 2.2 describes the execution context of a process. Section 2.3 describes the modes of execution of a process. Section 2.4 describes the creation of a subprocess. Section 2.5 describes the creation of a detached process. Section 2.6 describes the creation and use of process quota lists (PQLs). Section 2.7 describes debugging within a subprocess and a detached process. Section 2.8 describes kernel threads and the parts that make up the kernel threads process. Section 2.9 describes I64-specic thread use and considerations.
Process Creation 21
When the system creates a detached process as the result of a login, it uses the system user authorization le (SYSUAF.DAT) to determine the processs execution context. For example, the following occurs when you log in to the system: 1. The process created for you executes the image LOGINOUT. 2. The terminal you are using is established as the input, output, and error stream device for images that the process executes. 3. Your disk and directory defaults are taken from the user authorization le. 4. The resource quotas and privileges you have been granted by the system manager are associated with the created process. 5. A command language interpreter (CLI) is mapped into the created process.
22 Process Creation
1 The created subprocess can include DCL by executing the system image SYS$SYSTEM:LOGINOUT.EXE. 2 Plus
group job and system logical name tables. is default, can also be specied.
3 Parents
Process Creation 23
24 Process Creation
Process Creation 25
26 Process Creation
Process Creation 27
logical name SYS$INPUT. This logical name may represent a mailbox that the calling process previously created with the Create Mailbox and Assign Channel (SYS$CREMBX) system service. Any input the subprocess reads from the logical device SYS$INPUT is from the mailbox.
" The output argument equates the equivalence name COMPUTE_OUT to
the logical name SYS$OUTPUT. All messages the program writes to the logical device SYS$OUTPUT are to this le. When a workstation (WSA0) device is specied with LOGINOUT as the image, the target (created) process receives the specied workstation as its DECwindows default display (DECW$DISPLAY).
28 Process Creation
logical name SYS$ERROR. All system-generated error messages are written into this le. Because this is the same le as that used for program output, the le effectively contains a complete record of all output produced during the execution of the program image. The SYS$CREPRC system service does not provide default equivalence names for the logical names SYS$INPUT, SYS$OUTPUT, and SYS$ERROR. If none are specied, any entries in the group or system logical name tables, if any, may provide equivalences. If, while the subprocess executes, it reads or writes to one of these logical devices and no equivalence name exists, an error condition results. The SYS$CREPRC system service also does not provide default equivalence names for the logical names SYS$LOGIN, SYS$LOGIN_DEVICE, and SYS$SCRATCH. These logical names are available to the created process only when the specied image is LOGINOUT, and when the PRC$M_NOUAF ag is not set. In a program that creates a subprocess, you can cause the subprocess to share the input, output, or error device of the creating process. You must rst follow these steps: 1. Use the Get Device/Volume Information (SYS$GETDVIW) system service to obtain the device name for the logical name SYS$INPUT, SYS$OUTPUT, or SYS$ERROR. 2. Specify the address of the descriptor returned by the SYS$GETDVIW service when you specify the input, output, or error argument to the SYS$CREPRC system service. This procedure is illustrated in the following example: #include <descrip.h> #include <dvidef.h> #include <efndef.h> #include <lib$routines.h> #include <ssdef.h> #include <starlet.h> #include <stdio.h> #include <stsdef.h> // Comment syntax used here assumes compiler support main() { #define MAXTERMLEN 64 #define MAXITMLST 3 char TermName[MAXTERMLEN]; int BasPri = 4; int RetStat; int TermLen; unsigned short int IOSB[4]; // ItemList data structures used to acquire device name int i; struct { unsigned short int BufLen; unsigned short int ItmCod; void *BufAdr; void *BufRLA; } ItmLst[MAXITMLST];
Process Creation 29
no event flag needed here Channel (not needed here) Device Name item list Address of I/O Status Block
// // // //
The image to be run Input (SYS$INPUT device) Output (SYS$OUTPUT device) Error (SYS$ERROR device)
In the following example, the program assigns a channel to the device specied by the logical name SYS$OUTPUT:
For more information about channel assignment for I/O operations, see Chapter 23. Setting Privileges Set different privileges by dening the privilege list for the subprocess using the prvadr argument. This is particularly useful when you want to dedicate a subprocess to execute privileged or sensitive code. If you do not specify this argument, the privileges of the calling process are used. If you specify the prvadr argument, only the privileges specied in the bit mask are used; the privileges of the calling process are not used. For example, a creating process has the user privileges GROUP and TMPMBX. It creates a process, specifying the user privilege TMPMBX. The created process receives only the user privilege TMPMBX; it does not have the user privilege GROUP. If you need to create a process that has a privilege that is not one of the privileges of your current process, you must have the user privilege SETPRV. Symbols associated with privileges are dened by the $PRVDEF macro. Each symbol begins with PRV$M_ and identies the bits in the bit mask that must be set to specify a given privilege. The following example shows the data denition for a bit mask specifying the GRPNAM and GROUP privileges: unsigned int PrivQuad[2] = { (PRV$M_GRPNAM | PRV$M_GROUP), 0}; // could also use: __int64 PrivQuad = PRV$M_GRPNAM | PRV$M_GROUP; Setting Process Quotas Set different process quotas by dening the quota list of system resources for the subprocess using the quota argument. This option can be useful when managing a subprocess to limit use of system resources (such as AST usage, I/O, CPU time, lock requests, and working set size and expansion). If you do not specify this argument, the system denes default quotas for the subprocess. The following example shows how to construct the process quota array for the SYS$CREPRC call using HP C, and particularly how to avoid problems on OpenVMS Alpha due to the default use of member alignment. Without the nomember_alignment setting, there would be three pad bytes embedded within each element of the array, and SYS$CREPRC would not perform as expected.
}, }, }, }, }, }, }, }, }, }, }, }, }, }, }
For more information about process quotas and process quota lists, see Section 2.6. Setting the Subprocess Priority Set the subprocess priority by setting the base execution priority with the baspri argument. If you do not set the subprocess priority, the priority defaults to 2 for MACRO and BLISS and to 0 for all other languages. If you want a subprocess to have a higher priority than its creator, you must have the user privilege ALTPRI to raise the priority level. Specifying Additional Processing Options Enable and disable parent and subprocess wait mode, control process swapping, control process accounting, control process dump information, control authorization checks, and control working set adjustments using the stsg argument. This argument denes the status ag, a set of bits that controls some execution characteristics of the created process, including resource wait mode and process swap mode. Dening an Image for a Subprocess to Execute When you call the SYS$CREPRC system service, use the image argument to provide the process with the name of an image to execute. For example, the following lines of C create a subprocess to execute the image named CARRIE.EXE: $DESCRIPTOR(image,"CARRIE"); . . . RetStat = sys$creprc(0, &image, . . . ); In this example, only a le name is specied; the service uses current disk and directory defaults, performs logical name translation, uses the default le type .EXE, and locates the most recent version of the image le. When the subprocess completes execution of the image, the subprocess is deleted. Process deletion is described in Chapter 4.
The following program segment creates a detached process to execute the DCL commands in the command le SYS$USER:[TEST]COMMANDS.COM. The system image SYS$SYSTEM:LOGINOUT.EXE is executed to include DCL in the created process. The DCL commands to be executed are specied in a command procedure that is passed to SYS$CREPRC as the input le. Output is written to the le SYS$USER:[TEST]OUTPUT.DAT. . . . STATUS = SYS$CREPRC (, 2 SYS$SYSTEM:LOGINOUT, ! 2 SYS$USER:[TEST]COMMANDS.COM,! 2 SYS$USER:[TEST]OUTPUT.DAT, ! 2 ,,,, 2 %VAL(4), ! 2 ,, 2 %VAL(%LOC(PRC$M_DETACH))) !
See Chapter 9 in the HP OpenVMS Debugger Manual for more details on debugging subprocesses and detached processes. Kept Debugger With the kept debugger conguration, you start the debugger user interface using the DCL command DEBUG/KEEP. At the DBG> prompt, you then issue either the RUN or the CONNECT command, depending on whether or not the program you want to debug is already running.
The second requirement effectively means that the program must have been started with a command similar to: $ RUN/DETACH/INPUT=xxx.com SYS$SYSTEM:LOGINOUT where xxx.com is a command procedure that starts the program with /NODEBUG. After you have started or connected to the program, the remainder of the debugging session is the same as a normal debugger session. DBG$ Logical Names You can allow a program to be debugged within a subprocess or a detached process by using DBG$INPUT and DBG$OUTPUT. To allow debug operations with DBG$INPUT and DBG$OUTPUT, equate the subprocess logical names DBG$INPUT and DBG$OUTPUT to the terminal. When the subprocess executes the program, which has been compiled and linked with the debugger, the debugger reads input from DBG$INPUT and writes output to DBG$OUTPUT. If you are executing the subprocess concurrently, you should restrict debugging to the program in the subprocess. The debugger prompt DBG> should enable you to differentiate between input required by the parent process and input required by the subprocess. However, each time the debugger displays information, you must press the Return key to display the DBG> prompt. (By pressing the Return key, you actually write to the parent process, which has regained control of the terminal following the subprocesss writing to the terminal. Writing to the parent process allows the subprocess to regain control of the terminal.) DECwindows DECterm Display If you have DECwindows installed, you can use display for debugging a subprocess or detached process. The following debugging example with DECterm shows how to create a DECterm display, and pass it into the SYS$CREPRC call for use with an application that is built using the OpenVMS Debugger: #pragma module CREATE_DECTERM #include #include #include #include #include #include #include <descrip.h> <lib$routines.h> <pqldef.h> <prcdef.h> <ssdef.h> <starlet.h> <stsdef.h>
// Request creation of a DECterm display RetStat = decw$term_port( 0, // display (use default) 0, // setup file (use default) &Customization, // customization &DbgTerm, // resulting device name &DbgTermLen, // resulting device name length 0, // controller (use default) 0, // char buffer (use default) 0 ); // char change buffer (default) if ( !$VMS_STATUS_SUCCESS (RetStat )) lib$signal( RetStat ); DbgTerm.dsc$w_length = DbgTermLen; // Create the process as detached. StsFlg = PRC$M_DETACH; // Now create the process RetStat = sys$creprc( 0, // PID &Command, // Image to invoke &DbgTerm, // Input &DbgTerm, // Output 0, 0, 0, 0, 0, 0, 0, StsFlg ); // Process creation flags if ( !$VMS_STATUS_SUCCESS( RetStat )) lib$signal( RetStat ); return SS$_NORMAL; }
2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
This section denes and describes some advantages of using kernel threads. It also describes some kernel threads features, as well as the design changes made to the OpenVMS operating system.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
Note For information about the concepts and implementation of user threads with HP POSIX Threads Library, refer to the Guide to the POSIX Threads Library.
2.8.2.1 Multiple Execution Contexts Within a Process Before the implementation of kernel threads, the scheduling model for the OpenVMS operating system was per process. The only scheduling context was the process itself, that is, only one execution context per process. Since a threaded application could create thousands of threads, many of these threads could potentially be executing at the same time. But because OpenVMS processes had only a single execution context, in effect, only one of those application threads was running at any one time. If this multithreaded application was running on a multiprocessor system, the application could not make use of more than a single CPU. After the implementation of kernel threads, the scheduling model allows for multiple execution contexts within a process; that is, more than one application thread can be executing concurrently. These execution contexts are called kernel threads. Kernel threads allow a multithreaded application to have a thread executing on every CPU in a multiprocessor system. Therefore, kernel threads allow a threaded application to take advantage of multiple CPUs in a symmetric multiprocessing (SMP) system. The maximum number of kernel threads that can be created in a process is 256.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
2.8.2.2 Efcient Use of the OpenVMS and POSIX Threads Library Schedulers The user mode thread manager schedules individual user mode application threads. On OpenVMS, POSIX Threads Library is the user mode threading package of choice. Before the implementation of kernel threads, POSIX Threads Library multiplexed user mode threads on the single OpenVMS execution contextthe process. POSIX Threads Library implemented parts of its scheduling by using a periodic timer. When the AST executed and the thread manager gained control, the thread manager could then select a new application thread for execution. But because the thread manager could not detect that a thread had entered an OpenVMS wait state, the entire application blocked until that periodic AST was delivered. That resulted in a delay until the thread manager regained control and could schedule another thread. Once the thread manager gained control, it could schedule a previously preempted thread unaware that the thread was in a wait state. The lack of integration between the OpenVMS and POSIX Threads Library schedulers could result in wasted CPU resources. After the implementation of kernel threads, the scheduling model provides for scheduler callbacks, which is not the default. A scheduler callback is an upcall from the OpenVMS scheduler to the thread manager whenever a thread changes state. This upcall allows the OpenVMS scheduler to inform the thread manager that the current thread is stalled and that another thread should be scheduled. Upcalls also inform the thread manager that an event a thread is waiting on has completed. The two schedulers are now better integrated, minimizing application thread scheduling delays. 2.8.2.3 Terminating a POSIX Threads Image To avoid hangs or a disorderly shutdown of a multithreaded process, HP recommends that you issue an upcall with an EXIT command at the DCL prompt ($). This procedure causes a normal termination of the image currently executing. If the image declared any exit-handling routines, for instance, they are then given control. The exit handlers are run in a separate thread, which allows them to be synchronized with activities in other threads. This allows them to block without danger of entering a self-deadlock due to the handler having been involved in a context which already held resources. The effect of calling the EXIT command on the calling thread is the same as calling pthread_exit( ): the callers stack is unwound and the thread is terminated. This allows each frame on the stack to have an opportunity to be notied and to take action during the termination, so that it can then release any resource which it holds that might be required for an exit handler. By using upcalls, you have a way out of self-deadlock problems that can impede image rundown. You can optionally perform a rundown by using the control y EXIT (Ctrl Y/EXIT) command. By doing this and with upcalls enabled, you release the exit handler thread. All other threads continue to execute untouched. This removes the possibility of the self-deadlock problem which is common when you invoke exit handlers asynchronously in an existing context. However, by invoking exit handlers, you do not automatically initiate any kind of implicit shutdown of the threads in the process. Because of this, it is up to the application to request explicitly the shutdown of its threads from its exit handler and to ensure that their shutdown is complete before returning from the exit handler. By having the application do this, you ensure that subsequent exit handlers do not encounter adverse operating conditions, such as threads which access les after theyve been closed, or the inability to close les because they are being accessed by threads.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
Along with using control y EXIT (CtrlY/EXIT) to perform shutdowns, you can issue a control y (CtrlY/STOP) command. If you use a control y STOP (Ctrl Y/STOP) command, it is recommended that you do this with upcalls. To use a control y STOP (CtrlY/STOP) command, can cause a disorderly or unexpected outcome.
2.8.3.2.1 Process Structure With the implementation of OpenVMS kernel threads, all processes are a threaded process with at least one kernel thread. Every kernel thread gets stacks for each access mode. Quotas and limits are maintained and enforced at the process level. The process virtual address space remains per process and is shared by all threads. The scheduling entity moves from the process to the kernel thread. In general, ASTs are delivered directly to the kernel threads. Event ags and locks remain per process. See Section 2.8.4 for more information. 2.8.3.2.2 Access to Inner Modes With the implementation of kernel threads, a single threaded process continues to function exactly as it has in the past. A multithreaded process may have multiple threads executing in user mode or in user mode ASTs, as is also possible for supervisor mode. Except in cases where an activity in inner mode is considered thread safe, a multithreaded process may have only a single thread executing in an inner mode at any one time. Multithreaded processes retain the normal preemption of inner mode by more inner mode ASTs. A special inner mode semaphore serializes access to inner mode.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
2.8.3.2.3 Scheduling With the implementation of kernel threads, the OpenVMS scheduler concerns itself with kernel threads, and not processes. At certain points in the OpenVMS executive at which the scheduler could wait a kernel thread, it can instead transfer control to the thread manager. This transfer of control, known as a callback or upcall, allows the thread manager the chance to reschedule stalled application threads. 2.8.3.2.4 ASTs With the implementation of kernel threads, ASTs are not delivered to the process. They are delivered to the kernel thread on which the event was initiated. Inner mode ASTs are generally delivered to the kernel thread already in inner mode. If no thread is in inner mode, the AST is delivered to the kernel thread that initiated the event. 2.8.3.2.5 Event Flags With the implementation of kernel threads, event ags continue to function on a per-process basis, maintaining compatibility with existing application behavior. 2.8.3.2.6 Process Control Services With the implementation of kernel threads, many process control services continue to function at the process level. SYS$SUSPEND and SYS$RESUME system services, for example, continue to change the scheduling state of the entire process, including all of its threads. Other services such as SYS$HIBER and SYS$SCHDWK act on individual kernel threads instead of the entire process.
2.8.4.1 Process Control Block (PCB) and Process Header (PHD) Two primary data structures exist in the OpenVMS executive that describe the context of a process: Software process control block (PCB) Process header (PHD)
The PCB contains elds that identify the process to the system. The PCB comprises contexts that pertain to quotas and limits, scheduling state, privileges, AST queues, and identiers. In general, any information that is required to be resident at all times is in the PCB. Therefore, the PCB is allocated from nonpaged pool.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
The PHD contains elds that pertain to a processs virtual address space. The PHD contains the process section table. The PHD also contains the hardware process control block (HWPCB) and a oating-point register save area. The HWPCB contains the hardware execution context of the process. The PHD is allocated as part of a balance set slot. 2.8.4.1.1 Effect of a Multithreaded Process on the PCB and PHD With multiple execution contexts within the same process, the multiple threads of execution all share the same address space, but have some independent software and hardware context. This change to a multithreaded process results in an impact on the PCB and PHD structures, and on any code that references them. Before the implementation of kernel threads, the PCB contained much context that was per-process. Now, with the introduction of multiple threads of execution, much context becomes per-thread. To accommodate per-thread context, a new data structure, the kernel thread block (KTB), is created, with the per-thread context removed from the PCB. However, the PCB continues to contain context common to all threads, such as quotas and limits. The new per-kernel thread structure contains the scheduling state, priority, and the AST queues. The PHD contains the HWPCB that gives a process its single execution context. The HWPCB remains in the PHD; this HWPCB is used by a process when it is rst created. This execution context is also called the initial thread. A single threaded process has only this one execution context. A new structure, the oating-point registers and execution data block (FRED), is created to contain the hardware context of the newly created kernel threads. Since all threads in a process share the same address space, the PHD and page tables continue to describe the entire virtual memory layout of the process. 2.8.4.2 Kernel Thread Block (KTB) The kernel thread block (KTB) is a new per-kernel-thread data structure. The KTB contains all per-thread software context moved from the PCB. The KTB is the basic unit of scheduling, a role previously performed by the PCB, and is the data structure placed in the scheduling state queues. Typically, the number of KTBs a multithreaded process has is the same as the number of CPUs on the system. Actually, the number of KTBs is limited by the value of the system parameter MULTITHREAD. If MULTITHREAD is zero, the OpenVMS kernel support is disabled. With kernel threads disabled, userlevel threading is still possible with POSIX Threads Library. The environment is identical to the OpenVMS environment prior to the OpenVMS Version 7.0 release. If MULTITHREAD is nonzero, it represents the maximum number of execution contexts or kernel threads that a process can own, including the initial one. The KTB, in reality, is not an independent structure from the PCB. Both the PCB and KTB are dened as sparse structures. The elds of the PCB that move to the KTB retain their original PCB offsets in the KTB. In the PCB, these elds are unused. In effect, if the two structures are overlaid, the result is the PCB as it currently exists with new elds appended at the end. The PCB and KTB for the initial thread occupy the same block of nonpaged pool; therefore, the KTB address for the initial thread is the same as for the PCB.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
2.8.4.3 Floating-Point Registers and Execution Data Blocks (FREDs) To allow for multiple execution contexts, not only are additional KTBs required to maintain the software context, but additional HWPCBs must be created to maintain the hardware context. Each HWPCB has allocated with it space for preserving the contents of the oating-point registers across context switches. Additional bytes are allocated for per-kernel thread data. The combined structure that contains the HWPCB, oating-point register save area, and the per-kernel thread data is called the oating-point registers and execution data (FRED) block. Prior to Version 7.2, OpenVMS supported 16 kernel threads per process. As of Version 7.2, OpenVMS supports 256 kernel threads per process. Also, prior to Version 7.3-1, OpenVMS allocated the maximum number of FRED blocks for a given process when that process was created, even if the process did not become multithreaded. With Version 7.3-1 and higher, OpenVMS allocated all FRED blocks as needed. 2.8.4.4 Kernel Threads Region Much process context resides in P1 space, taking the form of data cells and the process stacks. Some of these data cells need to be per kernel thread, as do the stacks. During initialization of the multithread environment, a kernel thread region in P1 space is initialized to contain the per-kernel-thread data cells and stacks. The region begins at the boundary between P0 and P1 space at address 40000000x, and it grows toward higher addresses and the initial threads user stack. The region is divided into per-kernel-thread areas. Each area contains pages for data cells and the access mode stacks. 2.8.4.5 Per-Kernel Thread Stacks A process is created with separate stacks in P1 space for the four access modes. On Alpha systems, each access mode has a memory stack. A memory stack is used for storing data local to a procedure, saving register contents temporarily, and recording nested procedure call information. On I64 systems, memory stacks are used for storing data local to a procedure and for saving register contents temporarily, but not for recording nested procedure call information. To reduce procedure call overhead, the Intel Itanium architecture provides a large number of registers. Some, the so-called static registers, are shared by a caller and the procedure it calls; others, the dynamic or stacked registers, are not shared. When a procedure is called, it allocates as many dynamic general registers as it needs. On I64 systems, nested procedure call information is recorded in the dynamic registers. The I64 systems manage the dynamic registers like a stack, keeping track of each procedures allocation. Each procedure could, in fact, allocate all the dynamic registers for its own use. Whenever the dynamic register use by nested procedures cannot be accommodated by physical registers, the hardware saves the dynamic registers in an in-memory area established by OpenVMS called the register backing store or register stack. On I64 systems, OpenVMS creates a register stack whenever it creates a memory stack. Unlike memory stacks, register stacks grow from low addresses to high addresses. Stack sizes are either xed, determined by a SYSGEN parameter, or expandable. The parameter KSTACKPAGES controls the size of the kernel stack. Supervisor and executive mode stack sizes are xed.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
For the user stack, a more complex situation exists. OpenVMS allocates P1 space from high to lower addresses. The user stack is placed after the lowest P1 space address allocated. This allows the user stack to expand on demand toward P0 space. With the introduction of multiple sets of stacks, the locations of these stacks impose a limit on the size of each area in which they can reside. With the implementation of kernel threads, the user stack is no longer boundless. The initial user stack remains semi-boundless; it still grows toward P0 space, but the limit is the per-kernel thread region instead of P0 space. The default user stack in a process can expand on demand to be quite large, so single threaded applications do not typically run out of user stack. When an application is written using POSIX Threads Library, however, each POSIX thread gets its own user stack, which is a xed size. POSIX thread stacks are allocated from the P0 heap. Large stacks might cause the process to exceed its memory quotas. In an extreme case, the P0 region could ll completely, in which case the process might need to reduce the number of threads in use concurrently or make other changes to lessen the demand for P0 memory. If the application developer underestimates the stack requirements, the application may fail due to a thread overowing its stack. This failure is typically reported as an access violation and is very difcult to diagnose. To address this problem, yellow stack zones were introduced in OpenVMS Version 7.2 and are available to applications using POSIX Threads Library. Yellow stack zones are a mechanism by which the stack overow can be signaled back to the application. The application can then choose either to provide a stack overow handler or do nothing. If the application does nothing, this mechanism helps pinpoint the failure for the application developer. Instead of an access violation being signaled, a stack overow error is signaled. 2.8.4.6 Per-Kernel-Thread Data Cells Several pages in P1 space contain process state in the form of data cells. A number of these cells must have a per-kernel-thread equivalent. These data cells do not all reside on pages with the same protection. Because of this, the perkernel-thread area reserves two pages for these cells. Each page has a different page protection; one page protection is user read, user write (URUW); the other is user read, executive write (UREW). 2.8.4.7 Summary of Process Data Structures Process creation results in a PCB/KTB, a PHD/FRED, and a set of stacks. All processes have a single kernel thread, the initial thread. A multithreaded process always begins as a single threaded process. A multithreaded process contains a PCB/KTB pair and a PHD/FRED pair for the initial thread; for its other threads, it contains additional KTBs, additional FREDs, and additional sets of stacks. When the multithreaded application exits, the process returns to its single threaded state, and all additional KTBs, FREDs, and stacks are deleted. 2.8.4.8 Kernel Thread Priorities The SYS$SETPRI system service and the SET PROCESS/PRIORITY DCL command both take a process identication value (PID) as an input and therefore affect only a single kernel thread at a time. If you want to change the base priorities of all kernel threads in a process, you must either make a separate call to SYS$SETPRI or invoke the SET PROCESS/PRIORITY command for each thread.
Process Creation 2.8 Kernel Threads and the Kernel Threads Process Structure (Alpha and I64 Only)
In addition, a value for the policy parameter to the SYS$SETPRI system service was added. If JPI$K_ALL_THREADS is specied, the call to SYS$SETPRI changes the base priorities of all kernel threads in the target process. The same support is provided by the ALL_THREADS qualier to the SET PROCESS/PRIORITY DCL command.
3
Process Communication
This chapter describes communication mechanisms used within a process and between processes. It also describes programming with intra-cluster communication (ICC). It contains the following sections: Section 3.1 describes communication within a process. Section 3.2 describes communication between processes. Section 3.3 describes intra-cluster communication. The operating system allows your process to communicate within itself and with other processes. Processes can be either wholly independent or cooperative. This chapter presents considerations for developing applications that require the concurrent execution of many programs, and how you can use process communication to perform the following functions: Synchronize events Share data Obtain information about events important to the program you are executing
For passing information among chained images, you can use all four methods because the image reading the information executes immediately after the image that deposited it. Only the common area allows you to pass data reliably from one image to another in the event that another images execution intervenes the two communicating images. For communicating within a single image, you can use event ags, logical names, and symbols. For synchronizing events within a single image, use event ags. See Chapter 6 for more information about synchronizing events. Because permanent mailboxes and permanent global sections are not deleted when the creating image exits, they also can be used to pass information from the current image to a later executing image. However, HP recommends that you use the common area because it uses fewer system resources than the permanent structures and does not require privilege. (You need the PRMMBX privilege to
Process Communication 31
32 Process Communication
Process Communication 33
34 Process Communication
3.1.3.2 Creating and Using Global Symbols If you need to pass information from one program to another within a process, you can assign data to a global symbol when you create the symbol. Then, other programs can access the contents of the global symbol. You should use global symbols so the value within the symbol can be accessed by other programs. To use DCL global symbols, follow this procedure: 1. Create the symbol and assign data to it using the routine LIB$SET_SYMBOL. Make sure you specify that the symbol will be placed in the global symbol table in the tbl-ind argument. If you do not specify the global symbol table, the symbol will be a local symbol. 2. Access the symbol with the LIB$GET_SYMBOL routine. This routine uses DCL to return the value of the symbol as a string. 3. Once you have nished using the symbol, delete it with the LIB$DELETE_ SYMBOL routine. If you created a global symbol, make sure you specify the global symbol table in the tbl-ind argument. By default, the system searches the local symbol table.
Process Communication 35
36 Process Communication
Each approach offers different possibilities in terms of the speed at which it communicates information and the amount of information it can communicate. For example, shared les offer the possibility of sharing an unlimited amount of information; however, this approach is the slowest because the disk must be accessed to share information. Like shared les, global sections offer the possibility of sharing large amounts of information. Because sharing information through global sections requires only memory access, it is the fastest communication method. Logical names and mailboxes can communicate moderate amounts of information. Because each method operates through a relatively complex system service, each is faster than les, but slower than the other communication methods. The lock management services and common event ag cluster methods can communicate relatively small amounts of information. With the exception of global sections, they are the fastest of the interprocess communication methods.
Process Communication 37
38 Process Communication
3.2.2 Mailboxes
A mailbox is a virtual device used for communication among processes. You must call OpenVMS RMS services, language I/O statements, or I/O system services to perform actual data transfers. 3.2.2.1 Creating a Mailbox To create a mailbox, use the SYS$CREMBX system service. SYS$CREMBX creates the mailbox and returns the number of the I/O channel assigned to the mailbox. The format for the SYS$CREMBX system service is as follows: SYS$CREMBX ([prmg] ,chan ,[maxmsg] ,[bufquo] ,[promsk] ,[acmode] ,[lognam] ,[ags] ,[nullarg]) When you invoke SYS$CREMBX, you usually specify the following two arguments: Specify a variable to receive the I/O channel number using the chan argument. This argument is required. Specify the logical name to be associated with the mailbox using the lognam argument. The logical name identies the mailbox for other processes and for input/output statements.
The SYS$CREMBX system service also allows you to specify the message size, buffer size, mailbox protection code, and access mode of the mailbox; however, the default values for these arguments are usually sufcient. For more information on SYS$CREMBX, refer to the HP OpenVMS System Services Reference Manual. 3.2.2.2 Creating Temporary and Permanent Mailboxes By default, a mailbox is deleted when no I/O channel is assigned to it. Such a mailbox is called a temporary mailbox. If you have PRMMBX privilege, you can create a permanent mailbox (specify the prmg argument as 1 when you invoke SYS$CREMBX). A permanent mailbox is not deleted until it is marked for deletion with the SYS$DELMBX system service (requires PRMMBX). Once a permanent mailbox is marked for deletion, it is like a temporary mailbox; when the last I/O channel to the mailbox is deassigned, the mailbox is deleted. The following statement creates a mailbox named MAIL_BOX. The I/O channel assigned to the mailbox is returned in MBX_CHAN. ! I/O channel INTEGER*2 MBX_CHAN ! Mailbox name CHARACTER*(*) MBX_NAME PARAMETER (MBX_NAME = MAIL_BOX) STATUS = SYS$CREMBX (, 2 MBX_CHAN, ! I/O channel 2 ,,,, 2 MBX_NAME) ! Mailbox name
Process Communication 39
The following program segment creates a permanent mailbox, then creates a subprocess that marks that mailbox for deletion: INTEGER STATUS, 2 SYS$CREMBX INTEGER*2 MBX_CHAN ! Create permanent mailbox STATUS = SYS$CREMBX (%VAL(1), ! Permanence flag 2 MBX_CHAN, ! Channel 2 ,,,, 2 MAIL_BOX) ! Logical name IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Create subprocess to delete it STATUS = LIB$SPAWN (RUN DELETE_MBX) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) END The following program segment executes in the subprocess. Notice that the subprocess must assign a channel to the mailbox and then use that channel to delete the mailbox. Any process that deletes a permanent mailbox, unless it is the creating process, must use this technique. (Use SYS$ASSIGN to assign the channel to the mailbox to ensure that the mailbox already exists. SYS$CREMBX system service assigns a channel to a mailbox; however, SYS$CREMBX also creates the mailbox if it does not already exist.) INTEGER STATUS, 2 SYS$DELMBX, 2 SYS$ASSIGN INTEGER*2 MBX_CHAN ! Assign channel to mailbox STATUS = SYS$ASSIGN (MAIL_BOX, 2 MBX_CHAN,,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Delete the mailbox STATUS = SYS$DELMBX (%VAL(MBX_CHAN)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) END 3.2.2.3 Assigning an I/O Channel Along with a Mailbox A mailbox is a virtual device used for communication between processes. A channel is the communication path that a process uses to perform I/O operations to a particular device. The LIB$ASN_WTH_MBX routine assigns a channel to a device and associates a mailbox with the device. Normally, a process calls the SYS$CREMBX system service to create a mailbox and assign a channel and logical name to it. In the case of a temporary mailbox, this service places the logical name corresponding to the mailbox in the job logical name table. This implies that any process running in the same job and using the same logical name uses the same mailbox.
The routine returns this device name to the calling program, which then must pass the mailbox channel to the other programs with which it cooperates. In this way, the cooperating processes access the mailbox by its physical name instead of by its jobwide logical name. The calling program passes the routine a device name, which species the device to which the channel is to be assigned. For this argument (called dev-nam), you can use a logical name. If you do so, the routine attempts one level of logical name translation. The privilege restrictions and process quotas required for using this routine are those required by the $GETDVI, $CREMBX, and $ASSIGN system services. 3.2.2.4 Reading and Writing Data to a Mailbox The following list describes the three ways you can read and write to a mailbox: Synchronous I/OReads or writes to a mailbox and then waits for the cooperating image to perform the other operation. Use I/O statements for your programming language. This is the recommended method of addressing a mailbox. Immediate I/OQueues a read or write operation to a mailbox and continues program execution after the operation completes. To do this, use the SYS$QIOW system service. Asynchronous I/OQueues a read or write operation to a mailbox and continues program execution while the request executes. To do this, use the SYS$QIO system service. When the read or write operation completes, the I/O status block (if specied) is lled, the event ag (if specied) is set, and the AST routine (if specied) is executed.
Chapter 23 describes the SYS$QIO and SYS$QIOW system services and provides further discussion of mailbox I/O. See the HP OpenVMS System Services Reference Manual for more information. HP recommends that you supply the optional I/O status block parameter when you use these two system services. The contents of the status block varies depending on the QIO function code; refer to
Intracluster system services provide the following benets when implementing ICC: An easy-to-use conventional system service interface for interprocess communications within a cluster An interface usable for communications between processes within a single, nonclustered node An interface callable from all modes and from execlets as well as from images An easy-to-use interface giving access to high-speed interconnects such as Memory Channel An interface independent of the installation of any networking product
The intracluster communication system services are as follows: Open Association: SYS$ICC_OPEN_ASSOC Close Association: SYS$ICC_CLOSE_ASSOC Connect: SYS$ICC_CONNECT and SYS$ICC_CONNECTTW Accept: SYS$ICC_ACCEPT Reject: SYS$ICC_REJECT Disconnect: SYS$ICC_DISCONNECT and SYS$ICC_DISCONNECTW Transmit Data: SYS$ICC_TRANSMIT and SYS$ICC_TRANSMITW Receive Data: SYS$ICC_RECEIVE and SYS$ICC_RECEIVEW Transceive Data: SYS$ICC_TRANSCEIVE and SYS$ICC_TRANSCEIVEW Reply: SYS$ICC_REPLY and SYS$ICC_REPLYW
See the HP OpenVMS System Services Reference Manual: GETUTCZ for additional information about the ICC system services.
No matter what the cause of the disconnection, the application should be prepared to deal with disconnection other than that as an expected part of the application communication protocol.
logical_name logical_table
disc_event_rtn
recv_rtn
maxowbufcnt
3.3.1.4.1 Connection Events Once the association is opened, connection requests are delivered as asynchronous calls to the servers connection routine. The connection routine (and disconnection routine, if supplied) are each called with seven arguments as described in the $ICC_OPEN_ASSOC system service, located in the HP OpenVMS System Services Reference Manual: GETUTCZ. A single connection or disconnection routine may distinguish between the events based on the rst argument (event_type), which will either be the code ICC$C_ EV_CONNECT or ICC$C_EV_DISCONNECT. A connection routine must either call SYS$ICC_ACCEPT to complete the connection or SYS$ICC_REJECT to reject the connection. The EPID and username of the requesting process are supplied by ICC. Any additional information required by the application for verication either must be supplied by the client via the connection data parameter or must be obtainable by the server itself (for example, via SYS$GETJPI.) Failure to ACCEPT or REJECT the connection will stall all additional attempts to connect to this server. 3.3.1.4.2 Disconnection Events A disconnection event signals that the partner application of the connection has requested a disconnect, the partner process has been deleted, or that the remote node has left the cluster. Upon receiving a disconnect event, the server should call SYS$ICC_DISCONNECT to clean up the server side of the connection. However, when the partner that received the disconnect event calls SYS$ICC_DISCONNECT, the connection has already been terminated and the link is already gone. The return status from this call to SYS$ICC_DISCONNECT should be SS$_NORMAL, but the completion status returned in the IOSB is SS$_LINKDISCON. Failure to call DISCONNECT may leave resources allocated to the connection that are not released until the image terminates. In the case of inner mode associations, resources will be released at process termination.
conn_handle remote_assoc
remote_node
ags
When the CONNECT call completes, the connection is established and useable only if success status was returned as both the return value of the service and in the status elds (ios_icc$w_status and ios_icc$l_remstat) of the IOS_ICC.
4
Process Control
This chapter describes how to use operating system features to control a process or kernel thread. It contains the following sections: Section 4.1 describes the control of a process or kernel thread to complete a programming task. Section 4.2 describes how to use the operating systems process information services to gather information about a process or kernel thread. Section 4.3 describes how to change a processs scheduling. Section 4.4 describes the afnity and capability mechanisms for CPU scheduling. Section 4.5 describes the class scheduler and how to use it on VAX, Alpha, and I64 systems. Section 4.6 describes how to change a processs name. Section 4.7 describes how to access another processs context. Section 4.8 describes how to synchronize programs by setting specic times for program execution. Section 4.9 describes how to suspend, resume, and stop program execution.
Process Control 41
You can use system routines and DCL commands to accomplish these tasks. Table 41 summarizes which routines and commands to use. You can use the DCL commands in a command procedure that is executed as soon as the subprocess (or detached process) is created. For process synchronization techniques other than specifying a time for program execution, refer to Chapters 6, 7, and 8. Table 41 Routines and Commands for Controlling Processes and Kernel Threads
Routine LIB$GETJPI SYS$GETJPI SYS$GETJPIW DCL Command SHOW PROCESS Task Return process or kernel thread information. SYS$GETJPI(W) can request process and thread information from a specic PID or PRCNAM. If no specic thread is identied, then the data represents the initial thread. Set process privileges. Set process or kernel thread priority. This service affects the base and current priority of a specied kernel thread and not the entire process. Control swapping of process. Hibernate, suspend, and resume a process or kernel threads. These services hibernate, suspend, or resume all kernel threads associated with the specied process. Set process name. Initiate process and image rundown. All associated kernel threads of a specied process are run down and deleted. Delete process. (continued on next page)
SYS$SETPRV SYS$SETPRI
42 Process Control
SYS$ADJSTK
SET PROCESS
SYS$PROCESS_SCAN
SHOW PROCESS
SYS$SETSTK
None available
By default, the routines and commands reference the current process or kernel thread. To reference another process, you must specify either the process identication (PID) number or the process name when you call the routine or a command qualier when you enter commands. You must have the GROUP privilege to reference a process with the same group number and a different member number in its UIC, and WORLD privilege to reference a process with a different group number in its UIC. The information presented in this section covers using the routines. If you want to use the DCL commands in a command procedure, refer to the HP OpenVMS DCL Dictionary.
You need additional privileges to perform some specic functions; for example, raising the base priority of a process requires ALTPRI privilege.
Process Control 43
The service returns the process identication in the longword at ORIONID. You can now use either the process name (ORION) or the PID (ORIONID) to refer to this process in other system service calls. A process can set or change its own name with the Set Process Name ($SETPRN) system service. For example, a process can set its name to CYGNUS, as follows: /* Descriptor for process name */ $DESCRIPTOR(cygnus,"CYGNUS"); status = SYS$SETPRN( &cygnus ); /* prcnam - process name */ Most of the process control services accept the prcnam or the pidadr argument or both. However, you should identify a process by its process identication number for the following reasons: The service executes faster because it does not have to search a table of process names. For a process not in your group, you must use the process identication number (see Section 4.1.3).
If you specify the PID address, the service uses the PID address. If you specify the process name without a PID address, the sevice uses the process name. If you specify boththe process name and PID addressit uses the PID address unless the contents of the PID is 0. In that case, the service uses the process name. If you specify a PID address of 0 without a process name, then the service is performed for the calling process.
44 Process Control
No
Yes
No Yes
Yes No
PID
Yes
Yes
Yes
Yes
PID
Process Control 45
The SYS$GETJPI(W) and SYS$PROCESS_SCAN system services can also be used to get kernel threads information. SYS$GETJPI(W) can request threads information from a particular process ID or process name. SYS$PROCESS_SCAN can request information about all threads in a process, or all threads for each multithreaded process on the system. For more information about SYS$GETJPI, SYS$PROCESS_SCAN, and SYS$GETLKI, see the HP OpenVMS System Services Reference Manual. The differences among these procedures are as follows: SYS$GETJPI operates asynchronously. SYS$GETJPIW and LIB$GETJPI operate synchronously. SYS$GETJPI and SYS$GETJPIW can obtain one or more pieces of information about a process or kernel thread in a single call. LIB$GETJPI can obtain only one piece of information about a process or kernel thread in a single call. SYS$GETJPI and SYS$GETJPIW can specify an AST to execute at the completion of the routine. SYS$GETJPI and SYS$GETJPIW can use an I/O status block (IOSB) to test for completion of the routine. LIB$GETJPI can return some items either as strings or as numbers. It is often the easiest to call from a high-level language because the caller is not required to construct an item list. SYS$GETLKI returns information about the lock database.
46 Process Control
Note that a local process name can look like a remote process name. Therefore, if you specify ATHENS::SMITH, the system checks for a process named ATHENS::SMITH on the local node before checking node ATHENS for a process named SMITH. Chapter 17 and the HP OpenVMS System Services Reference Manual describe these routines completely, listing all items of information that you can request. LIB$GETJPI, SYS$GETJPI, and SYS$GETJPIW share the same item codes with the following exception: LIB$K_ items can be accessed only by LIB$GETJPI. In the following example, the string argument rather than the numeric argument is specied, causing LIB$GETJPI to return the UIC of the current process as a string: ! Define request codes INCLUDE ($JPIDEF) ! Variables for LIB$GETJPI CHARACTER*9 UIC INTEGER LEN STATUS = LIB$GETJPI (JPI$_UIC, 2 ,,, 2 UIC, 2 LEN) To specify a list of items for SYS$GETJPI or SYS$GETJPI(W) (even if that list contains only one item), use a record structure. Example 41 uses SYS$GETJPI(W) to request the process name and user name associated with the process whose process identication number is in SUBPROCESS_PID. Example 41 Obtaining Different Types of Process Information . . . ! PID of subprocess INTEGER SUBPROCESS_PID ! Include the request codes INCLUDE ($JPIDEF)
(continued on next page)
Process Control 47
48 Process Control
Example 42 Using SYS$GETJPI to Obtain Calling Process Information ! No process name or PID is specified; $GETJPI returns data on the ! calling process. PROGRAM CALLING_PROCESS IMPLICIT NONE INCLUDE ($jpidef) INCLUDE ($ssdef) /nolist /nolist ! Implicit none ! Definitions for $GETJPI ! System status codes ! Structure declaration for ! $GETJPI item lists
STRUCTURE /JPIITMLST/ UNION MAP INTEGER*2 BUFLEN, 2 CODE INTEGER*4 BUFADR, 2 RETLENADR
Process Control 49
! Declare the item list for ! $GETJPI ! System service entry points ! Status variable ! PID from $GETJPI ! I/O Status Block for $GETJPI
CHARACTER*16 2 PRCNAM ! Process name from $GETJPI INTEGER*2 PRCNAM_LEN ! Process name length ! Initialize $GETJPI item list JPILIST(1).BUFLEN = 4 JPILIST(1).CODE = JPI$_PID JPILIST(1).BUFADR = %LOC(PID) JPILIST(1).RETLENADR = 0 JPILIST(2).BUFLEN = LEN(PRCNAM) JPILIST(2).CODE = JPI$_PRCNAM JPILIST(2).BUFADR = %LOC(PRCNAM) JPILIST(2).RETLENADR = %LOC(PRCNAM_LEN) JPILIST(3).END_LIST = 0 ! Call $GETJPI to get data for this process STATUS = SYS$GETJPIW ( 2 , ! No event flag 2 , ! No PID 2 , ! No process name 2 JPILIST, ! Item list 2 IOSB, ! Always use IOSB with $GETJPI! 2 , ! No AST 2 ) ! No AST arg ! Check the status in both STATUS and the IOSB, if ! STATUS is OK then copy IOSB(1) to STATUS IF (STATUS) STATUS = IOSB(1) ! If $GETJPI worked, display the process, if done then ! prepare to exit, otherwise signal an error IF (STATUS) THEN TYPE 1010, PID, PRCNAM(1:PRCNAM_LEN) FORMAT ( ,Z8.8, ,A) ELSE CALL LIB$SIGNAL(%VAL(STATUS)) END IF END
1010
4.2.3.2 Requesting Information About All Processes on the Local System You can use SYS$GETJPI to perform a wildcard search on all processes on the local system. When the initial pidadr argument is specied as 01, SYS$GETJPI returns requested information for each process that the program has privilege to access. The requested information is returned for one process per call to SYS$GETJPI. To perform a wildcard search, call SYS$GETJPI in a loop, testing the return status.
Example 45 is a C program that demonstrates how to use the SYS$GETJPI wildcard to search for all processes on the local system.
01
Example 45 Using SYS$GETJPI to Request Information About All Processes on the Local System #include #include #include #include <stdio.h> <jpidef.h> <stdlib.h> <ssdef.h>
/* Item descriptor */ struct { unsigned short buflen, item_code; void *bufaddr; void *retlenaddr; unsigned int terminator; }itm_lst; /* I/O Status Block */ struct { unsigned short iostat; unsigned short iolen; unsigned int device_info; }iosb; main() { unsigned short len; unsigned int efn=1,pidadr = -1,status, usersize; char username[12]; /* Initialize the item list */ itm_lst.buflen = 12; itm_lst.item_code = JPI$_USERNAME; itm_lst.bufaddr = username; itm_lst.retlenaddr = &usersize; itm_lst.terminator = 0; do{
(continued on next page)
This wildcard search is initiated by invoking SYS$GETJPI with a 01 specied for the PID, and is available only on the local node. With kernel threads, a search for all threads in a single process is available, both on the local node and on another node on the cluster. In a dual architecture or mixed-version cluster, one or more nodes in the cluster may not support kernel threads. To indicate this condition, a threads capability bit (CSB$M_CAP_THREADS) exists in the CSB$L_CAPABILITY cell in the cluster status block. If this bit is set for a node, it indicates that the node supports kernel threads. This information is passed around as part of the normal cluster management activity when a node is added to a cluster. If a SYS$GETJPI request that requires threads support needs to be passed to another node in the cluster, a check is made on whether the node supports kernel threads before the request is sent to that node. If the node supports kernel threads, the request is sent. If the node does not support kernel threads, the status SS$_INCOMPAT is returned to the caller, and the request is not sent to the other node. You can use SYS$PROCESS_SCAN only with SYS$GETJPI; you cannot use it alone. The process context generated by SYS$PROCESS_SCAN is used like the 01 wildcard except that it is initialized by calling the SYS$PROCESS_ SCAN service instead of by a simple assignment statement. However, the SYS$PROCESS_SCAN context is more powerful and more exible than the 01 wildcard. SYS$PROCESS_SCAN uses an item list to specify selection criteria to be used in a search for processes and produces a context longword that describes a selective search for SYS$GETJPI. Using SYS$GETJPI with SYS$PROCESS_SCAN to perform a selective search is a more efcient way to locate information because only information about the processes you have selected is returned. For example, you can specify a search for processes owned by one user name, and SYS$GETJPI returns only the processes that match the specied user name. You can specify a search for
PSCAN$_ MULTITHREAD
4.2.4.1 Using SYS$PROCESS_SCAN Item List and Item-Specic Flags SYS$PROCESS_SCAN uses an item list to specify the selection criteria for the SYS$GETJPI search. Each entry in the SYS$PROCESS_SCAN item list contains the following: The attribute of the process to be examined The value of the attribute or a pointer to the value Item-specic ags to control how to interpret the value
Item-specic ags enable you to control selection information. For example, you can use ags to select only those processes that have attribute values that correspond to the value in the item list, as shown in Table 45. Table 45 Item-Specic Flags
Item-Specic Flag PSCAN$M_OR PSCAN$M_EQL PSCAN$M_NEQ PSCAN$M_GEQ PSCAN$M_GTR PSCAN$M_LEQ Description Match this value or the next value Match value exactly (the default) Match if value is not equal Match if value is greater than or equal to Match if value is greater than Match if value is less than or equal to (continued on next page)
The PSCAN$M_OR ag is used to connect entries in an item list. For example, in a program that searches for processes owned by several specied users, you must specify each user name in a separate item list entry. The item list entries are connected with the PSCAN$M_OR ag as shown in the following Fortran example. This example connects all the processes on the local node that belong to SMITH, JONES, or JOHNSON. PSCANLIST(1).BUFLEN PSCANLIST(1).CODE PSCANLIST(1).BUFADR PSCANLIST(1).ITMFLAGS PSCANLIST(2).BUFLEN PSCANLIST(2).CODE PSCANLIST(2).BUFADR PSCANLIST(2).ITMFLAGS PSCANLIST(3).BUFLEN PSCANLIST(3).CODE PSCANLIST(3).BUFADR PSCANLIST(3).ITMFLAGS PSCANLIST(4).END_LIST = = = = = = = = = = = = = LEN(SMITH) PSCAN$_USERNAME %LOC(SMITH) PSCAN$M_OR LEN(JONES) PSCAN$_USERNAME %LOC(JONES) PSCAN$M_OR LEN(JOHNSON) PSCAN$_USERNAME %LOC(JOHNSON) 0 0
Use the PSCAN$M_WILDCARD ag to specify that a character string is to be treated as a wildcard. For example, to nd all process names that begin with the letter A and end with the string ER, use the string A*ER with the PSCAN$M_ WILDCARD ag. If you do not specify the PSCAN$M_WILDCARD ag, the search looks for the 4-character process name A*ER. The PSCAN$M_PREFIX_MATCH denes a wildcard search to match the initial characters of a string. For example, to nd all process names that start with the letters AB, use the string AB with the PSCAN$M_PREFIX_MATCH ag. If you do not specify the PSCAN$M_PREFIX_MATCH ag, the search looks for a process with the 2-character process name AB. 4.2.4.2 Requesting Information About Processes That Match One Criterion You can use SYS$GETJPI with SYS$PROCESS_SCAN to search for processes that match an item list with one criterion. For example, if you specify a search for processes owned by one user name, SYS$GETJPI returns only those processes that match the specied user name. Example 46 demonstrates how to perform a SYS$PROCESS_SCAN search on the local node to select all processes that are owned by user SMITH.
! Declare the item list for ! $PROCESS_SCAN ! Declare the item list for ! $GETJPI ! System service entry points ! Status variable ! Context from $PROCESS_SCAN ! PID from $GETJPI ! I/O Status Block for $GETJPI ! Process name from $GETJPI ! Process name length ! Done with data loop
! Check the status in both STATUS and the IOSB, if ! STATUS is OK then copy IOSB(1) to STATUS IF (STATUS) STATUS = IOSB(1) ! If $GETJPI worked, display the process, if done then ! prepare to exit, otherwise signal an error
(continued on next page)
1010
Example 48 Selecting Processes That Match Multiple Criteria !******************************************** !* Initialize item list for $PROCESS_SCAN * !******************************************** ! Look for BATCH jobs owned by users SMITH and JONES PSCANLIST(1).BUFLEN PSCANLIST(1).CODE PSCANLIST(1).BUFADR PSCANLIST(1).ITMFLAGS PSCANLIST(2).BUFLEN PSCANLIST(2).CODE PSCANLIST(2).BUFADR PSCANLIST(2).ITMFLAGS PSCANLIST(3).BUFLEN PSCANLIST(3).CODE PSCANLIST(3).BUFADR PSCANLIST(3).ITMFLAGS PSCANLIST(4).END_LIST = = = = = = = = = = = = = LEN(SMITH) PSCAN$_USERNAME %LOC(SMITH) PSCAN$M_OR LEN(JONES) PSCAN$_USERNAME %LOC(JONES) 0 0 PSCAN$_MODE JPI$K_BATCH 0 0
!******************************************** !* End of item list initialization * !******************************************** See the HP OpenVMS System Services Reference Manual for more information about SYS$PROCESS_SCAN item codes and ags.
4.2.5.1 Checking All Nodes on the Cluster for Processes The SYS$PROCESS_SCAN system service can scan the entire cluster for processes. For example, to scan the cluster for all processes owned by SMITH, use code like that in Example 49 to initialize the item list to nd all processes with a nonzero cluster system identier (CSID) and a user name of SMITH. Example 49 Searching the Cluster for Process Information !******************************************** !* Initialize item list for $PROCESS_SCAN * !******************************************** ! Search the cluster for jobs owned by SMITH PSCANLIST(1).BUFLEN PSCANLIST(1).CODE PSCANLIST(1).BUFADR PSCANLIST(1).ITMFLAGS PSCANLIST(2).BUFLEN PSCANLIST(2).CODE PSCANLIST(2).BUFADR PSCANLIST(2).ITMFLAGS PSCANLIST(3).END_LIST = = = = = = = = = 0 PSCAN$_NODE_CSID 0 PSCAN$M_NEQ LEN(SMITH) PSCAN$_USERNAME %LOC(SMITH) 0 0
!******************************************** !* End of item list initialization * !******************************************** 4.2.5.2 Checking Specic Nodes on the Cluster for Processes You can specify a list of nodes as well. Example 410 demonstrates how to design an item list to search for batch processes on node TIGNES, VALTHO, or 2ALPES.
!******************************************** !* End of item list initialization * !******************************************** 4.2.5.3 Conducting Multiple Simultaneous Searches with SYS$PROCESS_SCAN Only one asynchronous remote SYS$GETJPI request per SYS$PROCESS_SCAN context is permitted at a time. If you issue a second SYS$GETJPI request using a context before a previous remote request using the same context has completed, your process stalls in a resource wait until the previous remote SYS$GETJPI request completes. This stall in the RWAST state prevents your process from executing in user mode or receiving user-mode ASTs. If you want to run remote searches in parallel, create multiple contexts by calling SYS$PROCESS_SCAN once for each context. For example, you can design a program that calls SYS$GETSYI in a loop to nd the nodes in the VMScluster system and creates a separate SYS$PROCESS_SCAN context for each remote node. Each of these separate contexts can run in parallel. The DCL command SHOW USERS uses this technique to obtain user information more quickly. Only requests to remote nodes must wait until the previous search using the same context has completed. If the SYS$PROCESS_SCAN context species the local node, any number of SYS$GETJPI requests using that context can be executed in parallel (within the limits implied by the process quotas for ASTLM and BYTLM). Note When you use SYS$GETJPI to reference remote processes, you must properly synchronize all SYS$GETJPI calls. Before the operating systems Version 5.2, if you did not follow these synchronization rules, your programs might have appeared to run correctly. However, if you attempt to run such improperly synchronized programs using SYS$GETJPI
To perform a synchronous search in which the program waits until all requested information is available, use SYS$GETJPIW with an iosb argument. See the HP OpenVMS System Services Reference Manual for more information about process identication, SYS$GETJPI, and SYS$PROCESS_SCAN.
!******************************************** !* End of item list initialization * !******************************************** 4.2.6.3 Fullling Remote SYS$GETJPI Quota Requirements A remote SYS$GETJPI request uses system dynamic memory for messages. System dynamic memory uses the process quota BYTLM. Follow these steps to determine the number of bytes required by a SYS$GETJPI request: 1. Add the following together: The size of the SYS$PROCESS_SCAN item list The total size of all reference buffers for SYS$PROCESS_SCAN (the sum of all buffer length elds in the item list) The size of the SYS$GETJPI item list The size of the SYS$GETJPI buffer The size of the calling process RIGHTSLIST Approximately 300 bytes for message overhead
Process Control 425
You must examine the return length of an item to verify that the item was retrieved. The information may be located in a different data structure in another release of the operating system.
You must examine the return length of an item to verify that the item was retrieved. The information may be located in a different data structure in another release of the operating system. The use of the ag JPI$M_NO_TARGET_AST also implies that SYS$GETJPI does not swap in a process, because SYS$GETJPI would only bring a process into memory to deliver an AST to that process. JPI$M_IGNORE_TARGET_STATUS When you specify JPI$M_IGNORE_TARGET_STATUS, SYS$GETJPI attempts to retrieve as much information as possible, even if the process is suspended or being deleted. Use JPI$M_IGNORE_TARGET_STATUS to retrieve all possible information from a process. For example, use this ag with SHOW SYSTEM to display processes that are suspended, being deleted, or in miscellaneous wait states. Example 412 demonstrates how to use SYS$GETJPI control ags to avoid swapping processes during a SYS$GETJPI call. Example 412 Using SYS$GETJPI Control Flags to Avoid Swapping a Process into the Balance Set PROGRAM CONTROL_FLAGS IMPLICIT NONE INCLUDE ($jpidef) /nolist INCLUDE ($pscandef) /nolist INCLUDE ($ssdef) /nolist ! Implicit none ! Definitions for $GETJPI ! Definitions for $PROCESS_SCAN ! Definitions for SS$_ names
(continued on next page)
! Declare the item list for ! $PROCESS_SCAN ! Declare the item list for ! $GETJPI ! System service entry points ! ! ! ! Status variable Context from $PROCESS_SCAN PID from $GETJPI Flags for $GETJPI
INTEGER*2 IOSB(4) CHARACTER*16 2 PRCNAM, 2 NODENAME INTEGER*2 PRCNAM_LEN, 2 NODENAME_LEN CHARACTER*80 2 IMAGNAME INTEGER*2 IMAGNAME_LEN LOGICAL*4 DONE
! I/O Status Block for $GETJPI ! ! ! ! Process name from $GETJPI Node name from $GETJPI Process name length Node name length
! Image name from $GETJPI ! Image name length ! Done with data loop
!******************************************** !* End of item list initialization * !******************************************** STATUS = SYS$PROCESS_SCAN ( ! Set up the scan context 2 CONTEXT, 2 PSCANLIST) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Initialize $GETJPI item list JPILIST(1).BUFLEN = JPILIST(1).CODE = JPILIST(1).BUFADR = JPILIST(1).RETLENADR = JPILIST(2).BUFLEN = JPILIST(2).CODE = JPILIST(2).BUFADR = JPILIST(2).RETLENADR = JPILIST(3).BUFLEN = JPILIST(3).CODE = JPILIST(3).BUFADR = JPILIST(3).RETLENADR = JPILIST(4).BUFLEN = JPILIST(4).CODE = JPILIST(4).BUFADR = JPILIST(4).RETLENADR = JPILIST(5).BUFLEN = JPILIST(5).CODE = JPILIST(5).BUFADR = JPILIST(5).RETLENADR = JPILIST(6).END_LIST = ! Loop calling $GETJPI 4 IAND (FFFFX, JPI$_GETJPI_CONTROL_FLAGS) %LOC(JPIFLAGS) 0 4 JPI$_PID %LOC(PID) 0 LEN(PRCNAM) JPI$_PRCNAM %LOC(PRCNAM) %LOC(PRCNAM_LEN) LEN(IMAGNAME) JPI$_IMAGNAME %LOC(IMAGNAME) %LOC(IMAGNAME_LEN) LEN(NODENAME) JPI$_NODENAME %LOC(NODENAME) %LOC(NODENAME_LEN) 0 with the context
END DO 1010 1020 FORMAT ( ,Z8.8, ,A6,:: ,A, (no image)) FORMAT ( ,Z8.8, ,A6,:: ,A, ,A) END
#include #include
while (status == ss$_normal) { status = sys$getlkiw( 1, &lock_context, getlki_item_list,0,0,0,0); /* */ /* Dequeue the lock if the value block contains a 1 */ /* */ if ((status == ss$_normal) & (value_block[0] == 1)){ status = sys$deq( lock_id, 0, 0, 0 ); } } if (status != ss$_nomorelock){ exit(status); } }
4.4 Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only)
On Alpha and I64 systems, the afnity and capabilities mechanisms allow CPU scheduling to be adapted to larger CPU congurations by controlling the distribution of processes or threads throughout the active CPU set. Control of the distribution of processes throughout the active CPU set becomes more important as higher-performance server applications, such as databases and real-time process-control environments, are implemented. Afnity and capabilities provide the user with opportunities to perform the following tasks:
Process Control 4.4 Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only)
Create and modify a set of user-dened process capabilities Create and modify a set of user-dened CPU capabilities to match those in the process Allow a process to apply the afnity mechanisms to a subset of the active CPU set in a symmetric multiprocessing (SMP) conguration
Run
Quorum
Vector
Process Control 4.4 Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only) 4.4.3 Looking at User Capabilities
Previously, the use of capabilities was restricted to system resources and control events. However, it is also valuable for user functions to be able to indicate a resource or special CPU function. There are 16 user-dened capabilities added to both the process and the CPU structures. Unlike the static denitions of the current system capabilities, the user capabilities have meaning only in the context of the processes that dene them. Through system service interfaces, processes or individual threads of a multithreaded process, can set specic bits in the capability masks of a CPU to give it a resource, and can set specic bits in the kernel threads capability mask to require that resource as an execution criterion. The user capability feature is a direct superset of the current capability functionality. All currently existing capabilities are placed into the system capability set; they are not available to the process through system service interfaces. These system service interfaces affect only the 16 bits specically set aside for user denition. The OpenVMS operating system has no direct knowledge of what the dened capability is that is being used. All responsibility for the correct denition, use, and management of these bits is determined by the processes that dene them. The system controls the impact of these capabilities through privilege requirements; but, as with the priority adjustment services, abusive use of the capability bits could affect the scheduling dynamic and CPU loads in an SMP environment.
Process Control 4.4 Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only)
Both services allow multiple bits to be set or cleared, or both, simultaneously. Each takes as parameters a select mask and a modify mask that dene the operation set to be performed. The service callers are responsible for setting up the select mask to indicate the user capabilities bits affected by the current call. This select mask is a bit vector of the ORed bit symbolic names that, when set, states that the value in the modify mask is the new value of the bit. Both masks use the symbolic constants to indicate the same bit; alternatively, if appropriate, you can use the symbolic constant CAP$K_USER_ALL in the select mask to indicate that the entire set of capabilities is affected. Likewise, you can use the symbolic constant CAP$K_USER_ADD or CAP$K_USER_REMOVE in the modify mask to indicate that all capabilities specied in the select mask are to be either set or cleared. For information about using the SYS$CPU_CAPABILITIES and SYS$PROCESS_ CAPABILITIES system services, see the HP OpenVMS System Services Reference Manual: AGETUAI and HP OpenVMS System Services Reference Manual: GETUTCZ.
Process Control 4.4 Using Afnity and Capabilities in CPU Scheduling (Alpha and I64 Only)
4.4.5.2 Explicit Afnity Even though capabilities and afnity overlap considerably in their functional behavior, they are nonetheless two discrete scheduling mechanisms. Afnity, the subsetting of the number of CPUs on which a process can execute, has precedence over the capability feature and provides an explicit binding operation between the process and CPU. It forces the scheduling algorithm to consider only the CPU set it requires, and then applies the capability tests to see whether any of them are appropriate. Explicit afnity allows database and high-performance applications to segregate application functions to individual CPUs, providing improved cache and TB performance as well as reducing context switching and general scheduling overhead. During the IPL 8 scheduling pass, the process is investigated to see to which CPUs it is bound and whether the current CPU is one of those. If it passes that test, capabilities are also validated to allow the process to context switch. The number of CPUs that can be supported is 32. The SYS$PROCESS_AFFINITY system service provides access to the explicit afnity functionality. SYS$PROCESS_AFFINITY resolves to a specic process, defaulting to the current one, through the pidadr and prcnam arguments. Like the other system services, the CPUs that are affected are indicated through select_mask, and the binding state of each CPU is specied in modify_mask. Specic CPUs can be referenced in select_mask and modify_mask using the symbolic constants CAP$M_CPU0 through CAP$M_CPU31. These constants are dened to match the bit position of their associated CPU ID. Alternatively, specifying CAP$K_ALL_ACTIVE_CPUS in select_mask sets or clears explicit afnity for all CPUs in the current active set. Explicit afnity, like capabilities, has a permanent process as well as current image copy. As each completed image is run down, the permanent explicit afnity values overwrite the running image set, superseding any changes that were made in the interim. Specifying CAP$M_FLAG_PERMANENT in the ags parameter indicates that both the current and permanent processes are to be modied simultaneously. As a result, unless explicitly changed again, this operation has a scope from the current image through the end of the process life. For information about the SYS$SET_IMPLICIT_AFFINITY and SYS$PROCESS_ AFFINITY system services, see the HP OpenVMS System Services Reference Manual: AGETUAI and HP OpenVMS System Services Reference Manual: GETUTCZ.
4.5.1.2 The Delete Subcommand The format for the Delete subcommand is as follows: SYSMAN>class_schedule delete "class name" The Delete subcommand deletes the scheduling class from the class scheduler database le, and all processes that are members of this scheduling class are no longer class scheduled. 4.5.1.3 The Modify Subcommand The format for the Modify subcommand is as follows: SYSMAN>class_schedule modify "class name" /cpulimit = ([primary], [h1-h2=time%],[h1=time%], [,...],[secondary],[h1-h2=time%],[h1=time%],[,...]) [/primedays = ([no]day[,...])] [/username = (name1, name2,...name"n")] [/account = (name1, name2,...name"n")] [/uic = (uic1,uic2,...uic"n")] [/(no)windfall]
Note By default, a limited display of data is shown by this subcommand. The default shows the following: Name Maximum CPU times for reach range of hours Primary days and secondary days Windfall settings
4.5.1.5 The Suspend Subcommand The format for the Suspend subcommand is as follows: SYSMAN>class_schedule suspend "class name" The Suspend subcommand suspends the specied 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 Subcommand The format of the Resume subcommand is as follows: SYSMAN>class_schedule resume "class name" The Resume subcommand complements the suspend command. You use this command to resume a scheduling class that is currently suspended.
Process Control 4.5 Using the Class Scheduler in CPU Scheduling 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 le as an RMS indexed le when the rst 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 le, and the Loginout image already has the process information from this le, 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 classs criteria. That is, its user and account name and/or UIC may not be part of the classs 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.
The SHOW SYSTEM DCL Command The DCL command, SHOW SYSTEM, with the qualier, /SCHEDULING_CLASS = "name", displays processes that belong to a specic scheduling class, or if no name is specied, 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 HP OpenVMS DCL Dictionary: NZ. 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 HP OpenVMS System Services Reference Manual: AGETUAI. The Authorize Utility When a new user is added to the SYSUAF le, or when a users record is modied, Authorize searches the class scheduler database le 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.
440 Process Control
Process Control 4.5 Using the Class Scheduler in CPU Scheduling 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 specied 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 HP OpenVMS System Services Reference Manual: GETUTCZ.
4.7.1 Reading and Writing in the Address Space of Another Process (Alpha and I64 Only)
EXE$READ_PROCESS and EXE$WRITE_PROCESS are OpenVMS Alpha and OpenVMS I64 system routines in nonpaged system space. EXE$READ_ PROCESS reads data from a target processs address space or registers and writes it to a buffer in the local processs address space. EXE$WRITE_PROCESS obtains data from a local processs address space and transfers it to the target processs context. Both routines must be called from kernel mode at IPL 0. One of the arguments to these procedures species whether or not the procedure is to access memory and registers in the target process. Another argument species the memory address or register number. The contents of these arguments are symbolic names (beginning with the prex EACB$) that are dened by the $PROCESS_READ_WRITE macro in SYS$LIBRARY:LIB.MLB. (They are also dened 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 processs address space or registers and writes it to a buffer in the local processs 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 type access mechanism ipid longword (unsigned) read only by value
Internal process ID of the target process. The internal PID, or internal process ID, is distinct from the extended PID, or PID. The internal PID does not include any node information, and is used only in internal routines that operate on a single node within a cluster. The two types of pids are described in the PCBDEF.SDL le. Note that the bit layout of the pids is dependent upon the version of OpenVMS in use, and may change from one version of OpenVMS to the next. However, the internal PID can be derived from the extended PID using the routine EXE_STD$CVT_EPID_TO_IPID. This routine takes a single argument (the extended pid, unsigned longword by value) and returns the internal pid (unsigned longword by value) as the return value of the routine. If an error occurs, the return value is set to zero. buffer_size OpenVMS usage type access mechanism
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 the last available register (based on the value of EACB$K_GEN_REGS_ LENGTH), EXE$READ_PROCESS returns SS$_ILLSER status.
longword_unsigned longword (unsigned) read only 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. For I64, if target_address_type is EACB$K_GENERAL_REGISTER, register values extend from eacb$k_r0 through eacb$k_isr (see proc_read_write.h). If target_address_type type is EACB$K_INVOCATION_CONTEXT, register values represent values in an INVOCATION_CONTEXT. See the HP OpenVMS Calling Standard for the denition of invocation context. local_address OpenVMS usage type access mechanism
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. For I64, symbolic constant indicating whether the target_address argument is a memory address (eacb$k_memory), or a general register (eacb$k_general_ register), or an invocation context (eacb$k_invocation_context). 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.
Return Values
SS$_ACCVIO SS$_ILLSER Unable to write to the location indicated by local_address or ast_counter_address. Routine was called with IPL greater than 0, or an illegal target_address_type was specied. 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 the last available register (based on the value of EACB$K_GEN_REGS_LENGTH). Insufcient memory available for specied buffer. The ipid argument does not correspond to an existing process. The interprocess read nished successfully. The read operation did not nish 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 processs address space and writes it to a buffer in the local processs address space. EXE$READ_PROCESS allocates nonpaged pool for an AST control block (ACB), an ACB extension, and a buffer of the specied 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 processs 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 processs address space and writes it either to a target processs registers or a buffer in a target processs 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 type access mechanism ipid longword (unsigned) read only by value
Internal process ID of the target process. The internal PID, or internal process ID, is distinct from the extended PID, or PID. The internal PID does not include any node information, and is used only in internal routines that operate on a single node within a cluster. The two types of pids are described in the PCBDEF.SDL le. Note that the bit layout of the pids is dependent upon the version of OpenVMS in use, and may change from one version of OpenVMS to the next. However, the internal PID can be derived from the extended PID using the routine EXE_STD$CVT_EPID_TO_IPID. This routine takes a single argument (the extended pid, unsigned longword by value) and returns the internal pid (unsigned longword by value) as the return value of the routine. If an error occurs, the return value is set to zero. buffer_size OpenVMS usage type access mechanism
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 the last available register (based on the value of EACB$K_GEN_REGS_LENGTH), EXE$WRITE_PROCESS returns SS$_ILLSER status.
Address in local process from which data is to be transferred. target_address OpenVMS usage type access mechanism
longword_unsigned longword (unsigned) read only 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. For I64, if target_address_type is EACB$K_GENERAL_REGISTER, register values extend from each$k_r0 through eacb$k_isr (see proc_read_write.h). For Alpha and I64, target_address_type may not be set to EACB$K_ INVOCATION_CONTEXT. 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 type access mechanism cond_value longword (unsigned) write only by value
SS$_ILLSER
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 processs address space and writes it to a target processs registers or a buffer in a target processs address space. EXE$WRITE_PROCESS allocates nonpaged pool for an AST control block (ACB), an ACB extension, and a buffer of the specied 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.)
Process Control EXE$WRITE_PROCESS 4.7.2 Writing an Executive Image (Alpha and I64 Only)
An executive image is an image that is mapped into system space as part of the OpenVMS executive. It contains data, routines, and initialization code specic to an images functions and features. An executive image is implemented as a form of shareable image. Like any shareable image, it has a global symbol table, image section descriptors, and an image activator xup section. Unlike a shareable image, however, an executive image does not usually contain a symbol vector. Universally available procedures and data cells in system-supplied executive images are accessed through entries provided by the symbol vectors in the system base images SYS$BASE_IMAGE.EXE and SYS$PUBLIC_VECTORS.EXE. References to an executive image are resolved through these symbol vectors, whether from an executive image or from a user executable or shareable image. Unlike a system-supplied executive image, an executive image that you create cannot provide universally accessible entry points and symbols in this manner. Instead, it must establish its own vector of procedure descriptors for its callable routines and make the address of that vector available systemwide. The OpenVMS executive loader imposes several requirements on the sections of any executive image. These requirements include the following: On Alpha, an executive image can contain at most one image section of the following types and no others: Nonpaged execute section (for code) Nonpaged read/write section (for read-only and writable data, locations containing addresses that must be relocated at image activation, and the linkage section for nonpaged code) Paged execute section (for code) Paged read/write section (for read-only and writable data, locations containing addresses that must be relocated at image activation, and the linkage section for pageable code) Initialization section (for initialization procedures and their associated linkage section and data) Image activator xup section The modules of an executive image dene program sections (PSECT) with distinct names. The named PSECT is necessary so that the program sections can be collected into clusters, by means of the COLLECT= linker option, during linking. A COLLECT= option specied in the linking of an executive image generates each of the rst ve image sections. The linker creates the image activator xup section to enable the image activator to nally resolve references to SYS$BASE_IMAGE.EXE and SYS$PUBLIC_VECTORS.EXE with addresses within the loaded executive image. Once the executive image has been initialized, the OpenVMS executive loader deallocates the memory for both the xup section and the initialization section. On I64, an executive image can have any number of image sections of various types. Image sections are loaded using the actual image size, and a typespecic allocation granularity less than the page size. Having more than a minimum number of image sections has some impact on physical memory
INITIALIZATION_ROUTINE
Declares a routine to be an initialization routine.
Format
INITIALIZATION_ROUTINE name [,system_rtn=0] [,unload=0] [,priority=0]
Parameters
name Name of the initialization routine. [system_rtn=0] Indicates whether the initialization routine is external to the module invoking the macro. The default value of 0, indicating that the initialization routine is part of the current module, is the only option supported. [unload=0] Indicates whether the name argument species an unload routine. The default value of 0, indicating that the argument species an initialization routine, is the only option supported. [priority=0] Indicates the PSECT in which the entry for this initialization routine should be placed. Routines that specify the priority argument as 0 are placed in the rst PSECT (EXEC$INIT_000); those that specify a value of 1 are placed in the second (EXEC$INIT_001). The routines in the rst PSECT are called before those in the second.
Description
The INITIALIZATION_ROUTINE macro declares a routine to be an initialization routine.
! Replace execlet with your image name $ LINK /NATIVE_ONLY/BPAGES=14 /REPLACE/SECTION/NOTRACEBACK/SHARE=execlet/MAP=execlet /FULL /CROSS /SYMBOL=execlet SYS$LIBRARY:VMS_EXECLET_LNK /OPTION, SYS$INPUT/OPTION ! SYMBOL_TABLE=GLOBALS ! Creates .STB for System Dump Analyzer CLUSTER=execlet,,,- ! ! SYS$LIBRARY:STARLET/INCLUDE:(SYS$DOINIT), - " ! Insert executive object code here sys$disk:[]execlet.obj ! end of executive object code here SYS$LOADABLE_IMAGES:SYS$BASE_IMAGE.EXE/SHAREABLE/SELECTIVE
! The CLUSTER= option creates the named cluster execlet, specifying the order
an executive image. This module declares the initialization routine table and provides routines to drive the actual initialization of an executive image. 4.7.2.3 Loading an Executive Image (Alpha or I64 Only) There are two methods of loading an executive image: Calling LDR$LOAD_IMAGE to load the executive image at run time. This method lets you pass the address of a buffer to the images initialization routine by which the caller and the initialization routine can exchange data. Section 4.7.2.4 describes LDR$LOAD_IMAGE. Note that you must link the code that calls LDR$LOAD_IMAGE against the system base image, using the /SYSEXE qualier to the LINK command. Using the SYSMAN SYS_LOADABLE ADD command and updating the OpenVMS system images le (SYS$LOADABLE_IMAGES:VMS$SYSTEM_ IMAGES.DATA). This method causes the executive image to be loaded and initialized during the phases of system initialization. (See VMS for Alpha Platforms Internals and Data Structures for information about how an executive images initialization routine is invoked during system initialization.)
LDR$LOAD_IMAGE
Loads an OpenVMS executive image into the system.
Module
SYSLDR_DYN
Format
LDR$LOAD_IMAGE lename ,ags ,ref_handle ,user_buf
Arguments
lename OpenVMS usage type access mechanism character string character string read only by descriptor
The longword address of a character string descriptor containing the le name of the executive image to be loaded. The le name can include a directory specication and image name, but no device name. If you omit the directory specication, LDR$LOAD_IMAGE supplies SYS$LOADABLE_IMAGES as the default. ags OpenVMS usage type access mechanism
A ags longword, containing the following bit elds. (Symbolic names for these bit elds are dened by the $LDRDEF macro in SYS$LIBRARY:LIB.MLB.)
LDR$V_PAG
LDR$V_UNL LDR$V_OVR
LDR$V_USER_BUF
LDR$V_NO_SLICE
When set, indicates that the image should be loaded with its pageable sections resident. The ag is generally based on the value of the bit 0 in the S0_PAGING system parameter. This ag is ignored on I64, as all executive image sections are loaded resident (nonpaged). When set, indicates that the image may be removed from memory. When set, indicates that the images read-only sections should not be overwritten during bugcheck processing. This ag is not used on OpenVMS Alpha or I64 systems. When set, indicates that the caller has passed the address of a buffer that should be passed to the initialization routine. When set, indicates that the images sections should not be loaded into a granularity hint region. This ag is ignored on I64, as all executive image sections may be loaded into a granularity hint region.
The longword address of a reference handle, a three-longword buffer to be lled by LDR$LOAD_IMAGE as follows: +00 +04 Address of loaded image or zero if image was loaded sliced. Address of loaded image data block (LDRIMG). See the $LDRIMGDEF macro denition in SYS$LIBRARY:LIB.MLB and VMS for Alpha Platforms Internals and Data Structures for a description of the LDRIMG structure. Loaded image sequence number.
+08
The longword address of a user buffer passed to executive images initialization routine if LDR$V_USER_BUF is set in the ags longword.
Context
LDR$LOAD_IMAGE must be called in executive mode.
Return Values
SS$_ACCVIO Unable to read the character string descriptor containing the le name of the executive image to be loaded or to write the reference handle. An executive image was loaded containing a global symbol that is not vectored through either the SYS$BASE_IMAGE or the SYS$PUBLIC_ VECTORS image. Image header is larger than two blocks or was built with a version of the linker that is incompatible with LDR$LOAD_IMAGE. During a sliced image load request, a relocation or xup operation was attempted on an image offset that has no resultant address within the image. A load request was made for an executive image that illegally contains demand zero sections. Fewer than three arguments were passed to LDR$LOAD_IMAGE, or, with LDR$V_USER_ BUF set in the ags longword, fewer than four arguments. Insufcient nonpaged pool for the LDRIMG structure or insufcient physical memory to load nonpageable portion of an executive image (that is, an image loaded as nonsliced). Insufcient system page table entries (SPTEs) to describe the address space required for the executive image to be loaded as nonsliced. A load request was made for an image that was not linked correctly because it contains more than one each of the following types of sections: xup initialization nonpaged code nonpaged data paged code paged data
LOADER$_BAD_GSD
SS$_BADIMGHDR
LOADER$_BADIMGOFF
LOADER$_DZRO_ISD SS$_INSFARG
SS$_INSFMEM
SS$_INSFSPTS
LOADER$_MULTIPLE_ISDS
LOADER$_SPF_TOBIG
SS$_SYSVERDIF
LOADER$_VEC_TOBIG
Other
Description
LDR$LOAD_IMAGE loads an executive image into system space and calls its initialization routine. Optionally, LDR$LOAD_IMAGE returns information about the loaded image to its caller. The initialization routine is passed by two or three longword arguments, depending upon the setting of LDR$V_USER_BUF: Address of loaded image data block (LDRIMG) The ags longword The longword address of a user buffer passed to the executive images initialization routine (if LDR$V_USER_BUF is set in the ags longword)
LDR$UNLOAD_IMAGE
Unloads a removable executive image. This routine is called to unload an execlet. All resources are returned.
Module
SYSLDR_DYN
Format
LDR$UNLOAD_IMAGE lename ,ref_handle
Arguments
lename OpenVMS usage type access mechanism character string character string read only by descriptor
The longword address of a character string descriptor containing the le name of the executive image to be unloaded. The le name must be supplied exactly as it was supplied to LDR$LOAD_IMAGE when the executive image was loaded. ref_handle OpenVMS usage type access mechanism
The longword address of the reference handle containing the three-longword block returned by LDR$LOAD_IMAGE when the executive image was loaded. You can set the rst longword of the block to -1 to bypass reference handle checks and simply unload the named executive image.
Context
LDR$UNLOAD_IMAGE must be called in kernel mode.
Returns
OpenVMS usage type access mechanism cond_value longword (unsigned) write only by value
LOADER$_MARKUNL
LOADER$_UNL_PEN
Description
LDR$UNLOAD_IMAGE removes an executive image from system space and returns all memory resources allocated when the image was loaded. Images can only be removed if they were originally loaded with the bit LDR$V_UNL set in the input ags to LDR$LOAD_IMAGE.
Process Control 4.8 Synchronizing Programs by Specifying a Time for Program Execution
SYS$GETUTC SYS$NUMUTC
SYS$TIMCON
Process Control 4.8 Synchronizing Programs by Specifying a Time for Program Execution
Table 410 (Cont.) Time Manipulation System Services and Routines
Routine LIB$ADD_TIMES LIB$CONVERT_DATE_STRING LIB$CVT_FROM_INTERNAL_TIME LIB$CVTF_FROM_INTERNAL_TIME LIB$CVT_TO_INTERNAL_TIME LIB$CVTF_TO_INTERNAL_TIME LIB$CVT_VECTIM LIB$DAY LIB$DATE_TIME LIB$FORMAT_DATE_TIME LIB$FREE_DATE_TIME_CONTEXT LIB$GET_DATE_FORMAT LIB$GET_MAXIMUM_DATE_LENGTH LIB$GET_USERS_LANGUAGE LIB$INIT_DATE_TIME_CONTEXT LIB$SUB_TIMES Description Adds two quadword times Converts an input date/time string to an operating system internal time Converts internal time to external time Converts internal time to external time (F-oating value) Converts external time to internal time Converts external time to internal time (F-oating value) Converts 7-word vector to internal time Obtains offset to current day from base time, in number of days Obtains the date and time in user-specied format Formats a date and/or time for output Frees date/time context Returns the users specied date/time input format Returns the maximum possible length of an output date/time string Returns the users selected langauge Initializes the date/time context with a user-specied format Subtracts two quadword times
4.8.1.1 Executing a Program at a Specied Time To execute a program at a specied time, use LIB$SPAWN to create a process that executes a command procedure containing two commandsthe DCL command WAIT and the command that invokes the desired program. Because you do not want the parent process to remain in hibernation until the process executes, execute the process concurrently. You can also use the SYS$CREPRC system service to execute a program at a specied time. However, because a process created by SYS$CREPRC hibernates rather than terminates after executing the desired program, HP recommends you use the LIB$SPAWN routine unless you need a detached process. Example 414 executes a program at a specied delta time. The parent program prompts the user for a delta time, equates the delta time to the symbol EXECUTE_TIME, and then creates a subprocess to execute the command procedure LATER.COM. LATER.COM uses the symbol EXECUTE_TIME as the parameter for the WAIT command. (You might also allow the user to enter an absolute time and have your program change it to a delta time by subtracting the current time from the specied time. Chapter 27 discusses time manipulation.) Example 414 Executing a Program Using Delta Time ! Delta time CHARACTER*17 TIME INTEGER LEN
(continued on next page)
Process Control 4.8 Synchronizing Programs by Specifying a Time for Program Execution
Example 414 (Cont.) Executing a Program Using Delta Time ! Mask for LIB$SPAWN INTEGER*4 MASK ! Declare status and library routine INTEGER STATUS, LIB$SPAWN ! Get delta time STATUS = LIB$GET_INPUT (TIME, 2 Time (delta): , 2 LEN) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) ! Equate symbol to TIME STATUS = LIB$SET_SYMBOL (EXECUTE_TIME, 2 TIME(1:LEN)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) ! Set the mask and call LIB$SPAWN MASK = IBSET (MASK,0) ! Execute subprocess concurrently STATUS = LIB$SPAWN(@LATER, 2 DATA84.IN, 2 DATA84.RPT, 2 MASK) END LATER.COM $ WAIT EXECUTE_TIME $ RUN SYS$DRIVE0:[USER.MATH]CALC $ DELETE/SYMBOL EXECUTE_TIME 4.8.1.2 Executing a Program at Timed Intervals To execute a program at timed intervals, you can use either LIB$SPAWN or SYS$CREPRC. Using LIB$SPAWN Using LIB$SPAWN, you can create a subprocess that executes a command procedure containing three commands: the DCL command WAIT, the command that invokes the desired program, and a GOTO command that directs control back to the WAIT command. Because you do not want the parent process to remain in hibernation until the subprocess executes, execute the subprocess concurrently. See Section 4.8.1.1 for an example of LIB$SPAWN. Using SYS$CREPRC Using SYS$CREPRC, create a detached process to execute a program at timed intervals as follows: 1. Create and hibernate a processUse SYS$CREPRC to create a process that executes the desired program. Set the PRC$V_HIBER bit of the stsg argument of the SYS$CREPRC system service to indicate that the created process should hibernate before executing the program. 2. Schedule a wakeup call for the created subprocessUse the SYS$SCHDWK system service to specify the time at which the system should wake up the subprocess, and a time interval at which the system should repeat the wakeup call.
Process Control 4.8 Synchronizing Programs by Specifying a Time for Program Execution
Example 415 executes a program at timed intervals. The program creates a subprocess that immediately hibernates. (The identication number of the created subprocess is returned to the parent process so that it can be passed to SYS$SCHDWK.) The system wakes up the subprocess at 6:00 a.m. on the 23rd (month and year default to system month and year) and every 10 minutes thereafter. Example 415 Executing a Program at Timed Intervals ! SYS$CREPRC options and values INTEGER OPTIONS EXTERNAL PRC$V_HIBER ! ID of created subprocess INTEGER CR_ID ! Binary times INTEGER TIME(2), 2 INTERVAL(2) . . . ! Set the PRC$V_HIBER bit in the OPTIONS mask and ! create the process OPTIONS = IBSET (OPTIONS, %LOC(PRC$V_HIBER)) STATUS = SYS$CREPRC (CR_ID, ! PID of created process 2 CHECK, ! Image 2 ,,,,, 2 SLEEP, ! Process name 2 %VAL(4), ! Priority 2 ,, 2 %VAL(OPTIONS)) ! Hibernate IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Translate 6:00 a.m. (absolute time) to binary STATUS = SYS$BINTIM (23-- 06:00:00.00, ! 6:00 a.m. 2 TIME) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Translate 10 minutes (delta time) to binary STATUS = SYS$BINTIM (0 :10:00.00, ! 10 minutes 2 INTERVAL) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Schedule wakeup calls STATUS = SYS$SCHDWK (CR_ID, ! ID of created process 2 , 2 TIME, ! Initial wakeup time 2 INTERVAL) ! Repeat wakeup time IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) . . .
Process Control 4.8 Synchronizing Programs by Specifying a Time for Program Execution
Use the system service SYS$SETIMR to place a request in the system timer queue. The format of this service is as follows: SYS$SETIMR ([efn] ,daytim ,[astadr] ,[reqidt] ,[ags]) Specifying the Starting Time Specify the absolute or delta time at which you want the program to begin execution using the daytim argument. Use the SYS$BINTIM system service to convert an ASCII time to the binary system format required for this argument. Signaling Timer Expiration Once the system has reached this time, the timer expires. To signal timer expiration, set an event ag in the efn argument or specify an AST routine to be executed in the astadr argument. Refer to Section 6.8 and Chapter 8 for more information about using event ags and ASTs. How Timer Requests Are Identied The reqidt argument identies each system time request uniquely. Then, if you need to cancel a request, you can refer to each request separately. To cancel a timer request, use the SYS$CANTIM system service.
The kernel thread can continue execution normally only after a corresponding Wake from Hibernation (SYS$WAKE) system service (if it is hibernating), or after a Resume Process (SYS$RESUME) system service, if it is suspended. Suspending or hibernating a kernel thread puts it into a dormant state; the thread is not deleted.
Reversed by SYS$WAKE/SYS$SCHDWK system service. Interruptible; can receive ASTs. Can wake self. Can schedule wake up at an absolute time or at a xed time interval.
Noninterruptible; cannot receive ASTs1 . Cannot cause self to resume. Cannot schedule resumption.
1 If a process is suspended in kernel mode (a hard suspension), it cannot receive any ASTs. If a process is suspended at supervisor mode (a soft suspension), it can receive executive or kernel mode ASTs. See the description of SYS$SUSPND in the HP OpenVMS System Services Reference Manual: GETUTCZ.
Table 412 summarizes the system services and routines that can place a process in or remove a process from hibernation or suspension. Table 412 System Services and Routines Used for Hibernation and Suspension
Routine Hibernating Processes SYS$HIBER Places the requesting kernel thread in the hibernation state. An AST can be delivered to the thread while it is hibernating. The service puts only the calling thread into HIB; no other thread is affected. Resumes execution of a kernel thread in hibernation. This service wakes all hibernating kernel threads in a process regardless of the caller. Any thread that is not hibernating when the service is called is marked wake pending. Because of the wake pending, the next call to SYS$HIBER completes immediately and the thread does not hibernate. Premature wakeups must be handled in the code. Resumes execution of a kernel thread in hibernation at a specied time. This service schedules a wakeup request for a thread that is about to call SYS$HIBER. The wakeup affects only the requesting thread; any other hibernating kernel threads are not affected. Uses the services SYS$SCHDWK and SYS$HIBER. (continued on next page) Function
SYS$WAKE
SYS$SCHDWK
LIB$WAIT
Suspended Kernel Threads and Processes SYS$SUSPEND SYS$RESUME Puts in a suspended state all threads associated with the specied process. Puts in an execution state all threads of the specied process.
4.9.1.1 Using Process Hibernation The hibernate/wake mechanism provides an efcient way to prepare an image for execution and then to place it in a wait state until it is needed. If you create a subprocess that must execute the same function repeatedly and must execute immediately when it is needed, you could use the SYS$HIBER and SYS$WAKE system services, as shown in the following example: /* Process TAURUS */ #include <stdio.h> #include <descrip.h> main() { unsigned int status; $DESCRIPTOR(prcnam,"ORION"); $DESCRIPTOR(image,"COMPUTE.EXE"); /* Create ORION */ status = SYS$CREPRC(0, &image, 0, 0, 0, 0, 0, &prcnam, 0, 0, 0, 0); if ((status & 1) != 1) LIB$SIGNAL(status); . . . /* Wake ORION */ status = SYS$WAKE(0, &prcnam); if ((status & 1) != 1) LIB$SIGNAL(status); . . . /* Wake ORION again */ status = SYS$WAKE(0, &prcnam); if ((status & 1) != 1) LIB$SIGNAL(status); . . . }
!
"
! Process TAURUS creates the process ORION, specifying the descriptor for the
ORION continues execution following the SYS$HIBER service call. When it nishes its job, ORION loops back to repeat the SYS$HIBER call and to wait for another wakeup.
# The image COMPUTE is initialized, and ORION issues the SYS$HIBER
system service. The Schedule Wakeup (SYS$SCHDWK) system service, a variation of the SYS$WAKE system service, schedules a wakeup for a hibernating process at a xed time or at an elapsed (delta) time interval. Using the SYS$SCHDWK service, a process can schedule a wakeup for itself before issuing a SYS$HIBER call. For an example of how to use the SYS$SCHDWK system service, see Chapter 27. Hibernating processes can be interrupted by asynchronous system traps (ASTs), as long as AST delivery is enabled. The process can call SYS$WAKE on its own behalf in the AST service routine, and continue execution following the execution of the AST service routine. For a description of ASTs and how to use them, see Chapter 8. 4.9.1.2 Using Alternative Methods of Hibernation You can use two additional methods to cause a process to hibernate: Specify the stsg argument for the SYS$CREPRC system service, setting the bit that requests SYS$CREPRC to place the created process in a state of hibernation as soon as it is initialized. Specify the /DELAY, /SCHEDULE, or /INTERVAL qualier to the RUN command when you execute the image from the command stream.
When you use the SYS$CREPRC system service, the creating process can control when to wake the created process. When you use the RUN command, its qualiers control when to wake the process. If you use the /INTERVAL qualier and the image to be executed does not call the SYS$HIBER system service, the image is placed in a state of hibernation whenever it issues a return instruction (RET). Each time the image is awakened, it begins executing at its entry point. If the image does call SYS$HIBER, each time it is awakened it begins executing at either the point following the call to SYS$HIBER or at its entry point (if it last issued a RET instruction).
4.9.3.1 Performing Image Rundown The operating system performs image rundown functions that release system resources obtained by a process while it is executing in user mode. These activities occur in the following order: 1. Any outstanding I/O requests on the I/O channels are canceled, and I/O channels are deassigned. 2. Memory pages occupied or allocated by the image are deleted, and the working set size limit of the process is readjusted to its default value. 3. All devices allocated to the process at user mode are deallocated (devices allocated from the command stream in supervisor mode are not deallocated). 4. Timer-scheduled requests, including wakeup requests, are canceled. 5. Common event ag clusters are disassociated. 6. Locks are dequeued as a part of rundown. 7. User mode ASTs that are queued but have not been delivered are deleted, and ASTs are enabled for user mode. 8. Exception vectors declared in user mode, compatibility mode handlers, and change mode to user handlers are reset. 9. System service failure exception mode is disabled. 10. All process private logical names and logical name tables created for user mode are deleted. Deletion of a logical name table causes all names in that table to be deleted. Note that names entered in shareable logical name tables, such as the job or group table, are not deleted at image rundown, regardless of the access mode for which they were created. 4.9.3.2 Initiating Rundown To initiate the rundown activities described in Section 4.9.3.1, the system calls the Exit (SYS$EXIT) system service on behalf of the process. In some cases, a process can call SYS$EXIT to terminate the image itself (for example, if an unrecoverable error occurs). You should not call the SYS$EXIT system service directly from a main program. By not calling SYS$EXIT directly from a main program, you allow the main program to be more like ordinary modular routines and therefore usable by other programmers as callable routines.
Process Control 469
4.9.3.3 Performing Cleanup and Rundown Operations Use exit handlers to perform image-specic cleanup or rundown operations. For example, if an image uses memory to buffer data, an exit handler can ensure that the data is not lost when the image exits as the result of an error condition. To establish an exit-handling routine, you must set up an exit control block and specify the address of the control block in the call to the Declare Exit Handler (SYS$DCLEXH) system service. You can call an exit handler by using standard calling conventions; you can provide arguments to the exit handler in the exit control block. The rst argument in the control block argument list must specify the address of a longword for the system to write the status code from SYS$EXIT. If an image declares more than one exit handler, the control blocks are linked together on a last-in, rst-out (LIFO) basis. After an exit handler is called and returns control, the control block is removed from the list. You can remove exit control blocks prior to image exit by using the Cancel Exit Handler (SYS$CANEXH) system service. Exit handlers can be declared from system routines executing in supervisor or executive mode. These exit handlers are also linked together in other lists, and they receive control after exit handlers that are declared from user mode are executed. Exit handlers are called as a part of the SYS$EXIT system service. While a call to the SYS$EXIT system service often precedes image rundown activities, the call is not a part of image rundown. There is no way to ensure that exit handlers will be called if an image terminates in a nonstandard way. To see examples of exit handler programs, refer to Section 9.15.4. 4.9.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, &prcnam, 0); /* pidadr - Process id */ /* prcnam - Process name */ /* code - Completion code */
When the system is called to delete a process as a result of any of these conditions, it rst 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: The image executing in the process is run down. The image rundown that occurs during process deletion is the same as that described in Section 4.9.3.1. When a process is deleted, however, the rundown releases all system resources, including those acquired from access modes other than user mode. Resource quotas are released to the creating process, if the process being deleted is a subprocess. If the creating process species a termination mailbox, a message indicating that the process is being deleted is sent to the mailbox. For detached processes created by the system, the termination message is sent to the system job controller.
Figure 41 illustrates the ow of events from image exit through process deletion.
No
Call Them, in LIFO Order, Using Argument List in Exit Control Block
No
Call the Delete Process ($DELPRC) System Service to Delete the Process
No
*This exit handler is declared from supervisor mode and is located during the normal search for exit handlers.
Deletion Complete
ZK0857GE
Because a subprocess is automatically deleted when the image it is executing terminates (or when the command stream for the command interpreter reaches end of le), you normally do not need to call the SYS$DELPRC system service explicitly. 4.9.4.2 $DELPRC System Service Can Invoke Exit Handlers (Alpha and I64 only) As of OpenVMS Version 7.3-1, the system parameter DELPRC_EXIT provides the default system setting for whether an exit handler is called and at what access mode. DELPRC_EXIT allows you to specify the least-privileged mode for which exit handling will be attempted, or that no exit handling will be attempted. The possible DELPRC_EXIT values are as follows: 0= Do not enable the EXIT functionality with $DELPRC 4= Execute kernel mode exit handlers 5= Execute exec and more privileged mode exit handlers 6= Execute supervisor and more privileged mode exit handlers 7= Execute user and more privileged mode exit handlers
The system default is 5, which allows components with exec mode exit handlers to execute normal rundown activity, but prevents continued execution of user mode application code or command procedures. In particular, the RMS exec-mode exit handler completes le updates in progress. This prevents le inconsistencies or loss of some le updates made just prior to a process deletion.
DELPRC$M_MODE DELPRC$M_NOEXIT
For example, to delete a process executing exec mode exit handlers from a macro program: $DELPRC_S PIDADR = pid,FLAGS = #<DELPRC$M_EXIT!PSL$C_EXEC> If the ags argument is not specied or is specied with a zero, the system parameter DELPRC_EXIT controls what exit handlers, if any, are called by $DELPRC. As of OpenVMS Version 7.3-1 you can also use the DCL STOP command qualier [NO]EXIT[=access-mode] to override the system default setting determined by the system parameter DELPRC_EXIT. If you specify an access mode of user_mode, supervisor_mode, executive_mode, or kernel_mode, the resulting $DELPRC ag argument is set accordingly. You should be aware of the following differences: If you use the DCL STOP command with the /EXIT qualier but do not specify an access mode, executive_mode is used by default. If you use the DCL STOP command without the /EXIT qualier, the system parameter DELPRC_EXIT is used instead.
If you use the DCL STOP command without either the /IDENTIFICATION qualier or the process-name parameter, then the currently excuting image is terminated; the process is not deleted. In a mixed version or mixed architecture cluster, any explicit control specied to $DELPRC or a DCL STOP command is passed to the node on which the process is executing. The process deletion on the remote node executes as dened for the version of OpenVMS running on the target node. Therefore, consider the following conguration examples.
OpenVMS Alpha version prior to 7.3-1 or OpenVMS VAX (local) to OpenVMS Alpha Version 7.3-1 or later (remote) Any mix of OpenVMS Alpha prior to Version 7.3-1 or any OpenVMS VAX version
Note Deleting the current process: When $DELPRC is used to delete the current process, execution cannot continue in the mode from which $DELPRC was called. The rst exit handlers that are called will be in the next more privileged mode relative to the mode from which $DELPRC was called (subject to options dened). For example: $DELPRC called from user mode could call supervisor mode exit handlers. $DELPRC called from exec mode could only execute kernel mode exit handlers. $DELPRC called from kernel mode cannot call exit handlers.
4.9.4.3 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 rst 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 nal status value of the image. The remainder of the message contains system accounting information used by the job controller and is identical to the rst part of the accounting record sent to the system accounting log le. The description of the SYS$CREPRC system service in the HP OpenVMS System Services Reference Manual provides the complete format of the termination message. If necessary, the creating process can determine the process identication 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 identication of the process being deleted. A termination mailbox cannot be located in memory shared by multiple processors.
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 { 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, &exchan, maxmsg, bufquo, promsk, 0,0,0,0); if ((status & 1 ) != 1) LIB$SIGNAL( status /* /* /* /* /* ); /* efn - event flag */ /* chan - channel */ /* devnam - device name */ /* item list */
# !
prmflg (permanent or temporary) */ " channel */ maximum message size */ no. of bytes used for buffer */ protection mask */
/* Get the mailbox unit number */ status = SYS$GETDVI(0, exchan, 0, &mbxinfo, 0,0,0,0); if ((status & 1 ) != 1) LIB$SIGNAL( status );
/* Create a subprocess */ status = SYS$CREPRC(&pidadr, /* &image, /* 0,0,0,0,0,0,0,0, unitnum, /* 0); /* if ((status & 1 ) != 1) LIB$SIGNAL( status );
/* /* /* /* /* /* /* /* /*
efn - event flag */ $ chan - channel number */ function modifier */ iosb - I/O status block */ astadr - astadr AST routine */ astprm - astprm AST parameter */ p1 - buffer to receive message*/ p2 - length of buffer */ p3, p4, p5, p6 */
execute the image LYRA.EXE and returns the process identication at LYRAPID. The mbxunt argument refers to the unit number of the mailbox, obtained from the Get Device/Volume Information (SYS$GETDVI) system service.
$ 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 dened in the $ACCDEF macro. The process continues executing.
receives control. Because this mailbox can be used for other interprocess communication, the AST routine does the following: Checks for successful completion of the I/O operation by examining the rst word in the IOSB Checks that the message received is a termination message by examining the message type eld in the termination message at the offset ACC$W_ MSGTYPE Checks for the process identication of the process that has been deleted by examining the second longword of the IOSB Checks for the completion status of the process by examining the status eld in the termination message at the offset ACC$L_FINALSTS
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 23.
5
Symmetric Multiprocessing (SMP) Systems
5.1 Introduction to Symmetric Multiprocessing
OpenVMS Alpha and OpenVMS I64 support 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 congurations, refer to VMS for Alpha Platforms 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: Initiate an I/O request Service exceptions Service software interrupts Service hardware interrupts, such as interprocessor and interval timer interrupts Execute process context code in any access mode
6
Synchronizing Data Access and Program Operations
This chapter describes the operating systems synchronization features. It focuses on referencing memory and the techniques used to synchronize memory access. These techniques are the basis for mechanisms OpenVMS itself uses and for mechanisms OpenVMS provides for applications to use. This chapter contains the following sections: Section 6.1 describes synchronization, execution of threads, and atomicity. Section 6.2 describes alignment, granularity, ordering of read and write operations, and performance of memory read and write operations on VAX and Alpha systems in uniprocessor and multiprocessor environments. Section 6.3 describes how alignment and granularity affect the access of shared data on I64 systems. It also discusses the importance of the order of reads and writes completed on I64 systems, and how I64 systems perform memory reads and writes. Section 6.4 describes memory read-modify-write operations on VAX and Alpha systems in uniprocessor and multiprocessor environments. Section 6.5 describes memory read-modify-write operations on I64 systems. Section 6.6 describes hardware-level synchronization methods, such as interrupt priority level, load-locked/store-conditional and interlocked instructions, memory barriers, and PALcode routines. Section 6.7 describes software-level synchronization methods, such as processprivate synchronization techniques, process priority, and spin locks. It also describes how to write applications for a multiprocessor environment using higher-level synchronization methods and how to write to global sections. Section 6.8 describes how to use local and common event ags for synchronization. Section 6.9 describes how to use SYS$SYNCH system service for synchronization.
Process-based threads of execution can share any data in the per-process address space and must synchronize access to any data they share. A thread of execution can incur an exception, which results in passing of control to a condition handler. Alternatively, the thread can receive an AST, which results in passing of control to an AST procedure. Further, an AST procedure can incur an exception, and a condition handlers execution can be interrupted by an AST delivery. If a thread of execution requests a system service or RMS service, control passes to an inner access-mode thread of execution. Code that executes in the inner mode can also incur exceptions, receive ASTs, and request services. Multiple processes, each with its own set of threads of execution, can execute concurrently. Although each process has private address space, processes can share data in a global section mapped into each processs address spaces. You need to synchronize access to global section data because a thread of execution accessing the data in one process can be rescheduled, allowing a thread of execution in another process to access the same data before the rst process completes its work. Although processes access the same system address space, the protection on system space pages usually prevents outer mode access. However, process-based code threads running in inner access modes can access data concurrently in system space and must synchronize access to it. Interrupt service routines access only system space. They must synchronize access to shared system space data among themselves and with process-based threads of execution. A CPU-based thread of execution and an I/O processor must synchronize access to shared data structures, such as structures that contain descriptions of I/O operations to be performed.
6.1.2 Atomicity
Atomicity is a type of serialization that refers to the indivisibility of a small number of actions, such as those occurring during the execution of a single instruction or a small number of instructions. With more than one action, no single action can occur by itself. If one action occurs, then all the actions occur. Atomicity must be qualied by the viewpoint from which the actions appear indivisible: an operation that is atomic for threads running on the same processor can appear as multiple actions to a thread of execution running on a different processor. An atomic memory reference results in one indivisible read or write of a data item in memory. No other access to any part of that data can occur during the course of the atomic reference. Atomic memory references are important for synchronizing access to a data item that is shared by multiple writers or by one writer and multiple readers. References need not be atomic to a data item that is not shared or to one that is shared but is only read.
6.2 Memory Read and Memory Write Operations for VAX and Alpha
This section presents the important concepts of alignment and granularity and how they affect the access of shared data on VAX and Alpha systems. It also discusses the importance of the order of reads and writes completed on VAX and Alpha systems, and how VAX and Alpha systems perform memory reads and writes.
Synchronizing Data Access and Program Operations 6.2 Memory Read and Memory Write Operations for VAX and Alpha
on other processors. Newer Alpha processors with the byte-word extension also provide atomic access to bytes and aligned words. VAX and Alpha systems differ in granularity of data access. The phrase granularity of data access refers to the size of neighboring units of memory that can be written independently and atomically by multiple processors. Regardless of the order in which the two units are written, the results must be identical. VAX systems have byte granularity: individual adjacent or neighboring bytes within the same longword can be written by multiple threads of execution on one or more processors, as can aligned words and longwords. VAX systems provide instructions that can manipulate byte-sized and aligned word-sized memory data in a single, noninterruptible operation. On VAX systems, a byte-sized or word-sized data item that is shared can be manipulated individually. Alpha systems guarantee longword and quadword granularity. That is, adjacent aligned longwords or quadwords can be written independently. Because earlier Alpha systems support instructions that load or store only longword-sized and quadword-sized memory data, the manipulation of byte-sized and word-sized data on such Alpha systems may require that the entire longword or quadword containing the byte- or word-sized item be manipulated. Thus, simply because of its proximity to an explicitly shared data item, neighboring data might become shared unintentionally. Manipulation of byte-sized and word-sized data on such Alpha systems requires multiple instructions that: 1. Fetch the longword or quadword that contains the byte or word 2. Mask the nontargeted bytes 3. Manipulate the target byte or word 4. Store the entire longword or quadword On such Alpha systems, because this sequence is interruptible, operations on byte and word data are not atomic. Also, this change in the granularity of memory access can affect the determination of which data is actually shared when a byte or word is accessed. On such Alpha systems, the absence of byte and word granularity has important implications for access to shared data. In effect, any memory write of a data item other than an aligned longword or quadword must be done as a multipleinstruction read-modify-write sequence. Also, because the amount of data read and written is an entire longword or quadword, programmers must ensure that all accesses to elds within the longword or quadword are synchronized with each other. Alpha systems with the byte-word extension provide instructions that can read or write byte-size and aligned word-sized memory data in a single noninterruptible operation.
Synchronizing Data Access and Program Operations 6.2 Memory Read and Memory Write Operations for VAX and Alpha 6.2.2 Ordering of Read and Write Operations
On VAX uniprocessor and multiprocessor systems, write operations and read operations appear to occur in the same order in which you specify them from the viewpoint of all types of external threads of execution. Alpha uniprocessor systems also guarantee that read and write operations appear ordered for multiple threads of execution running within a single process or within multiple processes running on a uniprocessor. On Alpha multiprocessor systems, you must order reads and writes explicitly to ensure that they occur in a specic order from the viewpoint of threads of execution on other processors. To provide the necessary operating system primitives and compatibility with VAX systems, Alpha systems provide instructions that impose an order on read and write operations.
6.3 Memory Read and Memory Write Operations for I64 Systems
OpenVMS I64 systems provide memory access only through register load and store instructions and special semaphore instructions. This section describes how alignment and granularity affect the access of shared data on I64 systems. It also discusses the importance of the order of reads and writes completed on I64 systems, and how I64 systems perform memory reads and writes.
Synchronizing Data Access and Program Operations 6.3 Memory Read and Memory Write Operations for I64 Systems 6.3.2 Accessing Memory on I64
I64 integer store instructions can write either 1, 2, 4, or 8 bytes, and oatingpoint store instructions can write 4, 8, or 10 bytes. For example, a st4 instruction writes the low-order four bytes of an integer register to memory. In addition, semaphore instructions can read and write memory. For highest performance, data should be aligned on natural boundaries; 10-byte oating-point data should be stored on 16-byte aligned boundaries. If a load or store instruction accesses naturally aligned data, the reference is atomic with respect to the threads on the same CPU and on other SMP nodes. If the data is not naturally aligned, its access is not atomic with respect to threads on other SMP nodes. I64 can load and store aligned bytes, words, longwords, quadwords, and 10-byte oating-point values that are aligned on 16-byte boundaries.
Synchronizing Data Access and Program Operations 6.4 Memory Read-Modify-Write Operations for VAX and Alpha
On Alpha systems, read-modify-write operations that can be performed atomically on VAX systems require a sequence of instructions. Because this sequence can be interrupted, the data may be left in an unstable state. For example, the VAX increment long (INCL) instruction fetches the contents of a specied longword, increments its value, and stores the value back in the longword, performing the operations without interruption. On Alpha systems, each stepfetching, incrementing, storingmust be explicitly performed by a separate instruction. Therefore, another thread in the process (for example, an AST routine) could execute before the sequence completes. However, because atomic updates are the basis of synchronization, and to provide compatibility with VAX systems, Alpha systems provide the following mechanisms to enable atomic read-modify-write updates: Privileged architecture library (PALcode) routines perform queue insertions and removals. Load-locked and store-conditional instructions create a sequence of instructions that implement an atomic update.
Synchronizing Data Access and Program Operations 6.5 Memory Read-Modify-Write Operations for I64 Systems
Note that memory operands of the semaphore instructions must be on aligned boundaries. Unaligned access by a semaphore instruction results in a nonrecoverable unaligned data fault.
Synchronizing Data Access and Program Operations 6.5 Memory Read-Modify-Write Operations for I64 Systems
The problem with the I64 code sequence is that an interrupt can occur between any of the instructions. For example, if the interrupt causes an AST routine to execute or causes another process to be scheduled between the ld4 and the st4, and the AST or other process updates the data pointed to by R1, the STL will store the result (R9) based on stale data. When an atomic operation is required, and /PRESERVE=ATOMICITY (or .PRESERVE ATOMICITY) is specied, the compiler generates the following I64 instruction sequence: $L3: ld4 r23 = [r9] mov.m apccv = r23 mov r22 = r23 sxt4 r23 = r23 adds r23 = 1, r23 cmpxchg4.acq r23, [r9] = r23 cmp.eq pr0, pr6 = r22, r23 (pr6) br.cond.dpnt.few $L3 This code uses the compare-exchange instruction (cmpxchg) to implement the locked access. If another thread of execution has modied the location being modied here, this code loops back and retries the operation.
On VAX systems, many read-modify-write instructions, including queue manipulation instructions, are noninterruptible. These instructions provide an atomic update capability on a uniprocessor. A kernel-mode code thread can block interrupt and process-based threads of execution by raising the IPL. Hence, it can execute a sequence of instructions atomically with respect to the blocked threads on a uniprocessor. Threads of execution that run on multiple processors of an SMP system synchronize access to shared data with read-modify-write instructions that interlock memory. On Alpha systems, some of these mechanisms are provided by hardware, while others have been implemented in PALcode routines. Alpha processors provide several features to assist with synchronization. Even though all instructions that access memory are noninterruptible, no single one performs an atomic read-modify-write. A kernel-mode thread of execution can raise the IPL in order to block other threads on that processor while it performs a read-modify-write sequence or while it executes any other group of instructions. Code that runs in any access mode can execute a sequence of instructions that contains load-locked (LDx_L) and store-conditional (STx_C) instructions to perform a read-modify-write sequence that appears atomic to other threads of execution. Memory barrier instructions order a CPUs memory reads and writes from the viewpoint of other CPUs and I/O processors. Other synchronization mechanisms are provided by PALcode routines.
In the above example, an LDQ instruction was found after an LDQ_L before the matching STQ_C. The LDQ must be moved out of the sequence, either by recompiling or by source code changes. (See Section 6.6.3.3.) ** Backward branch from 00040598 C3E00003 0004059C 47F20400 000405A0 B8100000 000405A4 F4000003 000405A8 A8300000 000405AC 40310DA0 000405B0 F41FFFFA 000405B0 to a STx_C sequence at 0004059C br R31, 000405A8 bis R31, R18, R0 stl_c R0, (R16) bne R0, 000405B4 ldl_l R1, (R16) cmple R1, R17, R0 bne R0, 0004059C
The following MACRO32 source code demonstrates code where there is a "fall through" path, but this case is still noncompliant because of the potential branch and a memory reference in the lock sequence. getlck: evax_ldql movl tstl beql movl is_clear: incl evax_stqc tstl beql r0, lockdata(r8) index, r2 r0 is_clear r3, r2 r0 r0, lockdata(r8) r0 getlck ; ; ; ; ; ; ; ; ; Get the lock data and the current index. If the lock is zero, skip ahead to store. Else, set special index. Increment lock count and store it. Did store succeed? Retry if not.
To correct this code, the memory access to read the value of INDEX must rst be moved outside the LDQ_L/STQ_C sequence. Next, the branch between the LDQ_L and STQ_C, to the label IS_CLEAR, must be eliminated. In this case, it could be done using a CMOVEQ instruction. The CMOVxx instructions are frequently useful for eliminating branches around simple value moves. The following example shows the corrected code: movl index, r2 getlck: evax_ldql r0, lockdata(r8) evax_cmoveq r0, r3, r2 incl r0 evax_stqc r0, lockdata(r8) tstl r0 beql getlck ; ; ; ; ; ; ; Get the current index and then the lock data. If zero, use special index. Increment lock count and store it. Did write succeed? Retry if not.
6.6.3.5 Compiler Versions This section contains information about versions of compilers that may generate noncompliant code sequences and the minimum recommended versions to use when recompiling. Table 61 contains information for OpenVMS compilers. Table 61 OpenVMS Compilers
Old Version BLISS V1.1 DEC C V5.x DEC C++ V5.x DEC Pascal V5.0-2 Recommended Minimum Version BLISS V1.3 HP C V6.0 HP C++ V6.0 HP Pascal V5.1-11 (continued on next page)
Current versions of the MACRO64 assembler may still encounter the loop rotation issue. However, MACRO64 does not perform code optimization by default, and this problem occurs only when optimization is enabled. If SRM_ CHECK indicates a noncompliant sequence in the MACRO64 code, it should rst be recompiled without optimization. If the sequence is still agged when retested, the source code itself contains a noncompliant sequence that must be corrected. 6.6.3.6 Interlocked Memory Sequence Checking for the MACRO32 Compiler The MACRO32 Compiler for OpenVMS Alpha Version 4.1 and later performs additional code checking and displays warning messages for noncompliant code sequences. The following warning messages can display under the circumstances described: BRNDIRLOC, branch directive ignored in locked memory sequence Explanation: The compiler found a .BRANCH_LIKELY directive within an LDx_L/STx_C sequence. User Action: None. The compiler ignores the .BRANCH_LIKELY directive and, unless other coding guidelines are violated, the code works as written. BRNTRGLOC, branch target within locked memory sequence in routine routine_name Explanation: A branch instruction has a target that is within an LDx_ L/STx_C sequence. User Action: To avoid this warning, rewrite the source code to avoid branches within or into LDx_L/STx_C sequences. Branches out of interlocked sequences are valid and are not agged. MEMACCLOC, memory access within locked memory sequence in routine routine_name Explanation: A memory read or write occurs within an LDx_L/STx_C sequence. This can be either an explicit reference in the source code, such as "MOVL data, R0", or an implicit reference to memory. For example, fetching the address of a data label (for example, "MOVAB label, R0") is accomplished by a read from the linkage section, the data area that is used to resolve external references. User Action: To avoid this warning, move all memory accesses outside the LDx_L/STx_C sequence. RETFOLLOC, RET/RSB follows LDx_L instruction Explanation: The compiler found a RET or RSB instruction after an LDx_ L instruction and before nding an STx_C instruction. This indicates an ill-formed lock sequence. User Action: Change the code so that the RET or RSB instruction does not fall between the LDx_L instruction and the STx_C instruction.
The VAX architecture interlock memory instructions are described in detail in the VAX Architecture Reference Manual.
The MB instruction guarantees that all subsequent loads and stores do not access memory until after all previous loads and stores have accessed memory from the viewpoint of multiple threads of execution. Alpha compilers provide semantics for generating memory barriers when needed for specic operations on data items. Code that modies the instruction stream must be changed to synchronize the old and new instruction streams properly. Use of an REI instruction to accomplish this does not work on OpenVMS Alpha systems. The instruction memory barrier (IMB) PALcode routine must be used after a modication to the instruction stream to ush prefetched instructions. In addition, it also provides the same ordering effects as the MB instruction.
Synchronizing Data Access and Program Operations 6.7 Software-Level Synchronization 6.7.1 Synchronization Within a Process
On Alpha and I64 systems without kernel threads, only one thread of execution can execute within a process at a time, so synchronization of threads that execute simultaneously is not a concern. However, a delivery of an AST or the occurrence of an exception can intervene in a sequence of instructions in one thread of execution. Because these conditions can occur, application design must take into account the need for synchronization with condition handlers and AST procedures. On Alpha systems without the byte-word extension, writing bytes or words or performing a read-modify-write operation requires a sequence of Alpha instructions. If the sequence incurs an exception or is interrupted by AST delivery or an exception, another process code thread can run. If that thread accesses the same data, it can read incompletely written data or cause data corruption. Aligning data on natural boundaries and unpacking word and byte data reduce this risk. On Alpha and I64 systems, an application written in a language other than MACRO-32 must identify to the compiler data accessed by any combination of mainline code, AST procedures, and condition handlers to ensure that the compiler generates code that is atomic with respect to other threads. Also, data shared with other processes must be identied. With process-private data accessed from both AST and non-AST threads of execution, the non-AST thread can block AST delivery by using the Set AST Enable (SYS$SETAST) system service. If the code is running in kernel mode, it can also raise IPL to block AST delivery. The Guide to Creating OpenVMS Modular Procedures describes the concept of AST reentrancy. On a uniprocessor or in a symmetric multiprocessing (SMP) system, access to multiple locations with a read or write instruction or with a read-modifywrite sequence is not atomic on OpenVMS systems. Additional synchronization methods are required to control access to the data. See Section 6.7.4 and the sections following it, which describe the use of higher-level synchronization techniques.
The operating system provides basic event synchronization through event ags. Common event ags can be shared among cooperating processes running on a uniprocessor or in an SMP system, though the processes must be in the same user identication code (UIC) group. Thus, if you have developed an application that requires the concurrent execution of several processes, you can use event ags to establish communication among them and to synchronize their activity. A shared, or common, event ag can represent any event that is detectable and agreed upon by the cooperating processes. See Section 6.8 for information about using event ags. The lock management system servicesEnqueue Lock Request (SYS$ENQ), and Dequeue Lock Request (SYS$DEQ)provide multiprocess synchronization tools that can be requested from all access modes. For details about using lock management system services, see Chapter 7. Synchronization of access to shared data by a multiprocess application should be designed to support processes that execute concurrently on different members of an SMP system. Applications that share a global section can use MACRO-32 interlocked instructions or the equivalent in other languages to synchronize access to data in the global section. These applications can also use the lock management system services for synchronization.
The wait form of system services is a variant of asynchronous services; there is a service request and then a wait for the completion of the request. For reliable operation in most applications, WAIT form services must specify a status block. The status prevents the service from completing prematurely and also provides status information.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
4. Suspend thread execution until an event ag is set. 5. Deallocate the local event ags or disassociate common event ags when they are no longer needed. Implicit use of event ags may involve only step 4, or steps 1, 4, and 5. Use run-time library routines and system services to accomplish these event ag tasks. Table 63 summarizes the event ag routines and services. Table 63 Event Flag Routines and Services
Routine or Service LIB$FREE_EF LIB$GET_EF LIB$RESERVE_EF SYS$ASCEFC SYS$CLREF SYS$DACEFC SYS$DLCEFC SYS$READEF SYS$SETEF SYS$SYNCH SYS$WAITFR SYS$WFLAND SYS$WFLOR Task Deallocate a local event ag. Allocate any local event ag. Allocate a specic local event ag. Associate a common event ag cluster. Clear a local or common event ag. Disassociate a common event ag cluster. Delete a common event ag cluster. Read a local or common event ag. Set a local or common event ag. Wait for a local or common event ag to be set and for nonzero status blockrecommended to be used with threads. Wait for a specic local or common event ag to be setnot recommended to be used with threads. Wait for several local or common event ags to be setlogical AND of event ags. Wait for one of several local or common event ags to be setlogical OR of event ags.
Some system services set an event ag to indicate the completion or the occurrence of an event; the calling program can test the ag. Other system services use event ags to signal events to the calling process, such as SYS$ENQ(W), SYS$QIO(W), or SYS$SETIMR.
6.8.2 Introducing Local and Common Event Flag Numbers and Event Flag Clusters
Each event ag has a unique number; event ag arguments in system service calls refer to these numbers. For example, if you specify event ag 1 in a call to the SYS$QIO system service, then event ag 1 is set when the I/O operation completes. To allow manipulation of groups of event ags, the ags are ordered in clusters of 32 numbers corresponding to bits 0 through 31 (<31:0>) in a longword. The clusters are also numbered from 0 to 4. The range of event ag numbers encompasses the ags in all clusters: event ag 0 is the rst ag in cluster 0, event ag 32 is the rst ag in cluster 1, and so on. Event ags are divided into ve clusters: two for local event ags and two for common event ags. There is also a special local cluster 4 that supports EFN 128.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
A local event ag cluster is process specic and is used to synchronize events within a process. A common event ag cluster can be shared by cooperating processes in the same UIC group. A common event ag cluster is identied by name and is specic to a UIC group and VMScluster node. Before a process can use a common event ag cluster, it must explicitly associate with the cluster. (Association is described in Section 6.8.6.) Use them to synchronize events among images executing in different processes. A special local cluster 4 supports only EFN 128, symbolically EFN$C_ENF. EFN$C_ENF is intended for use with wait form services, such as SYS$QIOW and SYS$ENQW, or SYS$SYNCH system service. However, EFN 128 can also be used with ASTs and the SYS$QIO service. By using EFN 128 with ASTs, for example, you can avoid setting event ag zero (0), which eliminates possible event ag contention in processes. The EFN 128 allows you to bypass all event ag processing in system services. Using EFN 128 also allows for faster processing. For more information, see Section 6.8.4. Table 64 summarizes the ranges of event ag numbers and the clusters to which they belong. The same system services manipulate ags in either local and common event ag clusters. Because the event ag number implies the cluster number, you need not specify the cluster number when you call a system service that refers to an event ag. When a system service requires an event ag cluster number as an argument, you need only specify the number of any event ag in the cluster. Thus, to read the event ags in cluster 1, you could specify any number in the range 32 through 63. Table 64 Event Flags
Cluster Number 0 0 Flag Number 0 1 to 23 Type Local Local Usage Default ag used by system routines. May be used in system routines. When an event ag is requested, it is not returned unless it has been previously and specically freed by calls to LIB$FREE_EF. Reserved for use only. Available for general use. Available for general use. Available for general use. Available for general use without explicit allocation.
0 1 2 3 4
24 to 31 32 to 63 64 to 95 96 to 127 128
Synchronizing Data Access and Program Operations 6.8 Using Event Flags 6.8.3 Using Event Flag Zero (0)
Event ag 0 is the default event ag. Whenever a process requests a system service with an event ag number argument, but does not specify a particular ag, event ag 0 is used. Therefore, event ag 0 is more likely than other event ags to be used incorrectly for multiple concurrent requests. Code that uses any event ag should be able to tolerate spurious sets, assuming that the only real danger is a spurious clear that causes a thread to miss an event. Since any system service that uses an event ag clears the ag, there is a danger that an event which has occured but has not been responded to is masked which can result in a hang. For further information, see the SYS$SYNCH system service in HP OpenVMS System Services Reference Manual: GETUTCZ.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
5. The program components that evaluate event ag status can be placed in a wait state. Then, when the event ag is set, execution is resumed. Use the SYS$WAITFR, SYS$WFLOR, SYS$WFLAND, or SYS$SYNCH system service to accomplish this task. 6. When a local event ag is no longer required, free it by using the LIB$FREE_ EF routine. The following Fortran example uses LIB$GET_EF to choose a local event ag and then uses SYS$CLREF to set the event ag to 0 (clear the event ag). (Note that run-time library routines require an event ag number to be passed by reference, and system services require an event ag number to be passed by value.) INTEGER 2 2 2 FLAG, STATUS, LIB$GET_EF, SYS$CLREF
STATUS = LIB$GET_EF (FLAG) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) STATUS = SYS$CLREF (%VAL(FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) 6.8.5.1 Example of Event Flag Services Local event ags are used most commonly with other system services. For example, you can use the Set Timer (SYS$SETIMR) system service to request that an event ag be set either at a specic time of day or after a specic interval of time has passed. If you want to place a process in a wait state for a specied period of time, specify an event ag number for the SYS$SETIMR service and then use the Wait for Single Event Flag (SYS$WAITFR) system service, as shown in the C example that follows: . . . main() { unsigned int status, daytim[1], efn=3; /* Set the timer */ status = SYS$SETIMR( efn, &daytim, 0, 0, 0); if ((status & 1) != 1) LIB$SIGNAL( status . . . /* /* /* /* /* ); efn - event flag */ daytim - expiration time */ astadr - AST routine */ reqidt - timer request id */ flags */
/* Wait until timer expires */ status = SYS$WAITFR( efn ); if ((status & 1) != 1) LIB$SIGNAL( status ); . . . } In this example, the daytim argument refers to a 64-bit time value. For details about how to obtain a time value in the proper format for input to this service, see Chapter 27.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags 6.8.6 Using Common Event Flags
Common event ags are manipulated like local event ags. However, before a process can use event ags in a common event ag cluster, the cluster must be created. The Associate Common Event Flag Cluster (SYS$ASCEFC) system service creates a named common event ag cluster. By calling SYS$ASCEFC, other processes in the same UIC group can establish their association with the cluster so they can access ags in it. Each process that associates with the cluster must use the same name to refer to it; the SYS$ASCEFC system service establishes correspondence between the cluster name and the cluster number that a process assigns to the cluster. The rst program to name a common event ag cluster creates it; all ags in a newly created cluster are clear. Other processes on the same OpenVMS cluster node that have the same UIC group number as the creator of the cluster can reference the cluster by invoking SYS$ASCEFC and specifying the cluster name. Different processes may associate the same name with different common event ag numbers; as long as the name and UIC group are the same, the processes reference the same cluster. Common event ags act as a communication mechanism between images executing in different processes in the same group on the same OpenVMS cluster node. Common event ags are often used as a synchronization tool for other, more complicated communication techniques, such as logical names and global sections. For more information about using event ags to synchronize communication between processes, see Chapter 3. If every cooperating process that is going to use a common event ag cluster has the necessary privilege or quota to create a cluster, the rst process to call the SYS$ASCEFC system service creates the cluster. The following example shows how a process might create a common event ag cluster named COMMON_CLUSTER and assign it a cluster number of 2: . . . #include <descrip.h> . . . unsigned int status, efn=65; $DESCRIPTOR(name,"COMMON_CLUSTER"); /* Cluster name */ . . . /* Create cluster 2 */ status = SYS$ASCEFC( efn, &name, 0, 0);
Other processes in the same group can now associate with this cluster. Those processes must use the same character string name to refer to the cluster; however, the cluster numbers they assign do not have to be the same.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
6.8.6.1 Using the name Argument with SYS$ASCEFC The name argument to the Associate Common Event Flag Cluster (SYS$ASCEFC) system service identies the cluster that the process is creating or associating with. The name argument species a descriptor pointing to a character string. Translation of the name argument proceeds in the following manner: 1. CEF$ is prexed to the current name string, and the result is subjected to logical name translation. 2. If the result is a logical name, step 1 is repeated until translation does not succeed or until the number of translations performed exceeds the number 10. 3. The CEF$ prex is stripped from the current name string that could not be translated. This current string is the cluster name. For example, assume that you have made the following logical name assignment: $ DEFINE CEF$CLUS_RT CLUS_RT_001 Assume also that your program contains the following statements: #include <ssdef.h> #include <descrip.h> . . . unsigned int status; $DESCRIPTOR(name,"CLUS_RT"); /* Logical name of cluster */ . . . status = SYS$ASCEFC( . . . ,&name, . . . ); The following logical name translation takes place: 1. CEF$ is prexed to CLUS_RT. 2. CEF$CLUS_RT is translated to CLUS_RT_001. (Further translation is unsuccessful. When logical name translation fails, the string is passed to the service.) There are two exceptions to the logical name translation method discussed in this section: If the name string starts with an underscore ( _ ), the operating system strips the underscore and considers the resultant string to be the actual name (that is, further translation is not performed). If the name string is the result of a logical name translation, the name string is checked to see whether it has the terminal attribute. If it does, the operating system considers the resultant string to be the actual name (that is, further translation is not performed).
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
6.8.6.2 Temporary Common Event Flag Clusters Common event ag clusters are either temporary or permanent. The perm argument to the SYS$ASCEFC system service denes whether the cluster is temporary or permanent. Temporary clusters require an element of the creating processs quota for timer queue entries (TQELM quota). They are deleted automatically when all processes associated with the cluster have disassociated. Disassociation can be performed explicitly with the Disassociate Common Event Flag Cluster (SYS$DACEFC) system service, or implicitly when the image that called SYS$ASCEFC exits. 6.8.6.3 Permanent Common Event Flag Clusters If you have the PRMCEB privilege, you can create a permanent common event ag cluster (set the perm argument to 1 when you invoke SYS$ASCEFC). A permanent event ag cluster continues to exist until it is marked explicitly for deletion with the Delete Common Event Flag Cluster (SYS$DLCEFC) system service (requires the PRMCEB privilege). Once a permanent cluster is marked for deletion, it is like a temporary cluster; when the last process that associated with the cluster disassociates from it, the cluster is deleted. In the following examples, the rst program segment associates common event ag cluster 3 with the name CLUSTER and then clears the second event ag in the cluster. The second program segment associates common event ag cluster 2 with the name CLUSTER and then sets the second event ag in the cluster (the ag cleared by the rst program segment). Example 1 STATUS = SYS$ASCEFC (%VAL(96), 2 CLUSTER,,) STATUS = SYS$CLREF (%VAL(98)) Example 2 STATUS = SYS$ASCEFC (%VAL(64), 2 CLUSTER,,) STATUS = SYS$SETEF (%VAL(66)) For clearer code, rather than using a specic event ag number, use one variable to contain the bit offset you need and one variable to contain the number of the rst bit in the common event ag cluster that you are using. To reference the common event ag, add the offset to the number of the rst bit. The following examples accomplish the same result as the preceding two examples: Example 1 INTEGER*4 BASE, 2 OFFSET PARAMETER (BASE = 96) OFFSET=2 STATUS = SYS$ASCEFC (%VAL(BASE), 2 CLUSTER,,) STATUS = SYS$CLREF (%VAL(BASE+OFFSET)) Example 2 INTEGER*4 BASE, 2 OFFSET PARAMETER (BASE = 64) OFFSET=2 STATUS = SYS$ASCEFC (%VAL(BASE), 2 CLUSTER,,) STATUS = SYS$SETEF (%VAL(BASE+OFFSET))
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
Common event ags are often used for communicating between a parent process and a created subprocess. The following parent process associates the name CLUSTER with a common event ag cluster, creates a subprocess, and then waits for the subprocess to set event ag 64: INTEGER*4 BASE, 2 OFFSET PARAMETER (BASE = 64, 2 OFFSET = 0) . . . ! Associate common event flag cluster with name STATUS = SYS$ASCEFC (%VAL(BASE), 2 CLUSTER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Create subprocess to execute concurrently MASK = IBSET (MASK,0) STATUS = LIB$SPAWN (RUN REPORTSUB, ! Image 2 INPUT.DAT, ! SYS$INPUT 2 OUTPUT.DAT, ! SYS$OUTPUT 2 MASK) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Wait for response from subprocess STATUS = SYS$WAITFR (%VAL(BASE+OFFSET)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) . . . REPORTSUB, the program executing in the subprocess, associates the name CLUSTER with a common event ag cluster, performs some set of operations, sets event ag 64 (allowing the parent to continue execution), and continues executing: INTEGER*4 2 PARAMETER 2 . . . BASE, OFFSET (BASE = 64, OFFSET = 0)
! Do operations necessary for ! continuation of parent process . . . ! Associate common event flag cluster with name STATUS = SYS$ASCEFC (%VAL(BASE), 2 CLUSTER,,) IF (.NOT. STATUS) 2 CALL LIB$SIGNAL (%VAL(STATUS)) ! Set flag for parent process to resume STATUS = SYS$SETEF (%VAL(BASE+OFFSET)) . . .
Synchronizing Data Access and Program Operations 6.8 Using Event Flags 6.8.7 Wait Form Services and SYS$SYNCH
A wait form system service is a variant of an asynchronous service in which there is a service request and then a wait for the completion of the request. The SYS$SYNCH system service checks the completion status of a system service that completes asynchronously. For reliable operation in most applications, the service whose completion status is to be checked must have been called with the efn and iosb arguments specied. The SYS$SYNCH service uses the event ag and I/O status block of the service to be checked. HP recommends that only EFN$C_ENF be used for concurrent use of event ags.
Another system service that accepts an event ag number as an argument is the Queue I/O Request (SYS$QIO) system service. The following example shows a program segment that issues two SYS$QIO system service calls and uses the SYS$WFLAND system service to wait until both I/O operations complete before it continues execution: . . . #include <lib$routines.h> #include <starlet.h> #include <stsdef.h> . . . unsigned int RetStat, Efn1=1, Efn2=2, EFMask; unsigned short int IOSB1[4], IOSB2[4]; unsigned int EFMask = 1L<<Efn1 | 1L<<Efn2; . . .
! " #
// Issue first I/O request and check for error */ RetStat = sys$qio( Efn1, Chan1, FuncCode1, IOSB1, . . . ) if (!$VMS_STATUS_SUCCESS( RetStat )) $ lib$signal(RetStat); // Issue second I/O request and check for error RetStat = sys$qio( Efn2, Chan2, FuncCode2, IOSB2, . . . ) if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal(RetStat); // Wait until both complete and check for error RetStat = sys$wfland( Efn1, EFMask ); if (!$VMS_STATUS_SUCCESS( RetStat )) lib$signal(status);
632 Synchronizing Data Access and Program Operations %
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
// Determine which asynchronous operation has completed. // If set to zero, the particular $qio call has not completed. if ( IOSB1[0] ) & CallOneCompleted(); if ( IOSB2[0] ) CallTwoCompleted(); . . .
! The event ag argument is specied in each SYS$QIO request. Both of these
event ags are explicitly declared in event ag cluster 0. These variables contain the event ag numbers, and not the event ag masks.
" The I/O Status Blocks are declared. Ensure that the storage associated with
these structures is valid over the lifetime of the asychronous call. Ensure that these structures are not declared within the local context of a call frame of a function that can exit before the asynchronous call completes. Be sure that these calls are declared with static or external context, within the stack frame of a function that will either remain active, or was located within other non-volatile storage. The use of either LIB$GET_EF or EFN$C_ENF (dened in efndef.h) is strongly recommended over the static declaration of local event ags, because the consistent use of either of these techniques will avoid the unintended reuse of local event ags within different parts of the same program, and the intermittent problems that can ensue. Common event ags are somewhat less likely to encounter similar problems due to the requirement to associate with the cluster before use. But the use and switching of event ag clusters and the use of event ags within each cluster should still be carefully coordinated.
# Set up the event ag mask. Since both of these event ags are located in
the same event ag cluster, you can use a simple OR to create the bit mask. Since these event ags are in the same cluster, you can use them in the SYS$WSFLAND call.
$ After both I/O requests are queued successfully, the program calls the
SYS$WFLAND system service to wait until the I/O operations complete. In this service call, the Efn1 argument can specify any event ag number within the event ag cluster containing the event ags to be waited for, since the argument indicates which event ag cluster is associated with the mask. The EFMask argument species to wait for ags 1 and 2. You should specify a unique event ag and a unique I/O status block for each asynchronous call.
% Note that the SYS$WFLAND system service (and the other wait system
services) waits for the event ag to be set; it does not wait for the I/O operation to complete. If some other event were to set the required event ags, the wait for event ag would complete prematurely. Use of event ags must be coordinated carefully.
& Use the I/O status block to determine which of the two calls have completed.
The I/O status block is initialized to zero by the SYS$QIO call, and is set to a nonzero value when the call is completed. An event ag can be set spuriouslytypically if there is unintended sharing or reuse of event ags and thus you should check the I/O status block. For a mechanism that can check both the event ag and the IOSB and thus ensure that the call has completed, see the SYS$SYNCH system service call.
Synchronizing Data Access and Program Operations 6.8 Using Event Flags 6.8.9 Setting and Clearing Event Flags
System services that use event ags clear the event ag specied in the system service call before they queue the timer or I/O request. This ensures that the process knows the state of the event ag. If you are using event ags in local clusters for other purposes, be sure the ags initial value is what you want before you use it. The Set Event Flag (SYS$SETEF) and Clear Event Flag (SYS$CLREF) system services set and clear specic event ags. For example, the following system service call clears event ag 32: $CLREF_S EFN=#32 The SYS$SETEF and SYS$CLREF services return successful status codes that indicate whether the specied ag was set or cleared when the service was called. The caller can thus determine the previous state of the ag, if necessary. The codes returned are SS$_WASSET and SS$_WASCLR. All event ags in a common event ag cluster are initially clear when the cluster is created. Section 6.8.10 describes the creation of common event ag clusters.
EFC0 0 // EFC 0 (Local) EFC1 32 // EFC 1 (Local) EFC2 64 // EFC 2 (Common) EFC3 96 // EFC 3 (Common) int Efn0 = 0, Efn1 = 1, Efn2 = 2, Efn3 = 3; int EFMask; $DESCRIPTOR(EFCname,"ENTERPRISE");
. . . // **** Process COLUMBIA **** // // The image running within process COLUMBIA creates a common // event flag cluster, associating it with Cluster 2 . . . RetStat = sys$ascefc(EFC2, &EFCname, . . . ); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); . . . EFMask = 1L<<Efn1 | 1L<<Efn2 | 1L<<Efn3; // Wait for the specified event flags
"
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
RetStat = sys$wfland(EFC2, EFMask); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); . . . // Disassociate the event flag cluster RetStat = sys$dacefc(EFC2); // // // // // **** Process ENDEAVOUR **** The image running within process ENDEAVOUR associates with the specified event flag cluster, specifically associating it with the common event flag cluster 3.
& %
. . . // Associate the event flag cluster, using Cluster 3 RetStat = sys$ascefc(EFC3,&EFCname, . . . ); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); // Set the event flag, and check for errors RetStat = sys$setef(Efn2+EFC3); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); . . . RetStat = sys$dacefc(EFC3); // // // // // **** Process ATLANTIS ****
The image running within process ATLANTIS associates with the specified event flag cluster, specifically associating it with the common event flag cluster 2.
// Associate the event flag cluster, using Cluster 2 RetStat = sys$ascefc(EFC2, &EFCname); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); // Set the event flag, and check for errors RetStat = sys$setef(Efn2+EFC2); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); . . . retstat = sys$dacefc(EFC2); // // // // **** Process DISCOVERY **** The image running within process DISCOVERY associates with the specified event flag cluster, specifically associating it with the common event flag cluster 3. RetStat = sys$ascefc(EFC3, &EFCname); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); // Wait for the flag, and check for errors RetStat = sys$waitfr(Efn2+EFC3); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat);
)
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
// Set event flag 2, and check for errors RetStat = sys$setef(Efn2+EFC3); if (!$VMS_STATUS_SUCCESS(RetStat)) lib$signal(RetStat); . . . RetStat = sys$dacefc(EFC2);
! Set up some common denitions used by the various applications, including
preprocessor denes for the event ag clusters, and some variables and values for particular event ags within the clusters.
" Assume that COLUMBIA is the rst process to issue the SYS$ASCEFC
system service and therefore is the creator of the ENTERPRISE event ag cluster. Because this is a newly created common event ag cluster, all event ags in it are clear. COLUMBA then waits for the specied event ags, and then exitsthe process will remain in a common event ag (CEF) wait state.
# Use bit-shifts and an OR operation to create a bit mask from the bit numbers. $ The SYS$ASCEFC call creates the relationship of the named event ag
cluster, the specied range of common event ags, and the process. It also creates the event ag cluster, if necessary.
% The SYS$DACEFC call disassociates the specied event ag cluster from the
COLUMBIA process.
& In process ENDEAVOUR, the argument EFCname in the SYS$ASCEFC
system service call is a pointer to the string descriptor containing the name to be assigned to the event ag cluster; in this example, the cluster is named ENTERPRISE and was created by process COLUMBIA. While COLUMBIA mapped this cluster as cluster 2, this service call associates this name with cluster 3, event ags 96 through 127. Cooperating processes ENDEAVOUR, ATLANTIS, and DISCOVERY must use the same character string name to refer to this cluster.
The continuation of process COLUMBIA depends on (unspecied) work
done by processes ENDEAVOUR, ATLANTIS, and DISCOVERY. The SYS$WFLAND system service call species a mask indicating the event ags that must be set before process COLUMBIA can continue. The mask in this example (binary 1110) indicates that the second, third, and fourth ags in the cluster must be set. Process ENDEAVOUR sets the second event ag in the event ag cluster longword, using the SYS$SETEF system service call.
( Process ATLANTIS associates with the cluster, but instead of referring to
it as cluster 2, it refers to it as cluster 3 (with event ags in the range 96 through 127). Thus, when process ATLANTIS sets the event ag, it must bias the ag for the particular event ag cluster longword.
) Process DISCOVERY associates with the cluster, waits for an event ag set
Synchronizing Data Access and Program Operations 6.8 Using Event Flags
Common event ags are often used for communicating between a parent process and a created subprocess. In the following example, REPORT.FOR creates a subprocess to execute REPORTSUB.FOR, which performs a number of operations. After REPORTSUB.FOR performs its rst operation, the two processes can perform in parallel. REPORT.FOR and REPORTSUB.FOR use the common event ag cluster named JESSIER to communicate. REPORT.FOR associates the cluster name with a common event ag cluster, creates a subprocess to execute REPORTSUB.FOR and then waits for REPORTSUB.FOR to set the rst event ag in the cluster. REPORTSUB.FOR performs its rst operation, associates the cluster name JESSIER with a common event ag cluster, and sets the rst ag. From then on, the processes execute concurrently. REPORT.FOR . . . ! Associate common event flag cluster STATUS = SYS$ASCEFC (%VAL(64), 2 JESSIER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Create subprocess to execute concurrently MASK = IBSET (MASK,0) STATUS = LIB$SPAWN (RUN REPORTSUB, ! Image 2 INPUT.DAT, ! SYS$INPUT 2 OUTPUT.DAT, ! SYS$OUTPUT 2 MASK IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Wait for response from subprocess. STATUS = SYS$WAITFR (%VAL(64)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) . . . REPORTSUB.FOR . . . ! Do operations necessary for ! continuation of parent process. . . . ! Associate common event flag cluster STATUS = SYS$ASCEFC (%VAL(64), 2 JESSIER,,) IF (.NOT. STATUS) 2 CALL LIB$SIGNAL (%VAL(STATUS)) ! Set flag for parent process to resume STATUS = SYS$SETEF (%VAL(64)) . . .
Synchronizing Data Access and Program Operations 6.9 Synchronizing System Services Operations
The W at the end of the system service name indicates the synchronous version of the service. The asynchronous version of a system service queues a request and immediately returns control to your program pending the completion of the request. You can perform other operations while the system service executes. To avoid data corruptions, you should not attempt any read or write access to any of the buffers or itemlists referenced by the system service call prior to the completion of the asynchronous portion of the system service call. Further, no self-referential or self-modifying itemlists should be used. Typically, you pass an event ag and a status block to an asynchronous system service. When the system service completes, it sets the event ag and places the nal status of the request in the status block. Use the SYS$SYNCH system service to ensure that the system service has completed. You pass to SYS$SYNCH the event ag and status block that you passed to the asynchronous system service; SYS$SYNCH waits for the event ag to be set and then examines the status block to be sure that the system service rather than some other program set the event ag. If the status block is still zero, SYS$SYNCH waits until the status block is lled. The following example shows the use of the SYS$GETJPI system service: ! Data structure for SYS$GETJPI . . . INTEGER*4 STATUS, 2 FLAG, 2 PID_VALUE ! I/O status block STRUCTURE /STATUS_BLOCK/ INTEGER*2 JPISTATUS, 2 LEN INTEGER*4 ZERO /0/ END STRUCTURE RECORD /STATUS_BLOCK/ IOSTATUS . . . ! Call SYS$GETJPI and wait for information STATUS = LIB$GET_EF (FLAG) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS))
Synchronizing Data Access and Program Operations 6.9 Synchronizing System Services Operations
STATUS = SYS$GETJPI (%VAL(FLAG), 2 PID_VALUE, 2 , 2 NAME_BUF_LEN, 2 IOSTATUS, 2 ,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) . . . STATUS = SYS$SYNCH (%VAL(FLAG), 2 IOSTATUS) IF (.NOT. IOSTATUS.JPISTATUS) THEN CALL LIB$SIGNAL (%VAL(IOSTATUS.JPISTATUS)) END IF END The synchronous version of a system service acts as if you had used the asynchronous version followed immediately by a call to SYS$SYNCH; however, it behaves this way only if you specify a status block. If you omit the status block, the result is as though you called the asynchronous version followed by a call to SYS$WAITFR. Regardless of whether you use the synchronous or asynchronous version of a system service, if you omit the efn argument, the service uses event ag 0.
7
Synchronizing Access to Resources
This chapter describes the use of the lock manager to synchronize access to shared resources and contains the following sections: Section 7.1 describes how the lock manager synchronizes processes to a specied resource. Section 7.2 describes the concepts of resources and locks. Section 7.3 describes how to use the SYS$ENQ and SYS$ENQW system services to queue lock requests. Section 7.4 describes specialized features of locking techniques. Section 7.5 describes how to use the SYS$DEQ system service to dequeue the lock. Section 7.6 describes how applications can perform local buffer caching. Section 7.7 presents a code example of how to use lock management services.
To synchronize access to resources, the lock management services provide a mechanism that allows processes to wait in a queue until a particular resource is available. The lock manager does not ensure proper access to the resource; rather, the programs must respect the rules for using the lock manager. The rules required for proper synchronization to the resource are as follows: The resource must always be referred to by an agreed-upon name. Access to the resource is always accomplished by queuing a lock request with the SYS$ENQ or SYS$ENQW system service. All lock requests that are placed in a wait queue must wait for access to the resource.
Synchronizing Access to Resources 7.1 Synchronizing Operations with the Lock Manager
A process can choose to lock a resource and then create a subprocess to operate on this resource. In this case, the program that created the subprocess (the parent program) should not exit until the subprocess has exited. To ensure that the parent program does not exit before the subprocess, specify an event ag to be set when the subprocess exits (use the completion-efn argument of LIB$SPAWN). Before exiting from the parent program, use SYS$WAITFR to ensure that the event ag is set. (You can suppress the logout message from the subprocess by using the SYS$DELPRC system service to delete the subprocess instead of allowing the subprocess to exit.) Table 71 summarizes the lock manager services. Table 71 Lock Manager Services
Routine SYS$ENQ(W) SYS$DEQ Description Queues a new lock or lock conversion on a resource Releases locks and cancels lock requests
The lock management services compare the lock mode of the newly requested lock to the mode of other locks with the same resource name. New locks are granted in the following instances: If no other process has a lock on the resource. If another process has a lock on the resource and the mode of the new request is compatible with the existing lock.
Processes can also use the SYS$ENQ system service to change the lock mode of a lock. This is called a lock conversion.
Record
Record
Record
Record
Record
Item
Item
Item
Item
Item
Item
Item
Item
Item
Item
Item
Item
ZK0373GE
The processes that request locks on the database shown in Figure 71 may lock the whole database, an area in the database, a record, or a single item. Locking the entire database is considered locking at a coarse granularity; locking a single item is considered locking at a ne granularity. In this example, overall access to the database can be represented by a root resource name. Access either to areas in the database or records within areas can be represented by sublocks. Root resources consist of the following: Resource domain Resource name Access mode
Subresources consist of the following: Parent resource Resource name Access mode
Synchronizing Access to Resources 7.2 Concepts of Resources and Locks 7.2.2 Resource Domains
Because resource names are arbitrary names chosen by applications, one application may interfere (either intentionally or unintentionally) with another application. Unintentional interference can be easily avoided by careful design, such as by using a registered facility name as a prex for all root resource names used by an application. Intentional interference can be prevented by using resource domains. A resource domain is a namespace for root resource names and is identied by a number. Resource domain 0 is used as a system resource domain. Usually, other resource domains are used by the UIC group corresponding to the domain number. By using the SYS$SET_RESOURCE_DOMAIN system service, a process can gain access to any resource domain subject to normal operating system access control. By default, each resource domain allows read, write, and lock access by members of the corresponding UIC group. See the HP OpenVMS Guide to System Security for more information about access control.
For two resources to be considered the same, these four parts must be identical for each resource. The name specied by the process represents the resource being locked. Other processes that need to access the resource must refer to it using the same name. The correlation between the name and the resource is a convention agreed upon by the cooperating processes. The access mode is determined by the callers access mode unless a less privileged mode is specied in the call to the SYS$ENQ system service. Access modes, their numeric values, and their symbolic names are discussed in the HP OpenVMS Calling Standard. The default resource domain is selected by the UIC group number for the process. You can access the system domain by setting the LCK$M_SYSTEM when you request a new root lock. Other domains can be accessed using the optional RSDM_ID parameter to SYS$ENQ. You need the SYSLCK user privilege to request systemwide locks from user or supervisor mode. No additional privilege is required to request systemwide locks from executive or kernel mode. When a lock request is queued, it can specify the identication of a parent lock, at which point it becomes a sublock (see Section 7.4.8). However, the parent lock must be granted, or the lock request is not accepted. This enables a process to lock a resource at different degrees of granularity.
Synchronizing Access to Resources 7.2 Concepts of Resources and Locks 7.2.4 Choosing a Lock Mode
The mode of a lock determines whether the resource can be shared with other lock requests. Table 72 describes the six lock modes. Table 72 Lock Modes
Mode Name LCK$K_NLMODE Meaning Null mode. This mode grants no access to the resource. The null mode is typically used either as an indicator of interest in the resource or as a placeholder for future lock conversions. Concurrent read. This mode grants read access to the resource and allows sharing of the resource with other readers. The concurrent read mode is generally used either to perform additional locking at a ner granularity with sublocks or to read data from a resource in an unprotected fashion (allowing simultaneous writes to the resource). Concurrent write. This mode grants write access to the resource and allows sharing of the resource with other writers. The concurrent write mode is typically used to perform additional locking at a ner granularity, or to write in an unprotected fashion. Protected read. This mode grants read access to the resource and allows sharing of the resource with other readers. No writers are allowed access to the resource. This is the traditional share lock. Protected write. This mode grants write access to the resource and allows sharing of the resource with users at concurrent read mode. No other writers are allowed access to the resource. This is the traditional update lock. Exclusive. The exclusive mode grants write access to the resource and prevents the sharing of the resource with any other readers or writers. This is the traditional exclusive lock.
LCK$K_CRMODE
LCK$K_CWMODE
LCK$K_PRMODE
LCK$K_PWMODE
LCK$K_EXMODE
Note that the concurrent write and protected read modes are considered to be of the same level.
Mode of Currently Granted Locks NL Yes Yes Yes Yes Yes Yes CR Yes Yes Yes Yes Yes No CW Yes Yes Yes No No No PR Yes Yes No Yes No No PW Yes Yes No No No No EX Yes No No No No No
A queue is associated with each of the three states (see Figure 72). When you request a new lock, the lock management services rst determine whether the resource is currently known (that is, if any other processes have locks on that resource). If the resource is new (that is, if no other locks exist on the resource), the lock management services create an entry for the new resource and the requested lock. If the resource is already known, the lock management services determine whether any other locks are waiting in either the conversion or the waiting queue. If other locks are waiting in either queue, the new lock request is queued at the end of the waiting queue. If both the conversion and waiting queues are empty, the lock management services determine whether the new lock is compatible with the other granted locks. If the lock request is compatible, the lock is granted; if it is not compatible, it is placed in the waiting queue. You can use a ag bit to direct the lock management services not to queue a lock request if one cannot be granted immediately.
GRANTED
Compatible Conversions
Conversions Granted
WAITING
ZK0374GE
Synchronizing Access to Resources 7.2 Concepts of Resources and Locks 7.2.8 Deadlock Detection
A deadlock occurs when any group of locks are waiting for each other in a circular fashion. In Figure 73, three processes have queued requests for resources that cannot be accessed until the current locks held are dequeued (or converted to a lower lock mode). Figure 73 Deadlock A B
ZK0375GE If the lock management services determine that a deadlock exists, the services choose a process to break the deadlock. The chosen process is termed the victim. If the victim has requested a new lock, the lock is not granted; if the victim has requested a lock conversion, the lock is returned to its old lock mode. In either case, the status code SS$_DEADLOCK is placed in the lock status block. Note that granted locks are never revoked; only waiting lock requests can receive the status code SS$_DEADLOCK. Note Programmers must not make assumptions regarding which process is to be chosen to break a deadlock.
These methods of synchronization are identical to the synchronization techniques used with the SYS$QIO system services (described in Chapter 23).
15 Condition value
The status code is placed in the lock status block either when the lock is granted or when errors occur in granting the lock. The uses of the lock value block are described in Section 7.6.1.
Synchronizing Access to Resources 7.4 Advanced Locking Techniques 7.4.5 Blocking ASTs
In some applications that use the lock management services, a process must know whether it is preventing another process from locking a resource. The lock management services inform processes of this through the use of blocking ASTs. When the lock prevents another lock from being granted, the blocking routine is delivered as an AST to the process. Blocking ASTs are not delivered when the state of the lock is either Conversion or Waiting. To enable blocking ASTs, the blkast argument of the SYS$ENQ system service must contain the address of a blocking AST service routine. The astprm argument passes a parameter to the blocking AST. For more information about ASTs and AST service routines, see Chapter 8. Some uses of blocking ASTs are also described in that chapter.
A procedure normally needs an exclusive (or protected write) mode lock while writing data. The procedure should not keep the resource exclusively locked all the time, however, because writing might not always be necessary. Maintaining an exclusive or protected write mode lock prevents other processes from accessing the resource. Lock conversions allow a process to request a low-level lock at rst and convert the lock to a high-level lock mode (protected write mode, for example) only when it needs to write data. Some applications of locks require the use of the lock value block. If a version number or other data is maintained in the lock value block, you need to maintain at least one lock on the resource so that the value block is not lost. In this case, processes convert their locks to null locks, rather than dequeuing them when they have nished accessing the resource. To improve performance in some applications, all resources that might be locked are locked with null locks during initialization. You can convert the null locks to higher-level locks as needed. Usually a conversion request is faster than a new lock request because the necessary data structures have already been built. However, maintaining any lock for the life of a procedure uses system dynamic memory. Therefore, the approach of creating all necessary locks as null locks and converting them as needed improves performance at the expense of increased storage requirements. Note If you specify the ag bit LCK$M_NOQUEUE on a lock conversion and the conversion fails, the new blocking AST address and parameter specied in the conversion request replace the blocking AST address and parameter specied in the previous SYS$ENQ request.
NL No No No No No No
CR Yes No No No No No
The following paragraphs describe the use of parent locks. Assume that a number of processes need to access a database. The database can be locked at two levels: the le and individual records. For updating all the records in a le, locking the whole le and updating the records without additional locking is faster and more efcient. But for updating selected records, locking each record as it is needed is preferable. To use parent locks in this way, all processes request locks on the le. Processes that need to update all records must request protected write or exclusive mode locks on the le. Processes that need to update individual records request concurrent write mode locks on the le and then use sublocks to lock the individual records in protected write or exclusive mode.
Note that when protected write or exclusive mode locks are dequeued using the Dequeue Lock Request (SYS$DEQ) system service and the address of a lock value block is specied in the valblk argument, the contents of that lock value block are written to the resource lock value block.
The following is an example of dequeuing locks: #include <stdio.h> #include <descrip.h> #include <lckdef.h> /* Declare a lock status block */ struct lock_blk { unsigned short lkstat ,reserved; unsigned int lock_id; }lksb; . . . void read_updates(); unsigned int status, lkmode=LCK$K_CRMODE, lkid; $DESCRIPTOR(resnam,"STRUCTURE_1"); /* resource */ /* Queue a request for concurrent read mode lock */ status = SYS$ENQW(0, /* efn - event flag */ lkmode, /* lkmode - lock mode */ &lksb, /* lksb - lock status block */ 0, /* flags */ &resnam, /* resnam - name of resource */ 0, /* parid - lock id of parent */ &read_updates,/* astadr - AST routine */ 0, 0, 0, 0); if((status & 1) != 1) LIB$SIGNAL(status); . . . lkid = lksb.lock_id; status = SYS$DEQ( lkid, 0, 0, 0); if((status & 1) != 1) LIB$SIGNAL(status); } /* lkid - id of lock to be dequeued */
Synchronizing Access to Resources 7.6 Local Buffer Caching with the Lock Management Services
7.6.2.2 Buffer Caching To perform local buffer caching using blocking ASTs, processes do not convert their locks to null mode from protected read or exclusive mode when nished with the buffer. Instead, they receive blocking ASTs whenever another process attempts to lock the same resource in an incompatible mode. With this technique, processes are notied that their cached buffers are invalid as soon as a writer needs the buffer, rather than the next time the process tries to use the buffer.
Part II
Interrupts and Condition Handling
This part describes the use of asynchronous system traps (ASTs), and the use of condition-handling routines and services.
8
Using Asynchronous System Traps
This chapter describes the use of asynchronous system traps (ASTs). It contains the following sections: Section 8.1 provides an overview of AST routines. Section 8.2 provides information about declaring and queuing ASTs. Section 8.3 describes common asynchronous programming mistakes. Section 8.4 provides information about using system services for AST event and time delivery. Section 8.5 describes access modes for ASTs. Section 8.6 provides information about calling ASTs. Section 8.7 provides information about delivering ASTs. Section 8.8 describes ASTs and process wait states. Section 8.9 presents code examples of how to use AST services.
The system services that use the AST mechanism accept as an argument the address of an AST service routine, that is, a routine to be given control when the event occurs. Table 82 shows some of the services that use ASTs. Table 82 System Services That Use ASTs
System Service SYS$DCLAST SYS$ENQ SYS$GETDVI SYS$GETJPI SYS$GETSYI SYS$QIO SYS$SETIMR SYS$SETPRA SYS$UPDSEC Task Performed Declare AST Enqueue Lock Request Get Device/Volume Information Get Job/Process Information Get Systemwide Information Queue I/O Request Set Timer Set Power Recovery AST Update Section File on Disk
The following sections describe in more detail how ASTs work and how to use them.
Using Asynchronous System Traps 8.2 Declaring and Queuing ASTs 8.2.1 Reentrant Code and ASTs
Compiled code that is generated by HP compilers is reentrant. Furthermore, HP compilers normally generate AST routine local data that is reentrant. Data that is shared static, shared external data, Fortran COMMON, and group or system global section data are not inherently reentrant, and usually require explicit synchronization. Because the queuing mechanism for an AST does not provide for returning a function value or passing more than one argument, you should write an AST routine as a subroutine. This subroutine should use nonvolatile storage that is valid over the life of the AST. To establish nonvolatile storage, you can use the LIB$GET_VM run-time routine. You can also use a high-level languages storage keywords to create permanent nonvolatile storage. For instance, you can use the C languages keywords as follows: extern static routine malloc(). In some cases, a system service that queues an AST (for example, SYS$GETJPI) allows you to specify an argument for the AST routine . If you choose to pass the argument, the AST routine must be written to accept the argument. 8.2.1.1 The Call Frame When a routine is active under OpenVMS, it has available to it temporary storage on a stack, in a construct known as a stack frame, or call frame. Each time a subroutine call is made, another call frame is pushed onto the stack and storage is made available to that subroutine. Each time a subroutine returns to its caller, the subroutines call frame is pulled off the stack, and the storage is made available for reuse by other subroutines. Call frames therefore are nested. Outer call frames remain active longer, and the outermost call frame, the call frame associated with the main routine, is normally always available. A primary exception to this call frame condition is when an exit handler runs. With an exit handler running, only static data is available. The exit handler effectively has its own call frame. Exit handlers are declared with the SYS$DCLEXH system service. The use of call frames for storage means that all routine-local data is reentrant; that is, each subroutine has its own storage for the routine-local data. The allocation of storage that is known to the AST must be in memory that is not volatile over the possible interval the AST might be pending. This means you must be familiar with how the compilers allocate routine-local storage using the stack pointer and the frame pointer. This storage is valid only while the stack frame is active. Should the routine that is associated with the stack frame return, the AST cannot write to this storage without having the potential for some severe application data corruptions.
If there is shared data access with multiple readers, your application must be able to tolerate having a stale counter that allows frequent looping back and picking up a new value from the code.
Using Asynchronous System Traps 83
8.4 Using System Services for AST Event and Time Delivery
The following list presents system services and routines that are used to queue the AST routine that determines whether an AST is delivered after a specied event or time. Note that the system service (W) calls are synchronous. Synchronous system services can have ASTs, but the code blocks pending completion, when the AST is activated. EventThe following system routines allow you to specify an AST routine to be delivered when the system routine completes: LIB$SPAWNSignals when the subprocess has been created. SYS$ENQ and SYS$ENQWSignals when the resource lock is blocking a request from another process. SYS$GETDVI and SYS$GETDVIWIndicate that device information has been received.
Using Asynchronous System Traps 8.4 Using System Services for AST Event and Time Delivery
SYS$GETJPI and SYS$GETJPIWIndicate that process information has been received. SYS$GETSYI and SYS$GETSYIWIndicate that system information has been received. SYS$QIO and SYS$QIOWSignal when the requested I/O is completed. SYS$UPDSECSignals when the section le has been updated. SYS$ABORT_TRANS and SYS$ABORT_TRANSWSignal when a transaction is aborted. SYS$AUDIT_EVENT and SYS$AUDIT_EVENTWSignal when an event message is appended to the system security audit log le or send an alarm to a security operator terminal. SYS$BRKTHRU and SYS$BRKTHRU(W)Signal when a message is sent to one or more terminals. SYS$CHECK_PRIVILEGE and SYS$CHECK_PRIVILEGEWSignal when the caller has the specied privileges or identier. SYS$DNS and SYS$DNSWOn VAX systems, signal when client applications are allowed to store resource names and addresses. SYS$END_TRANS and SYS$END_TRANSWSignal an end to a transaction by attempting to commit it. SYS$GETQUI and SYS$GETQUIWSignal when information is returned about queues and the jobs initiated from those queues. SYS$START_TRANS and SYS$START_TRANSWSignal the start of a new transaction. SYS$SETCLUEVT and SYS$SETCLUEVTWSignal a request for notication when a VMScluster conguration event occurs. EventThe SYS$SETPRA system service allows you to specify an AST to be delivered when the system detects a power recovery. TimeThe SYS$SETIMR system service allows you to specify a time for the AST to be delivered. TimeThe SYS$DCLAST system service delivers a specied AST immediately. This makes it an ideal tool for debugging AST routines.
If a program queues an AST and then exits before the AST is delivered, the AST is deleted before execution. If a process is hibernating when an AST is delivered, the AST executes, and the process then resumes hibernating. If a suspended process receives an AST, the execution of the AST depends on the AST mode and the mode at which the process was suspended, as follows: If the process was suspended from a SYS$SUSPEND call at supervisor mode, user-mode ASTs are executed as soon as the process is resumed. If more than one AST is delivered, they are executed in the order in which they were delivered. Supervisor-, executive-, and kernel-mode ASTs are executed upon delivery. If the process was suspended from a SYS$SUSPEND call at kernel mode, all ASTs are blocked and are executed as soon as the process is resumed.
Using Asynchronous System Traps 8.4 Using System Services for AST Event and Time Delivery
Generally, AST routines are used with the SYS$QIO or SYS$QIOW system service for handling Ctrl/C, Ctrl/Y, and unsolicited input.
struct { unsigned int lower, upper; }daytim; /* AST routine */ void time_ast(void); main() { unsigned int status; $DESCRIPTOR(timbuf,"0 ::10.00"); /* 10-second delta */ /* Convert ASCII format time to binary format */ status = SYS$BINTIM(&timbuf, &daytim); /* buffer containing ASCII time */ /* timadr (buffer to receive */ /* binary time) */
if ((status & 1) != 1) LIB$SIGNAL(status); else printf("Converting time to binary format...\n"); /* Set the timer */
(continued on next page)
if ((status & 1) != 1) LIB$SIGNAL(status); printf("Executing AST routine to perform wake up...\n"); # return; }
! The call to the SYS$SETIMR system service requests an AST at 10 seconds
from the current time. The daytim argument refers to the quadword, which must contain the time in system time (64-bit) format. For details on how this is accomplished, see Chapter 27. The astadr argument refers to TIME_AST, the address of the AST service routine. When the call to the system service completes, the process continues execution.
" The timer expires in 10 seconds and noties the system. The system
interrupts execution of the process and gives control to the AST service routine.
# The user routine TIME_AST handles the interrupt. When the AST routine
completes, it issues a RET instruction to return control to the program. The program resumes execution at the point at which it was interrupted.
Using Asynchronous System Traps 8.7 Delivering ASTs 8.7.1 The AST Service Routine
An AST service routine must be a separate procedure. The AST must use the standard call procedure, and the routine must return using a RET instruction. If the service routine modies any registers other than the standard scratch registers, it must set the appropriate bits in the entry mask so that the contents of those registers are saved. Because you cannot know when the AST service routine will begin executing, you must take care that when you write the AST service routine it does not modify any data or instructions used by the main procedure (unless, of course, that is its function). On entry to the AST service routine, the arguments shown in Table 83 are passed. Table 83 AST Arguments for VAX, Alpha, and I64 Systems
VAX System Arguments AST parameter R0 R1 PC PSL Alpha System Arguments AST parameter R0 R1 PC PS I64 System Arguments AST parameter 0 0 PC Synthesized Alpha PS
Registers R0 and R1, the program counter (PC), and the processor status longword (PSL) on VAX systems, or processor status (PS) on Alpha and I64 systems, and were saved when the process was interrupted by delivery of the AST. The AST parameter is an argument passed to the AST service routine so that it can identify the event that caused the AST. When you call a system service requesting an AST, or when you call the SYS$DCLAST system service, you can supply a value for the AST parameter. If you do not specify a value, the parameter defaults to 0. The following example illustrates an AST service routine. In this example, the ASTs are queued by the SYS$DCLAST system service; the ASTs are delivered to the process immediately so that the service routine is called following each SYS$DCLAST system service call. #include #include #include #include <stdio.h> <ssdef.h> <starlet.h> <lib$routines.h>
/* Declare the AST routine */ void astrtn ( int ); main() { unsigned int status, value1=1, value2=2;
/* Evaluate AST parameter */ switch (value) { case 1: printf("Executing AST routine with value 1...\n"); goto handler_1; break; case 2: printf("Executing AST routine with value 2...\n"); goto handler_2; break; default: printf("Error\n"); }; /* Handle first AST */ handler_1: . . . return; /* Handle second AST */ handler_2: . . . return; }
! The program calls the SYS$DCLAST AST system service twice to queue
ASTs. Both ASTs specify the AST service routine, ASTRTN. However, a different parameter is passed for each call.
" The rst action this AST routine takes is to check the AST parameter so
that it can determine if the AST being delivered is the rst or second one declared. The value of the AST parameter determines the ow of execution. If a number of different values are determining a number of different paths of execution, HP recommends that you use the VAX MACRO instruction CASE.
Further, before kernel threads, user mode code could safely access data that it knows is only used by other user mode, non-AST level routines without needing any synchronization mechanisms. The underlying assumption is that only one thread of user mode execution exists. If the current code stream is accessing the data, then by implication no other code stream can be accessing it. After kernel threads, this assumed behavior of AST routines and user mode code is no longer valid. Multiple user-mode, non-AST level code streams can be executing at the same time. The use of any data that can be accessed by multiple user-mode code streams must be modied to become synchronized using the loadlocked (LDx_L) and store-conditional (STx_C) instructions, or by using some other synchronization mechanism. Kernel threads assumes that multiple threads of execution can be active at one time and includes outer mode ASTs. Within any given kernel thread, outer mode ASTs will still be delivered serially. Also, the kernel thread model allows any combination of multiple outer mode threads, or multiple outer mode ASTs. However, outer-mode AST routines, as well as non-AST outer-mode code, has to be aware that any data structure that can be accessed concurrently by outermode code, or by any other outer-mode AST must be protected by some form of synchronization. Before kernel threads, same-mode ASTs executed in the order that they were queued. After kernel threads and within a single kernel thread, that still is true. However, it is not true process-wide. If two ACBs are queued to two different KTBs, whichever is scheduled rst, executes rst. There is no attempt to schedule kernel threads in such a way to correctly order ASTs that have been queued to them. The ASTs execute in any order and can, in fact, execute concurrently.
After kernel threads, in contrast to the preceeding list, kernel threads deliver any non thread-safe inner mode ASTs to the kernel thread that already owns the semaphore. If no thread currently owns the semaphore when the AST is queued, then the semaphore is acquired in SCH$QAST, and the owner is set to the target kernel thread for that AST. Subsequently queued ASTs see that thread as the semaphore owner and are delivered to that thread. This allows the PALcode and the hardware architecture to process all the AST preemption and ordering rules.
8.8.2 Hibernation
A process can place itself in a wait state with the Hibernate (SYS$HIBER) system service. This state can be interrupted for the delivery of an AST. When the AST service routine completes execution, the process continues hibernation. The process can, however, wake itself in the AST service routine or be awakened either by another process or as the result of a timer-scheduled wakeup request. Then, it continues execution when the AST service routine completes. Process suspension is another form of wait; however, a suspended process cannot be interrupted by an AST. Process hibernation and suspension are described in Chapter 4.
Using Asynchronous System Traps 8.8 ASTs and Process Wait States 8.8.3 Resource Waits and Page Faults
When a process is executing an image, the system can place the process in a wait state until a required resource becomes available, or until a page in its virtual address space is paged into memory. These waits, which are generally transparent to the process, can also be interrupted for the delivery of an AST.
9
Condition-Handling Routines and Services
This chapter describes the OpenVMS Condition Handling facility and contains the following sections: Section 9.1 gives an overview of run-time errors. Section 9.2 gives an overview of the OpenVMS Condition Handling facility, presenting condition-handling terminology and functionality. Section 9.3 describes VAX, Alpha, and I64 system exceptions, arithmetic exceptions, and unaligned access traps on Alpha and I64 systems. Section 9.4 describes how run-time library routines handle exceptions. Section 9.5 describes the condition value eld and the testing and modifying of values. Section 9.6 describes the exception dispatcher. Section 9.7 describes the argument list that is passed to a condition handler. Section 9.8 describes signaling. Section 9.9 describes types of condition handlers. Section 9.10 describes types of actions performed by condition handlers. Section 9.11 describes messages and how to use them. Section 9.12 describes how to write a condition handler. Section 9.13 describes how to debug a condition handler. Section 9.14 describes several run-time library routines that can be established as condition handlers. Section 9.15 describes how to establish, write, and debug an exit handler.
Condition-Handling Routines and Services 9.2 Overview of the OpenVMS Condition Handling Facility
condition An informational state that exists when an exception occurs. Condition is a more general term than exception; a condition implies either a hardware exception or a software-raised condition. Often, the term condition is preferred because the term exception implies an error. Section 9.3.1 further denes the differences between exceptions and conditions. condition handling When a condition is detected during the execution of a routine, a signal can be raised by the routine. The routine is then permitted to respond to the condition. The routines response is called handling the condition. On VAX systems, an address of 0 in the rst longword of a procedure call frame or in an exception vector indicates that a condition handler does not exist for that call frame or vector. On Alpha systems, the handler valid ag bit in the procedure descriptor is cleared to indicate that a condition handler does not exist. On I64 systems, the handler present ag bit in the frame ags eld of the invocation context block indicates the presence of a condition handler. The condition handlers are themselves routines; they have their own call frames. Because they are routines, condition handlers can have condition handlers of their own. This allows condition handlers to eld exceptions that might occur within themselves in a modular fashion. On VAX systems, a routine can enable a condition handler by placing the address of the condition handler in the rst longword of its stack frame. On Alpha and I64 systems, the association of a handler with a procedure is static and must be specied at the time a procedure is compiled (or assembled). Some languages that lack their own exception-handling syntax, however, may support emulation of dynamic specied handlers by means of built-in routines. If you determine that a program needs to be informed of particular exceptions so it can take corrective action, you can write and specify a condition handler. This condition handler, which receives control when any exception occurs, can test for specic exceptions. If an exception occurs and you have not specied a condition handler, the default condition handler established by the operating system is given control. If the exception is a fatal error, the default condition handler issues a descriptive message and causes the image that incurred the exception to exit. To declare or enable a condition handler, use the following system services: Set Exception Vector (SYS$SETEXV) Unwind from Condition Handler Frame (SYS$UNWIND) Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH)
Parallel mechanisms exist for uniform dispatching of hardware and software exception conditions. Exceptions that are detected and signaled by hardware transfer control to an exception service routine in the executive. Softwaredetected exception conditions are generated by calling the run-time library routines LIB$SIGNAL or LIB$STOP. Hardware- and software-detected exceptions eventually execute the same exception dispatching code. Therefore, a condition handler may handle an exception condition generated by hardware or by software identically.
Condition-Handling Routines and Services 9.2 Overview of the OpenVMS Condition Handling Facility
The Set Exception Vector (SYS$SETEXV) system service allows you to specify addresses for a primary exception handler, a secondary exception handler, and a last-chance exception handler. You can specify handlers for each access mode. The primary exception vector is reserved for the debugger. In general, you should avoid using these vectored handlers unless absolutely necessary. If you use a vectored handler, it must be prepared for all exceptions occurring in that access mode.
You can associate a condition handler for the currently executing routine by specifying an address pointing to the handler, either in the routines stack frame on VAX systems or in one of the exception vectors. (The Macro-32 compilers for OpenVMS Alpha and I64 systems generate the appropriate code from this VAX instruction to establish a dynamic condition handler.) On VAX systems, the high-level language programmer can call the common run-time library routine LIB$ESTABLISH (see the HP OpenVMS RTL Library (LIB$) Manual), using the name of the handler as an argument. LIB$ESTABLISH returns as a function value either the address of the former handler established for the routine or 0 if no handler existed. On VAX systems, the new condition handler remains in effect for your routine until you call LIB$REVERT or control returns to the caller of the caller of LIB$ESTABLISH. Once this happens, you must call LIB$ESTABLISH again if the same (or a new) condition handler is to be associated with the caller of LIB$ESTABLISH. On VAX systems, some languages provide access to condition handling as part of the language. You can use the ON ERROR GOTO statement in BASIC and the ON statement in PL/I to dene condition handlers. If you are using a language that does provide access to condition handling, use its language mechanism rather than LIB$ESTABLISH. Each procedure can declare a condition handler.
Condition-Handling Routines and Services 9.2 Overview of the OpenVMS Condition Handling Facility
When the routine signals an exception, the OpenVMS Condition Handling facility calls the condition handler associated with the routine. See Section 9.8 for more information about exception vectors. Figure 95 shows a sample stack scan for a condition handler. The following HP Fortran program segment establishes the condition handler ERRLOG. Because the condition handler is used as an actual argument, it must be declared in an EXTERNAL statement. INTEGER*4 OLD_HANDLER EXTERNAL ERRLOG . . . OLD_HANDLER = LIB$ESTABLISH (ERRLOG) LIB$ESTABLISH returns the address of the previous handler as its function value. If only part of a program unit requires a special condition handler, you can reestablish the original handler by invoking LIB$ESTABLISH and specifying the saved handler address as follows: CALL LIB$ESTABLISH (OLD_HANDLER) The run-time library provides several condition handlers and routines that a condition handler can call. These routines take care of several common exception conditions. Section 9.14 describes these routines. On Alpha and I64 systems, LIB$ESTABLISH and LIB$REVERT are not supported, though a high-level language may support them for compatibility. (Table 95 lists other run-time library routines supported and not supported on Alpha systems.) On VAX systems, remove an established condition-handler routine On VAX systems using LIB$REVERT, you can remove a condition handler from a routines stack frame by setting the frames handler address to 0. If your high-level language provides condition-handling statements, you should use them rather than LIB$REVERT. On VAX systems, enable or disable the detection of arithmetic hardware exceptions On VAX systems, using run-time library routines, you can enable or disable the signaling of oating point underow, integer overow, and decimal overow, which are detected by the VAX hardware. On I64 systems, allows access to the Floating Point Status Register, which contains dynamic control and status information for oating-point operations. On I64 systems, the services SYS$IEEE_SET_FP_CONTROL, SYS$IEEE_ SET_ROUNDING_MODE, and SYS$IEEE_SET_PRECISION_MODE provide the supported mechanisms to access and modify the Floating Point Status Register, and to modify the oating point rounding and precision modes respectively. Volume 1 of the Intel Itanium Architecture Software Developers Manual contains a thorough description of the Floating Point Status Register. Signal a condition When the hardware detects an exception, such as an integer overow, a signal is raised at that instruction. A routine may also raise a signal by calling LIB$SIGNAL or LIB$STOP. Signals raised by LIB$SIGNAL allow the condition handler either to terminate or to resume the normal ow of the
Condition-Handling Routines and Services 9.2 Overview of the OpenVMS Condition Handling Facility
routine. Signals raised by LIB$STOP require termination of the operation that raises the condition. The condition handler will not be allowed to continue from the point of call to LIB$STOP. Display an informational message The system establishes default condition handlers before it calls the main program. Because these default condition handlers provide access to the systems standard error messages, the standard method for displaying a message is by signaling the severity of the condition: informational, warning, or error. See Section 9.5 for the denition of the severity eld of a condition vector. The system default condition handlers resume execution of the instruction after displaying the messages associated with the signal. If the condition value indicates a severe condition, then the image exits after the message is displayed. Display a stack traceback on errors The default operations of the LINK and RUN commands provide a systemsupplied handler (the traceback handler) to print a symbolic stack traceback. The traceback shows the state of the routine stack at the point where the condition occurred. The traceback information is displayed along with the messages associated with the signaled condition. Compile customer-dened messages The Message utility allows you to dene your own exception conditions and the associated messages. Message source les contain the condition values and their associated messages. See Section 9.11.3 for a complete description of how to dene your own messages. Unwind the stack A condition handler can cause a signal to be dismissed and the stack to be unwound to the establisher or caller of the establisher of the condition handler when it returns control to the OpenVMS Condition Handling facility (CHF). During the unwinding operation, the CHF scans the stack. If a condition handler is associated with a frame, the system calls that handler before removing the frame. Calling the condition handlers during the unwind allows a routine to perform cleanup operations specic to a particular application, such as recovering from noncontinuable errors or deallocating resources that were allocated by the routine (such as virtual memory, event ags, and so forth). See Section 9.12.3 for a description of the SYS$UNWIND system service. Log error messages to a le The Put Message (SYS$PUTMSG) system service permits any user-written handler to include a message in a listing le. Such message logging can be separate from the default messages the user receives. See Section 9.11 for a detailed description of the SYS$PUTMSG system service. On Alpha or I64 systems, perform a nonlocal GOTO unwind. A GOTO unwind operation is a transfer of control that leaves one procedure invocation and continues execution in a prior (currently active) procedure. This unied GOTO operation gives unterminated procedure invocations the opportunity to clean up in an orderly way.
Hardware-generated exceptions always result in conditions that require special action if program execution is to continue. Software-generated exceptions may result in error or warning conditions. These conditions and their message descriptions are documented in the online Help Message utility and in the OpenVMS system messages documentation. To access online message descriptions, use the HELP/MESSAGE command. More information on using the Help Message utility is available in OpenVMS System Messages: Companion Guide for Help Message Users. That document describes only those messages that occur when the system is not fully operational and you cannot access Help Message. Some examples of exception conditions are as follows: Arithmetic exception condition in a user-written program detected and signaled by hardware (for example, oating-point overow) Error in a user argument to a run-time library routine detected by software and signaled by calling LIB$STOP (for example, a negative square root) Error in a run-time library language-support routine, such as an I/O error or an error in a data-type conversion RMS success condition stating that the record is already locked RMS success condition stating that the created le superseded an existing version
There are two standard methods for an HP- or user-written routine to indicate that an exception condition has occurred: Return a completion code to the calling program using the function value mechanism Most general-purpose run-time library routines indicate exception conditions by returning a condition value in R0 (R8 for I64). The calling program then tests bit 0 of R0 (R8 for I64) for success or failure. This method allows better programming structure, because the ow of control can be changed explicitly after the return from each call. If the actual function value returned is greater than 32 bits, then use both R0 and R1 (R8, R9 for I64). On Alpha systems, if the actual function returned is a oating-point value, the oating-point value is returned in F0, or F0 and F1. On I64 systems, if the actual function returned is a oating-point value, the oating-point value is returned in F8, F9. Signal the exception condition A condition can be signaled by calling the RTL routine LIB$SIGNAL or LIB$STOP. Any condition handlers that were enabled are then called by the CHF. See Figure 95 for the order in which CHF invokes condition handlers. Exception conditions raised by hardware or software are signaled to the routine identically.
SS$_ARTRES2
Trap. Reserved arithmetic trap. None. Trap. Stack invalid during attempt to deliver an AST.
SS$_ASTFLT
Type: Description:
1 On 2 On
VAX systems, this condition is generated by hardware. Alpha systems, this condition is generated by software.
5. 6.
SS$_BREAK
Fault. Breakpoint instruction encountered. None. Trap. Change mode to supervisor instruction encountered.4 Change mode code. The possible values are 32,768 through 32,767. Trap. Change mode to user instruction encountered.4 Change mode code. The possible values are 32,768 through 32,767. Fault. Compatibility-mode exception. This exception condition can occur only when executing in compatibility mode.5 Type of compatibility exception. The possible values are as follows: 0 = Reserved instruction execution 1 = BPT instruction executed 2 = IOT instruction executed 3 = EMT instruction executed 4 = TRAP instruction executed 5 = Illegal instruction executed 6 = Odd address fault 7 = TBIT trap.
SS$_CMODSUPR
SS$_CMODUSER
SS$_COMPAT1
1 On
PC and PSL (or PS) normally included in the signal array are not included in this argument list. The stack pointer of the access mode receiving this exception is reset to its initial value.
4 If a change mode handler has been declared for user or supervisor mode with the Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH) system service, that routine receives control when the associated trap occurs. 5 If a compatibility-mode handler has been declared with the Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH) system service, that routine receives control when this fault occurs.
3 The
Explanation Type: Description: Arguments: Trap. Decimal overow. None. Trap. Floating/decimal divide-by-zero. None. Fault. Floating divide-by-zero. None. Trap. Floating inexact result. None. Trap. Floating inexact result fault. None. Trap. Floating invalid operation. None. Trap. Floating invalid operation fault. None. Trap. Floating-point overow. None. Fault. Floating-point overow fault. None. Trap. Floating-point underow. None. Fault. Floating-point underow fault. None. Trap. Integer divide-by-zero. None.
SS$_FLTDIV
1 2 6
SS$_FLTDIV_F
SS$_FLTINE
SS$_FLTINE_F
SS$_FLTINV
SS$_FLTINV_F
SS$_FLTOVF1
2 6
SS$_FLTOVF_F
SS$_FLTUND
1 2 6
SS$_FLTUND_F
SS$_INTDIV1
1 On 2 On 6 On
VAX systems, this condition is generated by hardware. Alpha systems, this condition is generated by software. I64 systems, this condition is generated by hardware.
Explanation Type: Description: Arguments: Trap. Integer overow. None. Fault. Opcode reserved for customer fault. None. Fault. Opcode reserved for HP fault. None. Fault. Read error occurred during an attempt to read a faulted page from disk.
SS$_OPCCUS
SS$_OPCDEC
SS$_PAGRDERR
1.
Translation not valid reason. This is a mask with the following format: Bit <0> = 0 Bit <1> = page table entry reference 0 = specied virtual address not valid 1 = associated page table entry not valid Bit <2> = intended access 0 = read 1 = modify
2. SS$_RADRMOD1 Type: Description: Arguments: SS$_ROPRAND Type: Description: Arguments: SS$_SSFAIL Type: Description: Arguments:
Fault. Attempt to use a reserved addressing mode. None. Fault. Attempt to use a reserved operand. None. Fault. System service failure (when system service failure exception mode is enabled). Conditon occured as result of the use of the obsolete feature that was enabled by using $SETSFM service. Status return from system service (R0). (The same value is in R0 of the mechanism array.)
SS$_SUBRNG1
1 On 2 On
VAX systems, this condition is generated by hardware. Alpha systems, this condition is generated by software.
Explanation Type: Description: Arguments: Fault. Trace bit is pending following an instruction. None.
1 On
Arguments:
SS$_BREAK_APPL
SS$_DEBUG_FAULT
Type:
Arguments: 1. Reason mask = Bit <0> Execute exception - interruption is associated with an instruction fetch Bit <2> Write exception - interruption is associated with a write operation. Bit <19> Register Stack - interruption is associated with a mandatory RSE ll or spill. 2. Va = The address of the data being referenced.
Change-Mode and Compatibility-Mode Handlers Two types of hardware exception can be handled in a way different from the normal condition-handling mechanism described in this chapter. The two types of hardware exception are as follows: Traps caused by change-mode-to-user or change-mode-to-supervisor instructions On VAX systems, compatibility mode faults
You can use the Declare Change Mode or Compatibility Mode Handler (SYS$DCLCMH) system service to establish procedures to receive control when one of these conditions occurs. The SYS$DCLCMH system service is described in the HP OpenVMS System Services Reference Manual.
Comment
Generated for most Alpha arithmetic exceptions (see Section 9.3.3) No VAX equivalent
No Alpha system equivalent No Alpha system equivalent Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) Replaced by SS$_HPARITH on Alpha (see Section 9.3.3) No Alpha equivalent No Alpha equivalent No Alpha equivalent No Alpha equivalent
Alpha systems, this condition may be generated by software. I64 systems, this condition may be generated by software.
Condition-Handling Routines and Services 9.3 Exception Conditions 9.3.3 Arithmetic Exceptions
On VAX and I64 systems, the architecture ensures that arithmetic exceptions are reported synchronously; that is, an arithmetic instruction that causes an exception (such as an overow) enters any exception handlers immediately, and subsequent instructions are not executed. The program counter (PC) reported to the exception handler is that of the failing arithmetic instruction. This allows application programs, for example, to resume the main sequence, with the failing operation being emulated or replaced by some equivalent or alternative set of operations. On Alpha systems, arithmetic exceptions are reported asynchronously; that is, implementations of the architecture can allow a number of instructions (including branches and jumps) to execute beyond that which caused the exception. These instructions may overwrite the original operands used by the failing instruction, thus causing the loss of information that is integral to interpreting or rectifying the exception. The program counter (PC) reported to the exception handler is not that of the failing instruction, but rather is that of some subsequent instruction. When the exception is reported to an applications exception handler, it may be impossible for the handler to x up the input data and restart the instruction. Because of this fundamental difference in arithmetic exception reporting, Alpha systems dene a new condition code, SS$_HPARITH, to indicate most arithmetic exceptions. Thus, if your application contains a condition-handling routine that performs processing when an integer overow exception occurs, on VAX systems the application expects to receive the SS$_INTOVF condition code. On Alpha systems, this exception may be indicated by the condition code SS$_HPARITH. It is possible, however, that some higher level languages using RTL routines, for example, LIB$ routines, might convert the SS$_HPARITH into a more precise exception code such as SS$_INTOVF, or generate a precise exception code directly in an arthmetic emulation routine. If a SS$_HPARITH is received as the condition code, it indicates an imprecise Alpha system exception. If a precise integer overow is received, SS$_INTOVF, it indicates either a VAX system condition or a precise Alpha system condition. Figure 91 shows the format of the SS$_HPARITH exception signal array.
This signal array contains three arguments that are specic to the SS$_HPARITH exception: the integer register write mask, oating register write mask, and exception summary arguments of the exception pc and exception ps. The integer register write mask and oating register write mask arguments indicate the registers that were targets of instructions that set bits in the exception summary argument. Each bit in the mask represents a register. The exception summary argument indicates the type of exceptions that are being signaled by setting ags in the rst 7 bits. Table 94 lists the meaning of each of these bits when set. Table 94 Exception Summary Argument Fields
Bit 0 1 2 3 4 5 6 Meaning When Set Software completion. Invalid oating arithmetic, conversion, or comparison operation. Invalid attempt to perform a oating divide operation with a divisor of zero. Note that integer divide-by-zero is not reported. Floating arithmetic or conversion operation overowed the destination exponent. Floating arithmetic or conversion operation underowed the destination exponent. Floating arithmetic or conversion operation gave a result that differed from the mathematically exact result. Integer arithmetic or conversion operation from oating point to integer overowed the destination precision.
For more information and recommendations about using arithmetic exceptions on Alpha systems, see Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications. Note that this manual has been archived but is available on the OpenVMS Documentation Web site at: http://www.hp.com/go/openvms/doc
Condition-Handling Routines and Services 9.3 Exception Conditions 9.3.4 Unaligned Access Traps (Alpha and I64 Only)
On Alpha and I64 systems, an unaligned access trap is generated when an attempt is made to load or store a longword or quadword to or from a register using an address that does not have the natural alignment of the particular data reference and does not use an instruction that takes an unaligned address as an operand (for example, LDQ_U on Alpha systems). For more information about data alignment, see Section 9.4.2. Alpha and I64 compilers typically avoid triggering alignment faults by: Aligning static data on natural boundaries by default. (This default behavior can be overridden by using a compiler qualier.) Generating special inline code sequences for data that is known to be unnaturally aligned at compile time.
Note, however, that compilers cannot align dynamically dened data. Thus, alignment faults may be triggered. An alignment exception is identied by the condition code SS$_ALIGN. Figure 92 illustrates the elements of the signal array returned by the SS$_ ALIGN exception. Figure 92 SS$_ALIGN Exception Signal Array
31 Argument Count Condition Code (SS$_ALIGN) Virtual Address Register Number Exception PC Exception PS
ZK5205AGE
This signal array contains two arguments specic to the SS$_ALIGN exception: the virtual address argument and the register number (ISR for I64) argument. The virtual address argument contains the address of the unaligned data being accessed. The register number (ISR for I64) argument identies the target register of the operation.
Condition-Handling Routines and Services 9.4 How Run-Time Library Routines Handle Exceptions
In order to maintain modularity, the run-time library does not use exception vectors, which are processwide data locations. Thus, the run-time library itself does not establish handlers by using the primary, secondary, or last-chance exception vectors.
The user can enable or disable detection of oating-point underow at run time by calling the routine LIB$FLT_UNDER.
Condition-Handling Routines and Services 9.4 How Run-Time Library Routines Handle Exceptions
LIB$INT_OVEREnables or disables the signaling of an integer overow. By default, signaling is enabled.
You can establish these handlers in one of two ways: Invoke the appropriate handler as a function specifying the rst argument as 1 to enable signaling. Invoke the handler with command qualiers when you compile your program. (Refer to your program language manuals.)
You cannot disable the signaling of integer divide-by-zero, oating-point overow, and oating-point or decimal divide-by-zero. When the signaling of a hardware condition is enabled, the occurrence of the exception condition causes the operating system to signal the condition as a severe error. When the signaling of a hardware condition is disabled, the occurrence of the condition is ignored, and the processor executes the next instruction in the sequence. The signaling of overow and underow detection is enabled independently for activation of each routine, because the call instruction saves the state of the calling programs hardware enable operations in the stack and then initializes the enable operations for the called routine. A return instruction restores the calling programs enable operations. These run-time library routines are intended primarily for high-level languages, because you can achieve the same effect in MACRO with the single Bit Set PSW (BISPSW) or Bit Clear PSW (BICPSW) VAX instructions. These routines allow you to enable and disable detection of decimal overow, oating-point underow, and integer overow for a portion of your routines execution. Note that the HP BASIC for OpenVMS VAX Systems and HP Fortran compilers provide a compile-time qualier that permits you to enable or disable integer overow for your entire routine. On Alpha and I64 systems, certain RTL routines that process conditions do not exist because the exception conditions dened by the Alpha and Intel Itanium architectures differ somewhat from those dened by the VAX architecture. Table 95 lists the run-time library condition-handling support routines available on VAX systems and indicates which are supported on Alpha and I64 systems.
Condition-Handling Routines and Services 9.4 How Run-Time Library Routines Handle Exceptions
Table 95 Run-Time Library Condition-Handling Support Routines
Routine Arithmetic Exception Support Routines LIB$DEC_OVEREnables or disables signaling of decimal overow LIB$FIXUP_FLTChanges oating-point reserved operand to a specied value LIB$FLT_UNDEREnables or disables signaling of oatingpoint underow LIB$INT_OVEREnables or disables signaling of integer overow General Condition-Handling Support Routines LIB$DECODE_FAULTAnalyzes instruction context for fault LIB$ESTABLISHEstablishes a condition handler Not supported Not supported (languages may support for compatibility) Supported Not supported (languages may support for compatibility) Supported Supported Not supported Supported Supported Not supported Not supported Not supported Not supported Availability on Alpha and I64 Systems
LIB$SIG_TO_STOPConverts a signaled condition to a condition that cannot be continued LIB$SIG_TO_RETConverts a signal to a return status LIB$SIM_TRAPSimulates a oating-point trap LIB$SIGNALSignals an exception condition LIB$STOPStops execution by using signaling
Figure 93 shows the format of a condition value. Figure 93 Format of a Condition Value
31 Control
28 27 Condition identification
3 2 Severity
1 *S
16 15 Message number
ZK1795GE
Condition Value Fields severity The severity of the error condition. Bit <0> indicates success (logical true) when set and failure (logical false) when clear. Bits <1> and <2> distinguish degrees of success or failure. The three bits, when taken as an unsigned integer, are interpreted as described in Table 97. The symbolic names are dened in module $STSDEF.
4 5 6 7
STS$K_SEVERE
Severe error
condition identication Identies the condition uniquely on a systemwide basis. control Four control bits. Bit <28> inhibits the message associated with the condition value from being printed by the SYS$EXIT system service. After using the SYS$PUTMSG system service to display an error message, the system default handler sets this bit. It is also set in the condition value returned by a routine as a function value, if the routine has also signaled the condition, so that the condition has been either printed or suppressed. Bits <29:31> must be zero; they are reserved for HP. When a software component completes execution, it returns a condition value in this format. When a severity value of warning, error, or severe error has been generated, the status value returned describes the nature of the problem. Your program can test this value to change the ow of control or to generate a message. Your program can also generate condition values to be examined by other routines and by the command language interpreter. Condition values dened by customers must set bits <27> and <15> so that these values do not conict with values dened by HP. message number The number identifying the message associated with the error condition. It is a status identication, that is, a description of the hardware exception condition that occurred or a software-dened value. Message numbers with bit <15> set are specic to a single facility. Message numbers with bit <15> clear are systemwide status values. facility number Identies the software component generating the condition value. Bit <27> is set for user facilities and clear for HP facilities.
Condition-Handling Routines and Services 9.5 Condition Values 9.5.1 Return Status Convention
Most system-dened procedures are functions of longwords, where the function value is equated to a condition value. In this capacity, the condition value is referred to as a return status. You can write your own routines to follow this convention. See Section 9.14.3 for information about how to change a signal to a return status. Each routine description in the HP OpenVMS System Services Reference Manual, HP OpenVMS RTL Library (LIB$) Manual, OpenVMS Record Management Utilities Reference Manual, and OpenVMS Utility Routines Manual lists the condition values that can be returned by that procedure. 9.5.1.1 Testing Returned Condition Values When a function returns a condition value to your program unit, you should always examine the returned condition value. To check for a failure condition (warning, error, or severe error), test the returned condition value for a logical value of false. The following program segment invokes the run-time library procedure LIB$DATE_TIME, checks the returned condition value (returned in the variable STATUS), and, if an error has occurred, signals the condition value by calling the run-time library procedure LIB$SIGNAL (Section 9.8 describes signaling): INTEGER*4 STATUS, 2 LIB$DATE_TIME CHARACTER*23 DATE STATUS = LIB$DATE_TIME (DATE) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL (STATUS)) To check for a specic error, test the return status for a particular condition value. For example, LIB$DATE_TIME returns a success value (LIB$_STRTRU) when it truncates the string. If you want to take special action when truncation occurs, specify the condition as shown in the following example (the special action would follow the IF statement): INTEGER*4 STATUS, 2 LIB$DATE_TIME CHARACTER*23 DATE INCLUDE ($LIBDEF) . . . STATUS = LIB$DATE_TIME (DATE) IF (STATUS .EQ. LIB$_STRTRU) THEN . . . 9.5.1.2 Using the $VMS_STATUS_SUCCESS Macro You can use the $VMS_STATUS_SUCCESS macro, dened in stsdef.h, to test an OpenVMS condition value. $VMS_STATUS_SUCCESS depends on the documented format of an OpenVMS condition value, and particularly on the setting of the lowest bit in a condition value. If the lowest bit is set, the condition indicates a successful status, while the bit is clear for an unsuccessful status. $VMS_STATUS_SUCCESS is used only with condition values that follow the OpenVMS condition status value format, and not with C standard library routines and return values that follow C native status value norms. For deails on the OpenVMS condition status value structure, please see Chapter 9. For information on the return values from the various C standard library routines, see the HP C Run-Time Library Reference Manual for OpenVMS Systems.
924 Condition-Handling Routines and Services
Because either a general or a specic value can be returned, your program must test for both. The following four symbols provide a starting and ending point with which you can compare the returned condition value: SS$_NOPRIVSTRTFirst specic value for SS$_NOPRIV SS$_NOPRIVENDLast specic value for SS$_NOPRIV SS$_NOQUOTASTRTFirst specic value for SS$_EXQUOTA SS$_NOQUOTAENDLast specic value for SS$_EXQUOTA
The following HP Fortran example tests for a privilege error by comparing STATUS (the returned condition value) with the specic condition value SS$_ NOPRIV and the range provided by SS$_NOPRIVSTRT and SS$_NOPRIVEND. You would test for SS$_NOEXQUOTA in a similar fashion.
Figure 94 illustrates the exception dispatchers search of the call stack for a condition handler.
B Calls C 0 FP
X Calls A
The illustration of the call stack indicates the calling sequence: Procedure A calls procedure B, and procedure B calls procedure C. Procedure A establishes a condition handler. An exception occurs while procedure C is executing. The exception dispatcher searches for a condition handler. After checking for a condition handler declared in the exception vectors (assume that none has been specified for the process), the dispatcher looks at the first longword of procedure Cs call frame. A value of 0 indicates that no condition handler has been specified. The dispatcher locates the call frame for procedure B by using the frame pointer (FP) in procedure Cs call frame. Again, it finds no condition handler, and locates procedure As call frame. The dispatcher locates and gives control to handler A.
ZK0858GE
On Alpha and I64 systems, you can use the $CHFDEF2 macro instruction to dene the symbolic names to refer to the arguments listed in Table 911.
Condition-Handling Routines and Services 9.7 Argument List Passed to a Condition Handler
Table 911 $CHFDEF2 Symbolic Names and Arguments on Alpha and I64 Systems
Symbolic Name CHF$L_SIGARGLST CHF$L_MCHARGLST CHF$IS_SIG_ARGS CHF$IS_SIG_NAME CHF$IS_SIG_ARG1 CHF$IS_MCH_ARGS CHF$IS_MCH_FLAGS CHF$PH_MCH_FRAME CHF$IS_MCH_DEPTH CHF$PH_MCH_DADDR CHF$PH_MCH_ESF_ADDR CHF$PH_MCH_SIG_ADDR CHF$IH_MCH_SAVRnn CHF$FH_MCH_SAVFnn Related Argument Address of signal array Address of mechanism array Number of signal arguments Condition name First signal-specic argument Number of mechanism arguments Flag bits <63:0> for related argument mechanism information Establisher frame address Frame depth of establisher Address of the handler data quadword if the exception handler data eld is present Address of the exception stack frame Address of the signal array A copy of the saved integer registers at the time of the exception A copy of the saved oating-point registers at the time of the exception
9.8 Signaling
Signaling can be initiated when hardware or software detects an exception condition. In either case, the exception condition is said to be signaled by the routine in which it occurred. If hardware detects the error, it passes control to a condition dispatcher. If software detects the error, it calls one of the runtime library signal-generating routines: LIB$SIGNAL or LIB$STOP. The RTL signal-generating routines pass control to the same condition dispatcher. When LIB$STOP is called, the severity code is forced to severe, and control cannot return to the routine that signaled the condition. See Section 9.12.1 for a description of how a signal can be dismissed and how normal execution from the point of the exception condition can be continued. When a routine signals, it passes to the OpenVMS Condition Handling facility (CHF) the condition value associated with the exception condition, as well as optional arguments that can be passed to a condition handler. The CHF uses these arguments to build two data structures on the stack: The signal argument vector. This vector contains the information describing the nature of the exception condition. The mechanism argument vector. This vector describes the state of the process at the time the exception condition occurred.
These two vectors become the arguments that the CHF passes to condition handlers. These argument vectors are described in detail in Section 9.8.2 and Section 9.8.3.
The OpenVMS Condition Handling facility searches for and calls condition handlers from each frame on the stack until the frame pointer is zero (indicating the end of the call sequence). At that point, the CHF calls the vectored catchall handler, which displays an error message and causes the program to exit. Note that, normally, the frame containing the stack catchall handler is at the end of the calling sequence or at the bottom of the stack. Section 9.9 explains the possible actions of default and user condition handlers in more detail. Figure 95 illustrates a stack scan for condition handlers in which the main program calls procedure A, which then calls procedure B. A stack scan is initiated either when a hardware exception condition occurs or when a call is made to LIB$SIGNAL or LIB$STOP.
Secondary Exception Vector Top of Stack :SP Routine B Stack Frame 0 Routine A Stack Frame User Handler Main Program Stack Frame 0 :FP
Traceback Handler
LastChance Vector
LastChance Handler
ZK1935GE
OpenVMS 32-bit condition value. The condition-value argument is an unsigned longword that contains this condition value. Section 9.5 explains the format of a condition value. condition-argument
OpenVMS usage: type: access: mechanism: varying_arg unspecied read only by value
As many arguments as are required to process the exception specied by condition-value. These arguments are also used as FAO (formatted ASCII output) arguments to format a message. condition-value-n
OpenVMS usage: type: access: mechanism: cond_value longword (unsigned) read only by value
OpenVMS 32-bit condition value. The optional condition-value-n argument is an unsigned longword that contains this condition value. The calling routine can specify additional conditions to be processed by specifying conditionvalue-2 through condition-value-n, with each condition value followed by
As many arguments as required to create the message reporting the exception specied by condition-value-n. LIB$STOP When your program wants to issue a message and stop execution unconditionally, it calls LIB$STOP. The calling sequence for LIB$STOP is as follows: LIB$STOP condition-value [,number-of-arguments] [,FAO-argument....] Only the condition-value argument must be specied; other arguments are optional. The condition-value argument is an OpenVMS 32-bit condition value. The condition-value argument is an unsigned longword that contains this condition value. The number-of-arguments argument, if specied, contains the number of FAO arguments that are associated with condition-value. The optional number-ofarguments argument is a signed longword integer that contains this number. If omitted or specied as zero, no FAO arguments follow. The FAO-argument argument is an optional FAO (formatted ASCII output) argument that is associated with the specied condition value. The condition-value argument indicates the condition that is being signaled. However, LIB$STOP always sets the severity of condition-value to SEVERE before proceeding with the stack-scanning operation. The FAO arguments describe the details of the exception condition. These are the same arguments that are passed to the OpenVMS Condition Handling facility as part of the signal argument vector. The system default condition handlers pass them to SYS$PUTMSG, which uses them to issue a system message. Unlike most routines, LIB$SIGNAL and LIB$STOP preserve R0 and R1 as well as the other registers. Therefore, a call to LIB$SIGNAL allows the debugger to display the entire state of the process at the time of the exception condition. This is useful for debugging checks and gathering statistics. The behavior of LIB$SIGNAL is the same as that of the exception dispatcher that performs the stack scan after hardware detects an exception condition. That is, the system scans the stack in the same way, and the same arguments are passed to each condition handler. This allows a user to write a single condition handler to detect both hardware and software conditions. For more information about the RTL routines LIB$SIGNAL and LIB$STOP, see the HP OpenVMS RTL Library (LIB$) Manual.
Condition-Handling Routines and Services 9.8 Signaling 9.8.2 Signal Argument Vector
Signaling a condition value causes systems to pass control to a special subprogram called a condition handler. The operating system invokes a default condition handler unless you have established your own. The default condition handler displays the associated error message and continues or, if the error is a severe error, terminates program execution. The signal argument vector contains information describing the nature of the hardware or software condition. Figure 96 illustrates the open-ended structure of the signal argument vector, which can be from 3 to 257 longwords in length. The format of the signal argument array and the data it returns is the same on VAX systems, Alpha systems, and I64 systems with the exception of the processor status (PS) returned on Alpha systems and I64 and the processor status longword (PSL) returned on VAX systems. On Alpha and I64 systems, it is the low-order 32 bits of the PS. Note that the PS in the signal arrays on I64 systems is fabricated. On Alpha systems, CHF$IS_SIG_ARGS and CHF$IS_SIG_NAME are aliases for CHF$L_SIG_ARGS and CHF$L_SIG_NAME, as shown in Figure 96, and the PSL eld for VAX systems is the processor status (PS) eld for Alpha systems. Figure 96 Format of the Signal Argument Vector
MACRO and BLISS n = Additional Longwords Condition Value Optional Additional Arguments Making Up One or More Message Sequences PC PSL SIGARGS(n) SIGARGS(n + 1) ZK1963GE CHF$L_SIG_ARGS CHF$L_SIG_NAME HighLevel Languages SIGARGS(1) SIGARGS(2)
Fields of the Signal Argument Vector SIGARGS(1) An unsigned integer (n) designating the number of longwords that follow in the vector, not counting the rst, including PC and PSL. (On Alpha systems, the value used for the PSL is the low-order half of the Alpha processor status [PS] register. For I64 systems the PS is also used, but the PS is fabricated.) For example, the rst entry of a 4-longword vector would contain a 3. SIGARGS(2) This argument is a 32-bit value that uniquely identies a hardware or software exception condition. The format of the condition code, which is the same for VAX systems, Alpha systems, and I64 systems, is shown and described in Figure 93. However, Alpha systems do not support every condition returned on VAX systems, and Alpha systems dene several new conditions that cannot be returned on VAX systems. Some Alpha conditions exist on I64, some Alpha conditions are not
The formats for some conditions signaled by the operating system and the runtime library are shown in Figure 97 and Figure 98. These formats are the same on VAX systems and Alpha systems, except for the PSL, or on Alpha and I64 systems, the PS register (which is fabricated on I64).
Fields of the VAX Mechanism Argument Vector MCHARGS(1) An unsigned integer indicating the number of longwords that follow, not counting the rst, in the vector. Currently, this number is always 4. MCHARGS(2) The address of the stack frame of the routine that established the handler being called. You can use this address as a base from which to reference the local stack-allocated storage of the establisher, as long as the restrictions on the handlers use of storage are observed. For example, if the call stack is as shown in Figure 94, this argument points to the call frame for procedure A. You can use this value to display local variables in the procedure that established the condition handler if the variables are at known offsets from the frame pointer (FP) of the procedure. MCHARGS(3) The stack depth, which is the number of stack frames between the establisher of the condition handler and the frame in which the condition was signaled. To ensure that calls to LIB$SIGNAL and LIB$STOP appear as similar as possible to hardware exception conditions, the call to LIB$SIGNAL or LIB$STOP is not included in the depth. If the routine that contained the hardware exception condition or that called LIB$SIGNAL or LIB$STOP also handled the exception condition, then the depth is zero; if the exception condition occurred in a called routine and its caller handled the exception condition, then the depth is 1. If a system service signals an exception condition, a handler established by the immediate caller is also entered with a depth of 1. The following table shows the stack depths for the establishers of condition handlers:
Depth 3 2 1 Meaning Condition handler was established in the last-chance exception vector. Condition handler was established in the primary exception vector. Condition handler was established in the secondary exception vector.
For example, if the call stack is as shown in Figure 94, the depth argument passed to handler A would have a value of 2. The condition handler can use this argument to determine whether to handle the condition. For example, the handler might not want to handle the condition if the exception that caused the condition did not occur in the establisher frame. MCHARGS(4) and MCHARGS(5) Copies of the contents of registers R0 and R1 at the time of the exception condition or the call to LIB$SIGNAL or LIB$STOP. When execution continues or a stack unwind occurs, these values are restored to R0 and R1. Thus, a handler can modify these values to change the function value returned to a caller.
MCH_FRAME
MCH_DEPTH MCH_RESVD1
MCH_DADDR
MCH_ESF_ADDR
:32
MCH_SIG_ADDR
:40
:48
:56
:64 MCH_SAVR16
:160 MCH_SAVR28
:168 MCH_SAVF0
:176 MCH_SAVF1
:184 MCH_SAVF10
:344 MCH_SAVF30
:352 MCH_SIG64_ADDR
CHF$S_CHFDEF2 = 360
ZK4645AGE
CHF$IS_MCH_FLAGS
CHF$PS_MCH_DADDR
CHF$FM_MCH_SAVFnn
For more information and recommendations about using the mechanism argument vector on Alpha systems, see Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications. Note that this manual has been archived but is available on the OpenVMS Documentation CD-ROM.
:0 :4 :8 :16 :20 :24 :32 :40 :48 :56 :64 :72 :80 :96 :112
:176
CHF$IS_MCH_FLAGS
CHF$IS_MCH_DEPTH
CHF$IS_MCH_RESVD1 CHF$PH_MCH_DADDR
CHF$PH_MCH_ESF_ADDR CHF$PH_MCH_SIG_ADDR
CHF$IS_MCH_RETVAL CHF$IS_MCH_RETVAL2
Normally, the OpenVMS Condition Handling facility (CHF) searches all currently active frames for condition handlers, including B and C. If this happens, however, BH is called again. At this point, you skip the condition handlers that have already been called. Thus, the search for condition handlers should proceed in the following order: YH XH BHH (the handler for routine Bs handler) AH 6. The search now continues in its usual fashion. The CHF examines the primary and secondary exception vectors, then frames Y, X, and BH. Thus, handlers YH, XH, and BHH are called. Assume that these handlers resignal.
Condition-Handling Routines and Services 9.9 Types of Condition Handlers 9.9.1 Default Condition Handlers
The operating system establishes the following default condition handlers each time a new image is started. The default handlers are shown in the order they are encountered when the operating system processes a signal. These three handlers are the only handlers that output error messages. Traceback handler The traceback handler is established on the stack after the catchall handler. This enables the traceback handler to get control rst. This handler performs three functions in the following order: 1. Outputs an error message using the Put Message (SYS$PUTMSG) system service. SYS$PUTMSG formats the message using the Formatted ASCII Output (SYS$FAO) system service and sends the message to the devices identied by the logical names SYS$ERROR and SYS$OUTPUT (if it differs from SYS$ERROR). That is, it displays the message associated with the signaled condition code, the traceback message, the program unit name and line number of the statement that signaled the condition code, and the relative and absolute program counter values. (On a warning or error, the number of the next statement to be executed is displayed.) 2. Issues a symbolic traceback, which shows the state of the routine stack at the time of the exception condition. That is, it displays the names of the program units in the calling hierarchy and the line numbers of the invocation statements.
The traceback handler is in effect if you link your program with the /TRACEBACK qualier of the LINK command (the default). Once you have completed program development, you generally link your program with the /NOTRACEBACK qualier and use the catchall handler. Catchall handler The operating system establishes the catchall handler in the rst stack frame and thus calls it last. This handler performs the same functions as the traceback handler except for the stack traceback. That is, it issues an error message and decides whether to continue execution. The catchall is called only if you link with the /NOTRACEBACK qualier. It displays the message associated with the condition code and then continues program execution or, if the error is severe, terminates execution. Last-chance handler The operating system establishes the last-chance handler with a system exception vector. In most cases, this vector contains the address of the catchall handler, so that these two handlers are actually the same. The last-chance handler is called only if the stack is invalid or all the handlers on the stack have resignaled. If the debugger is present, the debuggers own last-chance handler replaces the system last-chance handler. Displays the message associated with the condition code and then continues program execution or, if the error is severe, terminates execution. The catchall handler is not invoked if the traceback handler is enabled. In the following example, if the condition code INCOME_LINELOST is signaled at line 496 of GET_STATS, regardless of which default handler is in effect, the following message is displayed: %INCOME-W-LINELOST, Statistics on last line lost due to CTRL/Z If the traceback handler is in effect, the following text is also displayed: %TRACE-W-TRACEBACK, symbolic stack dump follows module name routine name line rel PC GET_STATS INCOME GET_STATS INCOME 497 148 00000306 0000015A 0000A5BC 00009BDB 0000A599 abs PC 00008DA2 0000875A 0000A5BC 00009BDB 0000A599
Because INCOME_LINELOST is a warning, the line number of the next statement to be executed (497), rather than the line number of the statement that signaled the condition code, is displayed. Line 148 of the program unit INCOME invoked GET_STATS.
Condition-Handling Routines and Services 9.9 Types of Condition Handlers 9.9.2 Interaction Between Default and User-Supplied Handlers
Several results are possible after a routine signals, depending on a number of factors, such as the severity of the error, the method of generating the signal, and the action of the condition handlers you have dened and the default handlers. Given the severity of the condition and the method of signaling, Figure 913 lists all combinations of interaction between user condition handlers and default condition handlers. Figure 913 Interaction Between Handlers and Default Handlers
Severity of Condition
Exception Condition Is Signaled by a Call to LIB$SIGNAL or Detected by Hardware Issue Condition Message RETURN Issue Condition Message EXIT Call Last Chance Handler EXIT Call Last Chance Handler EXIT
RETURN
UNWIND
SEVERE
RETURN
UNWIND
Exception Condition Is Signaled by a Call to LIB$STOP LIB$STOP Forces Severity to SEVERE Message: "Attempt to continue from stop" EXIT Issue Condition Message EXIT Call Last Chance Handler EXIT ZK4257GE
UNWIND
Condition-Handling Routines and Services 9.10 Types of Actions Performed by Condition Handlers
Condition-Handling Routines and Services 9.10 Types of Actions Performed by Condition Handlers 9.10.1 Unwinding the Call Stack
One type of action a condition handler can take is to unwind the procedure call stack. The unwind operation is complex and should be used only when control must be restored to an earlier procedure in the calling sequence. Moreover, use of the SYS$UNWIND system service requires the calling condition handler to be aware of the calling sequence and of the exact point to which control is to return. SYS$UNWIND accepts two optional arguments: The depth to which the unwind is to occur. If the depth is 1, the call stack is unwound to the caller of the procedure that incurred the exception. If the depth is 2, the call stack is unwound to the callers caller, and so on. By specifying the depth in the mechanism array, the handler can unwind to the procedure that established the handler. The address of a location to receive control when the unwind operation is complete, that is, a PC to replace the current PC in the call frame of the procedure that will receive control when all specied frames have been removed from the stack.
If no argument is supplied to SYS$UNWIND, the unwind is performed to the caller of the procedure that established the condition handler that is issuing the SYS$UNWIND service. Control is returned to the address specied in the return PC for that procedure. Note that this is the default and the normal case for unwinding. Another common case of unwinding is to unwind to the procedure that declared the handler. On VAX systems, this is done by using the depth value from the exception mechanism array (CHF$L_MCH_DEPTH) as the depth argument to SYS$UNWIND. On Alpha and I64 systems, this is done by using the depth value from the exception mechanism array (CHF$IS_MCH_DEPTH) as the depth argument to SYS$UNWIND. Therefore, it follows that the default unwind (no depth specied) is equivalent to specifying CHF$L_MCH_DEPTH plus 1 on VAX systems. On Alpha and I64 systems, the default unwind (no depth specied) is equivalent to specifying CHF$IS_MCH_DEPTH plus 1. In certain instances of nested exceptions, however, this is not the case. HP recommends that you omit the depth argument when unwinding to the caller of the routine that established the condition handler. Figure 914 illustrates an unwind situation and describes some of the possible results. The unwind operation consists of two parts: 1. In the call to SYS$UNWIND, the return PCs saved in the stack are modied to point into a routine within the SYS$UNWIND service, but the entire stack remains present. 2. When the handler returns, control is directed to this routine by the modied PCs. It proceeds to return to itself, removing the modied stack frames, until the stack has been unwound to the proper depth. For this reason, the stack is in an intermediate state directly after calling SYS$UNWIND. Handlers should, in general, return immediately after calling SYS$UNWIND.
Condition-Handling Routines and Services 9.10 Types of Actions Performed by Condition Handlers
During the actual unwinding of the call stack, the unwind routine examines each frame in the call stack to see whether a condition handler has been declared. If a handler has been declared, the unwind routine calls the handler with the status value SS$_UNWIND (indicating that the call stack is being unwound) in the condition name argument of the signal array. When a condition handler is called with this status value, it can perform any procedure-specic cleanup operations required. For example, the handler should deallocate any processwide resources that have been allocated. Then, the handler returns control to the OpenVMS Condition Handling facility. After the handler returns, the call frame is removed from the stack. When a condition handler is called during the unwinding operation, the condition handler must not generate a new signal. A new signal would result in unpredictable behavior. Thus, in Figure 914, handler B can be called a second time, during the unwind operation. Note that handler B does not have to be able to interpret the SS$_ UNWIND status value specically; the return instruction merely returns control to the unwind procedure, which does not check any status values. Handlers established by the primary, secondary, or last-chance vector are not called, because they are not removed during an unwind operation. While it is unwinding the stack, the OpenVMS Condition Handling facility ignores any function value returned by a condition handler. For this reason, a handler cannot both resignal and unwind. Thus, the only way for a handler to both issue a message and perform an unwind is to call LIB$SIGNAL and then call $UNWIND. If your program calls $UNWIND before calling LIB$SIGNAL, the result is unpredictable. When the OpenVMS Condition Handling facility calls the condition handler that was established for each frame during unwind, the call is of the standard form, described in Section 9.2. The arguments passed to the condition handler (the signal and mechanism argument vectors) are shown in Section 9.8.2, Section 9.8.3, and Section 9.8.4. On VAX systems, if the handler is to specify the function value of the last function to be unwound, it should modify the saved copies of R0 and R1 (CHF$L_MCH_ SAVR0 and CHF$L_MCH_SAVR1) in the mechanism argument vector. On Alpha and I64 systems, the handler should modify the saved copies of R0 and R1 (R8, R9 for I64) (CHF$IH_MCH_SAVRnn). R0 and R1 (R8, R9 for I64) are restored from the mechanism argument vector at the end of the unwind.
Condition-Handling Routines and Services 9.10 Types of Actions Performed by Condition Handlers
Figure 914 Unwinding the Call Stack
D Runs and Incurs Condition 0 FP
C Calls D 0 FP
A Calls B 0 FP
X Calls A
1 The procedure call stack is as shown. Assume that no exception vectors are declared for the process and that the exception occurs during the execution of procedure D. 2 Because neither procedure D nor procedure C has established a condition handler, handler B receives control. 3 If handler B issues the $UNWIND system service with no arguments, the call frames for B, C, and D are removed from the stack (along with the call frame for handler B itself), and control returns to procedure A. Procedure A receives control at the point following its call to procedure B. 4 If handler B issues the $UNWIND system service specitying a depth of 2, call frames for C and D are removed, and control returns to procedure B.
ZK0860GE
Condition-Handling Routines and Services 9.10 Types of Actions Performed by Condition Handlers 9.10.2 GOTO Unwind Operations (Alpha and I64 Only)
On Alpha systems, a current procedure invocation is one in whose context the thread of execution is currently executing. At any instant, a thread of execution has exactly one current procedure. If code in the current procedure calls another procedure, then the called procedure becomes the current procedure. As each stack frame or register frame procedure is called, its invocation context is recorded in a procedure frame. The invocation context is mainly a snapshot of process registers at procedure invocation. It is used during return from the called procedure to restore the calling procedures state. The chain of all procedure frames starting with the current procedure and going all the way back to the rst procedure invocation for the thread is called the call chain. While a procedure is part of the call chain, it is called an active procedure. When a current procedure returns to its calling procedure, the most recent procedure frame is removed from the call chain and used to restore the now current procedures state. As each current procedure returns to its calling procedure, its associated procedure frame is removed from the call chain. This is the normal unwind process of a call chain. You can bypass the normal return path by forcibly unwinding the call chain. The Unwind Call Chain (SYS$UNWIND) system service allows a condition handler to transfer control from a series of nested procedure invocations to a previous point of execution, bypassing the normal return path. The Goto Unwind (SYS$GOTO_ UNWIND) system service allows any procedure to achieve the same effect. (On I64 systems SYS$GOTO_UNWIND does not exist, use SYS$GOTO_UNWIND_ 64.) SYS$GOTO_UNWIND (SYS$GOTO_UNWIND_64) restores saved register context for each nested procedure invocation, calling the condition handler, if any, for each procedure frame that it unwinds. Restoring saved register context from each procedure frame from the most recent one to the target procedure frame ensures that the register context is correct when the target procedure gains control. Also, each condition handler called during unwind can release any resources acquired by its establishing procedure. For information about the GOTO unwind operations and how to use the SYS$GOTO_UNWIND (SYS$GOTO_UNWIND_64) system service, see the HP OpenVMS Calling Standard and the HP OpenVMS System Services Reference Manual.
The message can also include up to 255 formatted ASCII output (FAO) arguments. These arguments can be used to display variable information about the condition that caused the message. In the following examples, the le specication is an FAO argument:
Variable Number of FAO Arguments Condition Value FAO_count FAO arg1 FAO arg2 Condition Value Number of FAO Arguments
FAO argn
VAX11 RMS Error with STV (Status Value) VAX11 RMS Condition Value (STS) Associated Status Value (STV) Condition Value One FAO Argument or SS$_... Condition Value
ZK1967GE
OpenVMS RMS system services return two related completion values: the completion code and the associated status value. The completion code is returned in R0 using the function value mechanism. The same value is also placed in the Completion Status Code eld of the RMS le access block (FAB) or record access block (RAB) associated with the le (FAB$L_STS or RAB$L_STS). The status value is returned in the Status Value eld of the same FAB or RAB (FAB$L_ STV or RAB$L_STV). The meaning of this secondary value is based on the corresponding STS (Completion Status Code) value. Its meaning could be any of the following: An operating system condition value of the form SS$_ . . . An RMS value, such as the size of a record that exceeds the buffer size Zero
Rather than have each calling program determine the meaning of the STV value, SYS$PUTMSG performs the necessary processing. Therefore, this STV value must always be passed in place of the FAO argument count. In other words, an RMS message sequence always consists of two arguments (passed by immediate value): an STS value and an STV value.
Condition-Handling Routines and Services 9.11 Displaying Messages 9.11.1 Chaining Messages
You can use a condition handler to add condition values to an originally signaled condition code. For example, if your program calculates the standard deviation of a series of numbers and the user only enters one value, the operating system signals the condition code SS$_INTDIV when the program attempts to divide by zero. (In calculating the standard deviation, the divisor is the number of values entered minus 1.) You could use a condition handler to add a user-dened message to the original message to indicate that only one value was entered. To display multiple messages, pass the condition values associated with the messages to the RTL routine LIB$SIGNAL. To display the message associated with an additional condition code, the handler must pass LIB$SIGNAL the condition code, the number of FAO arguments used, and the FAO arguments. To display the message associated with the originally signaled condition codes, the handler must pass LIB$SIGNAL each element of the signal array as a separate argument. Because the signal array is a variable-length array and LIB$SIGNAL cannot accept a variable number of arguments, when you write your handler you must pass LIB$SIGNAL more arguments than you think will be required. Then, during execution of the handler, zero the arguments that you do not need (LIB$SIGNAL ignores zero values), as described in the following steps: 1. Declare an array with one element for each argument that you plan to pass LIB$SIGNAL. Fifteen elements are usually sufcient. INTEGER*4 NEWSIGARGS(15) 2. Transfer the condition values and FAO information from the signal array to your new array. The rst element and the last two elements of the signal array do not contain FAO information and should not be transferred. 3. Fill any remaining elements of your new array with zeros. The following example demonstrates steps 2 and 3: DO I = 1, 15 IF (I .LE. SIGARGS(1) - 2) THEN NEWSIGARGS(I) = SIGARGS(I+1) ! Start with SIGARGS(2) ELSE NEWSIGARGS(I) = 0 ! Pad with zeros END IF END DO Because the new array is a known-length array, you can specify each element as an argument to LIB$SIGNAL. The following condition handler ensures that the signaled condition code is SS$_ INTDIV. If it is, the user-dened message ONE_VALUE is added to SS$_INTDIV, and both messages are displayed. INTEGER FUNCTION HANDLER (SIGARGS, 2 MECHARGS) ! Declare dummy arguments INTEGER SIGARGS(*), 2 MECHARGS(*) ! Declare new array for SIGARGS INTEGER NEWSIGARGS (15) ! Declare index variable for LIB$MATCH_COND INTEGER INDEX ! Declare procedures INTEGER LIB$MATCH_COND
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
HANDLER = SS$_CONTINUE ELSE HANDLER = SS$_RESIGNAL END IF END A signal argument list may contain one or more condition values and FAO arguments. Each condition value and its FAO arguments is chained to the next condition value and its FAO arguments. You can use chained messages to provide more specic information about the exception condition being signaled, along with a general message. The following message source le denes the exception condition PROG_ _FAIGETMEM: .FACILITY PROG,1 /PREFIX=PROG__
.SEVERITY FATAL .BASE 100 FAIGETMEM .END This source le sets up the exception message as follows: The .FACILITY directive species the facility, PROG, and its number, 1. It also adds the /PREFIX qualier to determine the prex to be used in the message. <failed to get !UL bytes of memory>/FAO_COUNT=1
Procedure A
Procedure A calls procedure B. Handler B An exception occurs during procedure B. CHF calls handler B. Procedure B $PUTMSG returns to handler B.
Handler B calls $PUTMSG and passes signal argument vector and address of action subroutine. $PUTMSG $PUTMSG obtains error message text and passes one line at a time to action subroutine. Users Action Subroutine
ZK1934GE
9.11.2.1 Creating a Running Log of Messages Using SYS$PUTMSG To keep a running log (that is, a log that is resumed each time your program is invoked) of the messages displayed by your program, use SYS$PUTMSG. Create a condition handler that invokes SYS$PUTMSG regardless of the signaled condition code. When you invoke SYS$PUTMSG, specify a function that writes the formatted message to your log le and then returns with a function value of 0. Have the condition handler resignal the condition code. One of the arguments of SYS$PUTMSG allows you to specify a user-dened function that SYS$PUTMSG invokes after formatting the message and before displaying the message. SYS$PUTMSG passes the formatted message to the specied function. If the function returns with a function value of 0, SYS$PUTMSG does not display the message; if the function returns with a value of 1, SYS$PUTMSG displays the message. The HP OpenVMS System Services Reference Manual contains complete specications for SYS$PUTMSG. 9.11.2.2 Suppressing the Display of Messages in the Running Log To keep a running log of messages, you might have your main program open a le for the error log, write the date, and then establish a condition handler to write all signaled messages to the error log. Each time a condition is signaled, a condition handler like the one in the following example invokes SYS$PUTMSG and species a function that writes the message to the log le and returns with a function value of 0. SYS$PUTMSG writes the message to the log le but does not display the message. After SYS$PUTMSG writes the message to the log le, the condition handler resignals to continue program execution. (The condition handler uses LIB$GET_COMMON to read the unit number of the le from the per-process common block.)
9.11.3 Using the Message Utility to Signal and Display User-Dened Messages
Section 9.11 explains how the OpenVMS Condition Handling facility displays messages. The signal argument list passed to LIB$SIGNAL or LIB$STOP can be seen as one or more message sequences. Each message sequence consists of a condition value, an FAO count, which species the number of FAO arguments to come, and the FAO arguments themselves. (The FAO count is omitted in the case of system and RMS messages.) The message text denition itself is actually a SYS$FAO control string, which may contain embedded $FAO directives. The HP OpenVMS System Services Reference Manual describes the Formatted ASCII Output (SYS$FAO) system service in detail. The Message utility is provided for compiling message sequences specic to your application. When you have dened an exception condition and used the Message utility to associate a message with that exception condition, your program can call LIB$SIGNAL or LIB$STOP to signal the exception condition. You signal a message that is dened in a message source le by calling LIB$SIGNAL or LIB$STOP, as for any software-detected exception condition. Then the system default condition handlers display your error message in the standard operating system format.
9.11.4 Signaling User-Dened Values and Messages with Global and Local Symbols
To signal a user-dened condition value, you use the symbol formed by the facility prex and the condition name (for example, INCOME_ _BADFIXVAL). Typically, you reference a condition value as a global symbol; however, you can create an include le (similar to the modules in the system library SYS$LIBRARY:FORSTSDEF.TLB) to dene the condition values as local symbols. If the message text contains FAO arguments, you must specify parameters for those arguments when you signal the condition value. 9.11.4.1 Signaling with Global Symbols To signal a user-dened condition value using a global symbol, declare the appropriate condition value in the appropriate section of the program unit, and then invoke the RTL routine LIB$SIGNAL to signal the condition value. The following statements signal the condition value INCOME_ _NOHOUSE when the value of FIX_HOUSE_NO is less than 1 or greater than the value of TOTAL_ HOUSES: EXTERNAL INCOME__NOHOUSE . . . IF ((FIX_HOUSE_NO .GT. TOTAL_HOUSES) .OR. 2 FIX_HOUSE_NO .LT. 1)) THEN CALL LIB$SIGNAL (%VAL (%LOC (INCOME__NOHOUSE))) END IF 9.11.4.2 Signaling with Local Symbols To signal a user-dened condition value using a local symbol, you must rst create a le containing PARAMETER statements that equate each condition value with its user-dened condition value. To create such a le, do the following: 1. Create a listing leCompile the message source le with the /LIST qualier to the MESSAGE command. The /LIST qualier produces a listing le with the same name as the source le and a le type of .LIS. The following line might appear in a listing le: 08018020 11 NOHOUSE "No such house number"
You can write a condition handler to take action when an exception condition is signaled. When the exception condition occurs, the OpenVMS Condition Handling facility sets up the signal argument vector and mechanism argument vector and begins the search for a condition handler. Therefore, your condition-handling routine must declare variables to contain the two argument vectors. Further, the handler must indicate the action to be taken when it returns to the OpenVMS Condition Handling facility. The handler uses its function value to do this. Thus, the calling sequence for your condition handler has the following format: handler signal-args ,mechanism-args signal-args The address of a vector of longwords indicating the nature of the condition. See Section 9.8.2 for a detailed description. mechanism-args The address of a vector of longwords that indicates the state of the process at the time of the signal. See Section 9.8.3 and Section 9.8.4 for more details. result A condition value. Success (bit <0> = 1) causes execution to continue at the PC; failure (bit <0> = 0) causes the condition to be resignaled. That is, the system resumes the search for other handlers. If the handler calls the Unwind (SYS$UNWIND) system service, the return value is ignored and the stack is unwound. (See Section 9.12.3.) Handlers can modify the contents of either the signal-args vector or the mechanism-args vector.
The sections that follow describe how to write condition handlers to perform these three operations.
On Alpha and I64 systems, LIB$SIM_TRAP is not supported. Table 95 lists the run-time library routines that are supported and not supported on Alpha and I64 systems.
9.12.2 Resignaling
Condition handlers check for specic errors. If the signaled condition is not one of the expected errors, the handler resignals. That is, it returns control to the OpenVMS Condition Handling facility with the function value SS$_RESIGNAL (with bit <0> clear). To alter the severity of the signal, the handler modies the low-order 3 bits of the condition value and resignals. For an example of resignaling, see Section 9.8.6.
Condition-Handling Routines and Services 9.12 Writing a Condition Handler 9.12.3 Unwinding the Call Stack
A condition handler can dismiss the signal by calling the system service SYS$UNWIND. The stack unwind is initiated when a condition handler that has called SYS$UNWIND returns to OpenVMS Condition Handling facility. For an explanation of unwinding, see Section 9.10.1; for an example of using SYS$UNWIND to return control to the program, see Section 9.12.4.5.
9.12.4.5 Returning Control to the Program Your handlers should return control either to the program unit that established the handler or to the program unit that invoked the program unit that established the handler. To return control to the program unit that established the handler, invoke SYS$UNWIND and pass the call depth (third element of the VAX mechanism array, or the CHF$IS_MCH_DEPTH eld for Alpha and I64) as the rst argument with no second argument. ! Declare dummy arguments INTEGER*4 SIGARGS(*), 2 MECHARGS(*) . . . CALL SYS$UNWIND (MECHARGS(3),) To return control to the caller of the program unit that established the handler, invoke SYS$UNWIND without passing any arguments. ! Declare dummy arguments INTEGER*4 SIGARGS(*), 2 MECHARGS(*) . . . CALL SYS$UNWIND (,)
Condition-Handling Routines and Services 9.12 Writing a Condition Handler 9.12.5 Example of Condition-Handling Routines
The following example shows two procedures, A and B, that have declared condition handlers. The notes describe the sequence of events that would occur if a call to a system service failed during the execution of procedure B. /* PGMA */ #include <stdio.h> #include <ssdef.h> unsigned int sigargs[],mechargs[]; main() { unsigned int status, vector=0, old_handler; old_handler = LIB$ESTABLISH( handlera ); status = pgmb (arglst); . . . } /* PGMB */ #include <stdio.h> #include <ssdef.h> main() { old_handler = LIB$ESTABLISH( handlerb ); . . .
# ! "
$ %
} /* Handler A */ int handlera( sigargs, mechargs ) { /* Compare condition value signalled with expected value */ if (sigargs[1] != SS$_SSFAIL) goto no_fail; . . . /* Signal to continue */ return SS$_CONTINUE; /* Signal to resignal */ no_fail: return SS$_RESIGNAL; } /* Handler B */ int handlerb( sigargs, mechargs ) { /* Compare condition value signalled with expected value */ if (sigargs[1] != SS$_BREAK) goto no_fail; . . . return SS$_CONTINUE;
&
(handler b). Handler B is set to handle SS$_BREAK, not SS$_SSFAIL so it returns SS$_RESIGNAL.
& Upon receiving the SS$_RESIGNAL status from HANDLER B, the exception
dispatcher resumes its search for a condition handler. It nds and calls handler a.
HANDLER A handles the system service failure exception, corrects the
condition, places the return value SS$_CONTINUE in r0 (r8 if this example were run on an I64 system), and returns control to the exception dispatcher, which will, in turn, return control to procedure B. Execution of procedure B resumes at the instruction following the system service failure.
Condition-Handling Routines and Services 9.14 Run-Time Library Condition-Handling Routines 9.14.1 RTL Jacket Handlers (Alpha and I64 Only)
Many RTLs establish a jacket RTL handler on a frame where the user program has dened its own handler. This RTL jacket does some setup and argument manipulation before actually calling the handler dened by the user. When processing the exception, the debugger sets the breakpoint on the jacket RTL jacket handler, because that is the address on the call stack. If the debugger suspends program execution at a jacket RTL handler, it is usually possible to reach the user-dened handler by entering a STEP/CALL command followed by a STEP/INTO command. Some cases might require that additional sequences of STEP/CALL and STEP/INTO commands be entered. For more information about frame-based handlers, see HP OpenVMS Calling Standard. If the jacket RTL handler is part of an installed shared image such as ALPHA LIBOTS, the debugger cannot set a breakpoint on it. In this case, activate the RTL as a private image by dening the RTL as a logical name, as in the following example: $DEFINE LIBOTS SYS$SHARE:LIBOTS.EXE; Note In the previous example, the trailing semicolon (;) is required.
When it is preferable to detect errors by signaling but the calling routine expects a returned status, LIB$SIG_TO_RET can be used by the routine that signals. For instance, if you expect a particular condition code to be signaled, you can prevent the operating system from invoking the default condition handler by establishing a different condition handler. LIB$SIG_TO_RET is a condition handler that converts any signaled condition to a return status. The status is returned to the caller of the routine that established LIB$SIG_TO_RET. You may
Your calling routine can now both test R0 (R8 for I64), as if the called routine had returned a status, and specify an error recovery action. The following paragraphs describe how to establish and use the system-dened condition handler LIB$SIG_TO_RET, which changes a signal to a return status that your program can examine. To change a signal to a return status, you must put any code that might signal a condition code into a function where the function value is a return status. The function containing the code must perform the following operations: Declare LIB$SIG_TO_RETDeclare the condition handler LIB$SIG_TO_RET. Establish LIB$SIG_TO_RETInvoke the run-time library procedure LIB$ESTABLISH to establish a condition handler for the current program unit. Specify the name of the condition handler LIB$SIG_TO_RET as the only argument. Initialize the function valueInitialize the function value to SS$_NORMAL so that, if no condition code is signaled, the function returns a success status to the invoking program unit. Declare necessary dummy argumentsIf any statement that might signal a condition code is a subprogram that requires dummy arguments, pass the necessary arguments to the function. In the function, declare each dummy argument exactly as it is declared in the subprogram that requires it and specify the dummy arguments in the subprogram invocation.
If the program unit GET_1_STAT in the following function signals a condition code, LIB$SIG_TO_RET changes the signal to the return status of the INTERCEPT_SIGNAL function and returns control to the program unit that invoked INTERCEPT_SIGNAL. (If GET_1_STAT has a condition handler established, the operating system invokes that handler before invoking LIB$SIG_ TO_RET.)
Condition-Handling Routines and Services 9.14 Run-Time Library Condition-Handling Routines 9.14.7 Decoding the Instruction That Generated a Fault (VAX Only)
On VAX systems, LIB$DECODE_FAULT locates the operands for an instruction that caused a fault and passes the information to a user action routine. When called from a condition handler, LIB$DECODE_FAULT locates all the operands and calls an action routine that you supply. Your action routine performs the steps necessary to handle the exception condition and returns control to LIB$DECODE_FAULT. LIB$DECODE_FAULT then restores the operands and the environment, as modied by the action routine, and continues execution of the instruction.
n = The number of arguments being passed to the exit handler; the exit status counts as the first argument.
ZK2053GE
The rst longword of the structure contains the address of the next handler. The operating system uses this argument to keep track of the established exit handlers; do not modify this value. The second longword of the structure contains the address of the exit handler being established. The low-order byte of the third
Use the language statements to assign the address of the descriptor to one of the longwords in the exit-handler data structure. The following program segment establishes an exit handler with two arguments, the mandatory status argument and a character argument: . . . ! Arguments for exit handler INTEGER EXIT_STATUS ! Status CHARACTER*12 STRING ! String STRUCTURE /DESCRIPTOR/ INTEGER SIZE, 2 ADDRESS END STRUCTURE RECORD /DESCRIPTOR/ EXIT_STRING ! Setup for exit handler STRUCTURE /EXIT_DESCRIPTOR/ INTEGER LINK, 2 ADDR, 2 ARGS /2/, 2 STATUS_ADDR, 2 STRING_ADDR END STRUCTURE RECORD /EXIT_DESCRIPTOR/ HANDLER
Part III
Addressing and Memory Management
This part describes 32-bit and 64-bit address space, and the support offered for 64-bit addressing. It also gives guidelines for 64-bit application programming interfaces (APIs); OpenVMS Alpha, OpenVMS I64, OpenVMS VAX, and VLM memory management with run-time routines for memory management, and alignment on OpenVMS Alpha, OpenVMS VAX, and OpenVMS I64 systems.
10
Overview of Alpha and I64 Virtual Address Space
The OpenVMS Alpha and OpenVMS I64 operating systems provide support for 64-bit virtual memory addressing. This capability makes the 64-bit virtual address space, dened by the Alpha and Intel Itanium architectures, available to the OpenVMS Alpha and OpenVMS I64 operating systems and to application programs. For information about Very Large Memory, see Chapter 16.
Overview of Alpha and I64 Virtual Address Space 10.2 Traditional OpenVMS 32-Bit Virtual Address Space Layout
Unreachable space
FFFFFFFF.7FFFFFFF
S0/S1 Space
The lower half of the OpenVMS VAX virtual address space (addresses between 0 and 7FFFFFFF16 ) is called process-private space. This space is further divided into two equal pieces called P0 space and P1 space. Each space is 1 GB long. The P0 space range is from 0 to 3FFFFFFF16 . P0 space starts at location 0 and expands toward increasing addresses. The P1 space range is from 4000000016 to 7FFFFFFF16 . P1 space starts at location 7FFFFFFF16 and expands toward decreasing addresses. The upper half of the VAX virtual address space is called system space. The lower half of system space (the addresses between 8000000016 and BFFFFFFF16 ) is called S0 space. S0 space begins at 8000000016 and expands toward increasing addresses. The VAX architecture associates a page table with each region of virtual address space. The processor translates system space addresses using the system page table. Each process has its own P0 and P1 page tables. A VAX page table does not map the full virtual address space possible; instead, it maps only the part of its region that has been created.
Overview of Alpha and I64 Virtual Address Space 10.3 OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout
10.3 OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout
The OpenVMS Alpha and OpenVMS I64 64-bit address space layout is an extension of the traditional OpenVMS 32-bit address space layout. Figure 102 illustrates the 64-bit virtual address space layout design.
Note To reduce the complexity of the gure, Figure 102 oversimplies the virtual address space layout. For OpenVMS Alpha, there is a gap in the middle of P2 space, as described in Section 10.3.4. For OpenVMS I64, there is no gap in P2 space. However, as described in Section 10.3.4: Itanium Region 0 is used for P0/P1, P2, and the process-private page table space. Regions 1 through 6 are not used. Itanium Region 7 is used for S0/S1, S2, and the shared page table space.
Only portions of Regions 0 and 7 are used in this release. For both OpenVMS Alpha and OpenVMS I64, the OpenVMS memory management system services always return virtually contiguous address ranges.
Overview of Alpha and I64 Virtual Address Space 10.3 OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout
Figure 102 64-Bit Virtual Address Space Layout
P2 Space
Private PT Space
Shared S2 Space
FFFFFFFF.7FFFFFFF
S0/S1 Space
FFFFFFFF.FFFFFFFF
ZK8384AGE
The 64-bit virtual address space layout is designed to accommodate the current and future needs of the OpenVMS Alpha and OpenVMS I64 operating systems and its users. The address space consists of the following fundamental areas: Process-private space System space Page table space
Overview of Alpha and I64 Virtual Address Space 10.3 OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout
The P0 and P1 spaces are dened to equate to the P0 and P1 regions dened by the VAX architecture. Together, they encompass the traditional 32-bit processprivate region that ranges from 0.0000000016 to 0.7FFFFFFF16 . P2 space encompasses all remaining process space that begins just above P1 space, 0.8000000016 , and ends just below the lowest address of PT space. OpenVMS I64 P2 process space is larger than that of OpenVMS Alpha: 8-TB (-2 GB for P0/P1) for OpenVMS I64, compared with 4-TB for OpenVMS Alpha.
Overview of Alpha and I64 Virtual Address Space 10.3 OpenVMS Alpha and OpenVMS I64 64-Bit Virtual Address Space Layout
I64 has two page table spaces, one for process private in region 0 and one for system space in region 7. If you use only supported interfaces to manage page table entries, this distinction is not visible. However, any code that attempts to compute the page table entry address "by hand" for a given virtual address is not guaranteed to work.
Overview of Alpha and I64 Virtual Address Space 10.4 Virtual Regions
Three process-permanent virtual regions are dened by OpenVMS at the time the process is created: Program region (in P0 space) Control region (in P1 space) 64-bit program region (in P2 space)
These three process-permanent virtual regions exist so that programmers do not have to create virtual regions if their application does not need to reserve additional ranges of address space. Virtual regions promote modularity within applications by allowing different components of the application to manipulate data in different virtual regions. When a virtual region is created, the caller of the service is returned a region ID to identify that virtual region. The region ID is used when creating, manipulating, and deleting virtual addresses within that region. Different components within an application can create separate virtual regions so that their use of virtual memory does not conict. Virtual regions exhibit the following characteristics. A virtual region is a light-weight object. That is, it does not consume pagele quota or working set quota for the virtual addresses specied. Creating a user-dened virtual region by calling a new OpenVMS system service merely denes a virtual address range as a distinct address object within which address space can be created, manipulated, and deleted. Virtual regions do not overlap. When creating address space within a virtual region, the programmer must specify a region ID to the OpenVMS system service. The programmer must specify the virtual region in which the address space is to be created. The programmer cannot create, manipulate, or delete address space that does not lie entirely within the bounds of a dened virtual region. Each user-dened virtual regions size is xed at the time it is created. Given the large range of virtual addresses in P2 space and the light-weight nature of virtual regions, it is not costly to reserve more address space than the application component immediately needs within that virtual region. Note the exception of process-permanent regions, which have no xed size. The 64-bit program virtual region is the only virtual region whose size is not xed when it is created. At process creation, the 64-bit program region encompasses all of P2 space. When a user-dened virtual region is created in P2 space, OpenVMS memory management shrinks the 64-bit program region so that no two regions overlap. When a user-dened virtual region is deleted, the 64-bit program region expands to encompass the virtual addresses within the deleted virtual region if no other user-dened virtual region exists at lower virtual addresses. Each virtual region has an owner mode and a create mode associated with it. Access modes that are less privileged than the owner of the virtual region cannot delete the virtual region. Access modes that are less privileged than the create mode set for the virtual region cannot create virtual addresses within the virtual region. Owner and create modes are set at the time the virtual region is created and cannot be changed. The create mode for a virtual region cannot be more privileged than the owner mode.
Overview of Alpha and I64 Virtual Address Space 10.4 Virtual Regions
When virtual address space is created within a virtual region, allocation generally occurs within the virtual region in a densely expanding manner, as is done within the program (P0 space) and control (P1 space) regions. At the time it is created, each virtual region is set up for the virtual addresses within that virtual region to expand toward either increasing virtual addresses, like P0 space, or decreasing virtual addresses, like P1 space. Users can override this allocation algorithm by explicitly specifying starting addresses. All user-dened virtual regions are deleted along with the pages created within each virtual region at image rundown.
Overview of Alpha and I64 Virtual Address Space 10.4 Virtual Regions
For maximum control of the process-private address space, the application programmer can specify the starting virtual address when creating a virtual region. This is useful in situations when it is imperative that the user be able to specify exact virtual memory layout. Virtual regions can be created so that allocation occurs with either increasing addresses or decreasing virtual addresses. This allows applications with stacklike structures to create virtual address space and expand naturally. Virtual region creation gives OpenVMS subsystems and the application programmer the ability to reserve virtual address space for expansion. For example, an application can create a large virtual region and then create some virtual addresses within that virtual region. Later, when the application requires more virtual address space, it can expand within the virtual region and create more address space in a virtually contiguous manner to the previous addresses allocated within that virtual region. Virtual regions can also be created within P0 and P1 space by specifying VA$M_ P0_SPACE or VA$M_P1_SPACE in the ags argument to the SYS$CREATE_ REGION_64 service. If you do not explicitly delete a virtual region with the SYS$DELETE_REGION_ 64 system service, the user-dened virtual region along with all created address space is deleted when the image exits.
11
Support for 64-Bit Addressing (Alpha and I64 Only)
This chapter describes the following features that support 64-bit addressing: System services, descriptors, and item lists RMS interfaces File systems OpenVMS Alpha and OpenVMS I64 64-bit API guidelines OpenVMS Alpha and OpenVMS I64 tools and utilities Language and pointers HP C RTLs
For information about MACRO-32 programming support for 64-bit addressing, see HP OpenVMS MACRO Compiler Porting and Users Guide.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Examples of routines with 64-bit unfriendly interfaces are most of the memory management system services, such as $CRETVA, $DELTVA, and $CRMPSC. The INADR and RETADR argument arrays do not promote easily to hold 64-bit addresses. 64-bit system service A 64-bit system service is a system service that is dened to accept all address arguments as 64-bit addresses (not necessarily 32-bit, sign-extended values). Also, a 64-bit system service uses the entire 64 bits of all virtual addresses passed to it. The 64-bit system services include the _64 sufx for services that accept 64-bit addresses by reference. For promoted services, this distinguishes the 64-bit capable version from its 32-bit counterpart. For new services, it is a visible reminder that a 64-bit wide address cell will be read/written. This is also used when a structure is passed that contains an embedded 64-bit address, if the structure is not self-identifying as a 64-bit structure. Hence, a routine name need not include _64 simply because it receives a 64-bit descriptor. Remember that passing an arbitrary value by reference does not mean the sufx is required; passing a 64-bit address by reference does.
The two forms are compatible, because they can be identied dynamically at run time, and except for the size and placement of elds, 32-bit and 64-bit descriptors are identical in content and interpretation. OpenVMS VAX, OpenVMS Alpha, and OpenVMS I64 systems use 32-bit descriptors. When used on OpenVMS Alpha and OpenVMS I64 systems, 32bit descriptors provide full compatibility with their use on OpenVMS VAX. The 64-bit descriptors are used only on OpenVMS Alpha and OpenVMS I64 systems. They have no counterparts and are not recognized on OpenVMS VAX systems. Figure 111 shows the general descriptor format for a 32-bit descriptor.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Figure 111 General Format of a 32-Bit Descriptor
CLASS
DTYPE POINTER
LENGTH
:0 :4
ZK4663AGE
Figure 112 shows the general descriptor format for a 64-bit descriptor. Figure 112 General Format of a 64-Bit Descriptor
64Bit Form (DSC64) quadword aligned CLASS DTYPE MBMO (=1) MBO (=1) :0 :4 :8 LENGTH
:16 POINTER
ZK7656AGE
When 32-bit descriptors are used on OpenVMS Alpha and OpenVMS I64 systems, they have no required alignment for compatibility with OpenVMS VAX systems, even though longword alignment usually promotes better performance. The 64-bit descriptors on OpenVMS Alpha and OpenVMS I64 systems must be quadword aligned. Table 111 shows the elds and meanings for both 32-bit and 64-bit descriptors. Because CLASS and DTYPE elds occupy the same offsets in both 32-bit and 64-bit descriptors, these two elds have the same denition, and can contain the same values with the same meanings in both 32-bit and 64-bit forms.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Table 111 Contents of the General Descriptor Format
Field Length MBO Description The data item length specic to the descriptor class. In a 64-bit descriptor, this eld must contain the value 1. This eld overlays the length eld of a 32-bit descriptor and the value 1 is necessary to distinguish correctly between the two forms. A data-type code. A descriptor class code that identies the format and interpretation of the other elds of the descriptor. The address of the rst byte of the data element described. In a 64-bit descriptor, this eld must contain the value -1 (all 1 bits). This eld overlays the pointer eld of a 32-bit descriptor and the value -1 is necessary to distinguish correctly between the two forms.
For extensive information about 32-bit and 64-bit descriptors, see Chapter 17. Section 11.4 provides serveral recommendations and guidelines on implementing 64-bit descriptors. It is recommended programming practice to use STR$ Run-Time Library routines when using descriptors. Using STR$ RTL procedures helps ensure correct operation of complex language features and enforces consistent operations on data access languages. For example, STR$ANALYZE_SDESC and STR$ANALYZE_ SDESC_64 take as input a 32-bit or 64-bit descriptor argument and extract from the descriptor the length of the data and the address at which the data starts for a variety of string descriptor classes. For complete information on using STR$ routines, see the OpenVMS RTL String Manipulation (STR$) Manual.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
in the item descriptor species the address of the next item list to be processed. Similarly, the LNM$_CHAIN item code of $CRELNM and JPI$_CHAIN item code of $GETJPI system services, point to another item list that the respective system service is to process immediately after it has processed the current item list. Item lists of 32-bits and 64-bits can be chained together. Item list segments are the elements that get linked together to form item lists. 11.1.3.1 32-Bit Item Lists Item lists do not have a formal denition. As a result, there is some variance in their use, but nearly every use consists of a list of one of two forms, referred to as the following: item_list_2 item_list_3
In both forms, an item code typically identies the data item to be set or fetched, and a buffer length and address describe the buffer to be read from or written to. The item codes are specic to the facility being called. Figure 113 shows the format of the item_list_2 item list. Figure 113 Item_list_2 Format
Buffer Length
:0 :4
VM-0971A-AI
Figure 114 shows the format of the item_list_3 item list. Figure 114 Item_list_3 Format
Buffer Length
:0 :4 :8
VM-0972A-AI
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
The following table denes the elds for 32-bit item list entries:
Field Buffer length Description A word containing a user-supplied integer specifying the length (in bytes) of the buffer in which the service is to write the information. The length of the buffer needed depends on the item code specied in the item code eld of the item descriptor. A word containing a user-supplied symbolic code specifying the item of information that a service is to return. A longword containing the user-supplied 32-bit address of the buffer in which a service is to write the information. A longword containing the user-supplied 32-bit address of a word in which a service writes the length (in bytes) of the information it actually returned.
Item code
You typically use the item_list_3 format when the list describes a series of data items to be returned. This format includes a return length address longword, which is the address of a location in which to write the (word) length of data actually written to the buffer. For item_list_3 entries, you can set the Return Length Address eld to point to the Buffer Length eld in the item list entry itself. As a result, the "descriptorlike" portion of the entry is updated by the routine returning the value. 11.1.3.2 64-Bit Item Lists To maintain a degree of compatibility with the 32-bit item lists, 64-bit item lists mirror the denition of 64-bit descriptors. The names of 32-bit item lists (item_list_2 and item_list_3), which expose the number of longwords in the structure in the name itself, do not apply to 64-bit item lists. The 64-bit versions (item_list_64a and item_list_64b) do not include an element count. Figure 115 shows the format of the item_list_64a item list. Figure 115 Item_list_64a Format
ITEM CODE (MBMO) (MBO)
:0 :4 :8
BUFFER LENGTH
ZK9016AGE
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Figure 116 shows the format of the item_list_64b item list. Figure 116 Item_list_64b Format
ITEM CODE (MBMO) (MBO)
:0 :4 :8
BUFFER LENGTH
ZK9017AGE
The following table denes the item descriptor elds for 64-bit item list entries:
Field MBO Item code Description The eld must contain a 1. The MBO and MBMO elds are used to distinguish 32-bit and 64-bit item list entries. A word containing a user-supplied symbolic code that describes the information in the buffer or the information to be returned to the buffer, pointed to by the buffer address eld. The eld must contain a -1. The MBMO and MBO elds are used to distinguish 32-bit and 64-bit item list entries. A quadword containing a user-supplied integer specifying the length (in bytes) of the buffer in which a service is to write the information. The length of the buffer needed depends on the item code specied in the item code eld of the item descriptor. A quadword containing the user-supplied 64-bit address of the buffer in which a service is to write the information. A quadword containing the user-supplied 64-bit address of a word in which a service writes the length (in bytes) of the information it actually returned.
Because they contain quadword entries, 64-bit item lists should be quadword aligned. If a misaligned list is specied, the called routine still functions properly, but a performance penalty results due to alignment faults. By maintaining a degree of compatibility between 32-bit and 64-bit item lists, the following advantages result: The 64-bit form is easily distinguished from the 32-bit form by routines receiving them as arguments.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
The item lists continue to demonstrate the behavior that if a 32-bit facility is incorrectly handed as a 64-bit item list, it fails predictably. The buffer address of -1 and the length eld of 1 are guaranteed to result in an access violation. The same result comes from passing a 64-bit item list entry to a routine expecting a 32-bit string descriptor. Passing a 64-bit item list element to a routine expecting a 64-bit descriptor is as reliable as it is for their 32-bit counterparts.
Section 11.4 provides several recommendations and guidelines on implementing 64-bit item lists.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Table 112 (Cont.) 64-Bit System Services
Service CPU Scheduling System Services $CPU_CAPABILITIES $CPU_TRANSITION(W) $FREE_USER_CAPABILITY $GET_USER_CAPABILITY $PROCESS_AFFINITY $PROCESS_CAPABILITIES $SET_IMPLICIT_AFFINITY Event Flag System Service $READEF Fast-I/O System Services $IO_CLEANUP $IO_PERFORM $IO_PERFORMW $IO_SETUP fandle fandle, chan, iosadr, bufadr, buen, porint fandle, chan, iosadr, bufadr, buen, porint func, bufobj, iosobj, astadr, ags, return_fandle efn, state_64 cpu_id, select_mask, modify_mask, prev_mask, ags tran_code, cpu_id, nodename, node_id, ags, efn, iosb, astadr_ 64, astprm_64 cap_num, prev_mask, ags cap_num, select_num, select_mask, prev_mask, ags pidadr, prcnam, select_mask, modify_mask, prev_mask, ags pidadr, prcnam, select_mask, modify_mask, prev_mask, ags pidadr, prcnam, state, cpu_id, prev_mask Arguments
Intra-Cluster Communications System Services SYS$ICC_ACCEPT SYS$ICC_CONNECT(W) conn_handle, accept_buf, accept_len, user_context, ags ios_icc, astadr, astprm, assoc_handle, conn_handle, remote_ assoc, remote_node, user_context, conn_buf, conn_buf_len, return_buf, return_buf_len, retlen_addr, ags conn_handle, iosb, astadr, astprm, disc_buf, disc_buf_len asoc_handle, assoc_name, logical_name, logical_table, conn_ event_rtn, disc_event_rtn, recv_rtn, maxowbufcut, prot conn_handle, ios_icc, astadr, astprm, recv_buf, recv_buf_len conn_handle, reject_buf, reject_buf_len, reason conn_handle, ios_icc, astadr, astprm, reply_buf, reply_len conn_handle, ios_icc, astadr, astprm, send_buf, send_len conn_handle, ios_icc, astadr, astprm, send_buf, send_len
SYS$ICC_DISCONNECT(W) SYS$ICC_OPEN_ASSOC SYS$ICC_RECEIVE(W) SYS$ICC_REJECT SYS$ICC_REPLY(W) SYS$ICC_TRANSCEIVE(W) SYS$ICC_TRANSMIT(W) I/O System Services $ASSIGN $QIO(W)
1
devnam, chan, acmode, mbxnam, ags efn, chan, func, iosb_64, astadr_64, astprm_64, p1_64, p2_64, p3_64, p4_64, p5_64, p6_64 efn, iosb_64
$SYNCH
1 For more information about the $QIO(W) arguments that support 64-bit addressing, see Writing OpenVMS Alpha Device Drivers in C, and HP OpenVMS Guide to Upgrading Privileged-Code Applications.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Table 112 (Cont.) 64-Bit System Services
Service Locking System Services $DEQ $ENQ(W) lkid, vablk_64, acmode, ags efn, lkmode, lksb_64, ags, resnam_64, parid, astadr_64, astprm_64, blkast_64, acmode Arguments
Logical Name System Services $CRELNM $CRELNT $DELLNM $TRNLNM Memory Management System Services $ADJWSL $CREATE_BUFOBJ_64 $CREATE_GDZRO $CRMPSC_GDZRO_64 $CREATE_GFILE $CREATE_GPFILE $CREATE_GPFN $CREATE_REGION_64 $CRETVA_64 $CRMPSC_FILE_64 $CRMPSC_GFILE_64 pagcnt, wsetlm_64 start_va_64, length_64, acmode, ags, return_va_64, return_ length_64, return_buffer_handle_64 gsdnam_64, ident_64, prot, length_64, acmode, ags, ... gsdnam_64, ident_64, prot, length_64, region_id_64, section_ offset_64, acmode, ags, return_va_64, return_length_64, ... gsdnam_64, ident_64, le_offset_64, length_64, chan, acmode, ags, return_length_64, ... gsdnam_64, ident_64, prot, length_64, acmode, ags gsdnam_64, ident_64, prot, start_pfn, page_count, acmode, ags length_64, region_prot, ags, return_region_id_64, return_va_ 64, return_length_64, ... region_id_64, start_va_64, length_64, acmode, ags, return_va_ 64, return_length_64 region_id_64, le_offset_64, length_64, chan, acmode, ags, return_va_64, return_length_64, ... gsdnam_64, ident_64, le_offset_64, length_64, chan, region_id_ 64, section_offset, acmode, ags, return_va_64, return_length_ 64, ... gsdnam_64, ident_64, prot, length_64, region_id_64, section_ offset_64, acmode, ags, return_va_64, return_length_64, ... gsdnam_64, ident_64, prot, start_pfn, page_count, region_id_64, relative_page, acmode, ags, return_va_64, return_length_64, ... region_id_64, start_pfn, page_count, acmode, ags, return_va_ 64, return_length_64, ... buffer_handle_64 region_id_64, acmode, return_va_64, return_length_64 region_id_64, start_va_64, length_64, acmode, return_va_64, return_length_64 (continued on next page) attr, tabnam, lognam, acmode, itmlst ttr, resnam, reslen, quota, promsk, tabnam, partab, acmode tabnam, lognam, acmode attr, tabnam, lognam, acmode, itmlst
$CRMPSC_GPFILE_64 $CRMPSC_GPFN_64
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Table 112 (Cont.) 64-Bit System Services
Service Memory Management System Services $DGBLSC $EXPREG_64 $GET_REGION_INFO $LCKPAG_64 $LKWSET_64 $MGBLSC_64 $MGBLSC_GPFN_64 $PURGE_WS $SETPRT_64 $ULKPAG_64 $ULWSET_64 $UPDSEC_64(W) ags, gsdnam_64, ident_64 region_id_64, length_64, acmode, ags, return_va_64, return_ length_64 function_code, region_id_64, start_va_64, ,buffer_length, buffer_ address_64, return_length_64 start_va_64, length_64, acmode, return_va_64, return_length_ 64 start_va_64, length_64, acmode, return_va_64, return_length_ 64 gsdnam_64, ident_64, region_id_64, section_offset_64, length_ 64, acmode, ags, return_va_64, return_length_64, ... gsdnam_64, ident_64, region_id_64, relative_page, page_count, acmode, ags, return_va_64, return_length_64, ... start_va_64, length_64 start_va_64, length_64, acmode, prot, return_va_64, return_ length_64, return_prot_64 start_va_64, length_64, acmode, return_va_64, return_length_ 64 start_va_64, length_64, acmode, return_va_64, return_length_ 64 start_va_64, length_64, acmode, updg, efn, iosa_64, return_ va_64, return_length_64, ... Arguments
Process Control System Services $GETJPI(W) $PROCESS_SCAN $WAKE Time System Services $ASCTIM $ASCUTC $BINTIM $BINUTC $CANTIM $GETTIM $GETUTC $NUMTIM $NUMUTC $SETIME $SETIMR timlen, timbuf, timadr, cvtg timlen, timbuf, utcadr, cvtg timbuf, timadr timbuf, utcadr reqidt_64, acmode timadr_64 utcadr timbuf, timadr timbuf, utcadr timadr efn, daytim_64, astadr_64, reqidt_64, ags (continued on next page) efn, pidadr, prcnam, itmlst, iosb, astadr, astprm pidctx, itmlst pidadr, prcnam
Support for 64-Bit Addressing (Alpha and I64 Only) 11.1 System Services Support for 64-Bit Addressing
Table 112 (Cont.) 64-Bit System Services
Service Time System Services $TIMCON Other System Services $ASCTOID $CLEAR_UNWIND_TABLE $CMEXEC_64 $CMKRNL_64 $FINISH_RDB $GETSYI(W) $GET_UNWIND_ENTRY_INFO $GOTO_UNWIND_64 $IDTOASC $SET_UNWIND_TABLE name, id, attrib code_base_va routine_64, quad_arglst_64 routine_64, quad_arglst_64 context efn, csidadr, nodename, itmlst, iosb, astadr, astprm pc, get_ue_block, name target_invo, target_pc, [NewRetVal], [NewRetVal2] id, namlen, nambuf, resid, attrib, contxt code_base_va, code_size, ut_base_va, ut_size, gp_value, unwind_info_base, name timadr, utcadr, cvtg Arguments
Support for 64-Bit Addressing (Alpha and I64 Only) 11.2 RMS Interface Features for 64-Bit Addressing
RBF (record buffer) RHB (xed-length record header buffer; xed portion of VFC record format) KBF (key buffer containing the key value for random access)
The prompt buffer pointed to by RAB$L_PBF is excluded because the terminal driver does not allow 64-bit addresses. Specic features of the RMS interface for 64-bit addressing are as follows: Data buffers can be placed in P2 or S2 space for the following user I/O services: Record I/O services: $GET, $FIND, $PUT, $UPDATE Block I/O services: $READ, $WRITE The RAB structure points to the record and data buffers used by these services. An extension of the existing RAB structure is used to specify 64-bit buffer pointers and sizes. The buffer size maximum for RMS block I/O services ($READ and $WRITE) is 2 GB, with two exceptions: For RMS journaling, a journaled $WRITE service is restricted to the current maximum (65535 minus 99 bytes of journaling overhead). An RSZ error is returned to RAB$L_STS if the maximum is exceeded. Magnetic tape is still limited to 65535 bytes at the device driver level. The rest of the RMS interface currently is restricted to 32-bit pointers: FAB, RAB, NAM, and XABs must still be allocated in 32-bit space. Any descriptors or embedded pointers to le names, item lists, and so on, must continue to use 32-bit pointers. Any arguments passed to the RMS system services remain 32-bit arguments. If you attempt to pass a 64-bit argument, the SS$_ARG_GTR_32_BITS error is returned.
64bit extension
ZK8425AGE
The RAB64 contains elds identical to all of the RAB elds except that eld names have the RAB64 prex instead of the RAB prex. In addition, RAB64 has the following elds in the extension:
Support for 64-Bit Addressing (Alpha and I64 Only) 11.2 RMS Interface Features for 64-Bit Addressing
Is an extension of this eld RAB64$L_CTX
Description User context. This eld is not used by RMS but is available to the user. The CTX eld is often used to contain a pointer. For asynchronous I/O, it provides the user with the equivalent of an AST parameter. Key buffer address containing the key value for random access (for $GET and $FIND). Record buffer address (for $PUT, $UPDATE, and $WRITE). Record header buffer address (xed portion of VFC record format). Record buffer size. User buffer address (for $GET and $READ). User buffer size.
Note that the elds with the PQ tag in their names can hold either a 64-bit address or a 32-bit address sign-extended to 64 bits. Therefore, you can use the elds in all applications whether or not you are using 64-bit addresses. For most record I/O service requests, there is an RMS internal buffer between the device and the users data buffer. The one exception occurs with the RMS service $PUT. If the device is a unit record device and it is not being accessed over the network, RMS passes the address of the user record buffer (RBF) to the $QIO system service. If you inappropriately specify a record buffer (RBF) allocated in 64-bit address space for a $PUT to a unit record device that does not support 64-bit address space (for example, a terminal), the $QIO service returns SS$_NOT64DEVFUNC. (See Writing OpenVMS Alpha Device Drivers in C and HP OpenVMS Guide to Upgrading Privileged-Code Applications for more information about $QIO.) RMS returns the error status RMS$_SYS with SS$_NOT64DEVFUNC as the secondary status value in RAB64$L_STV. RMS system services support the RAB structure as well as the RAB64 structure.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.2 RMS Interface Features for 64-Bit Addressing
The source module uses the value in the quadword size eld only if the contents of the 32-bit address eld designate its use. For example:
If this address eld contains -1 RAB64$L_UBF RAB64$L_RBF RAB64$L_KBF RAB64$L_RHB
1 This
And the size in this eld is used RAB64$Q_USZ RAB64$Q_RSZ RAB64$B_KSZ FAB$B_FSZ
RAB64$PQ_KBF RAB64$PQ_RHB
eld can contain either a 64-bit address or a 32-bit address sign-extended to 64 bits.
While RMS allows you to use the RAB64 wherever you can use a RAB, some source languages may impose other restrictions. Consult the documentation for your source language for more information.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.2 RMS Interface Features for 64-Bit Addressing
Values assigned to the keywords UBF, USZ, RBF, RSZ, RHB, or KBF are moved into the quadword elds for these keywords. (In contrast, the $RAB and $RAB_INIT macros move these values into the longword [or word] elds for these keywords.) The third macro allocates a block structure of bytes with a length of RAB$C_BLN64.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
Routines should guard against programming errors where 64-bit addresses are being passed instead of 32-bit addresses. This type of checking is called sign-extension checking, which means that the address is checked to ensure that the upper 32 bits are all zeros or all ones, matching the value of bit 31. This checking can be performed at the routine interface that is imposing this restriction. When dening a new routine interface, you should consider the ease of programming a call to the routine from a 32-bit source module. You should also consider calls written in all OpenVMS programming languages, not just those languages initially supporting 64-bit addressing. To avoid promoting awkward programming practices for the 32-bit caller of a new routine, you should accommodate 32-bit callers as well as 64-bit callers. Arguments passed by reference that are restricted to reside in a 32-bit address space (P0/P1/S0/S1) should have their reference addresses sign-extension checked. The OpenVMS Calling Standard requires that 32-bit values passed to a routine be sign-extended to 64-bits before the routine is called. Therefore, the called routine always receives 64-bit values. A 32-bit routine cannot tell if its caller correctly called the routine with a 32-bit address, unless the reference to the argument is checked for sign-extension. This sign-extension checking would also apply to the reference to a descriptor when data is being passed to a routine by descriptor. The called routine should return the error status SS$_ARG_GTR_32_BITS if the sign-extension check fails. Alternately, if you want the called routine to accept the data being passed in a 64-bit location without error and if the sign-extension check fails, the data can be copied by the called routine to a 32-bit address space. The 32-bit address space to which the routine copies the data can be local routine storage (that is, the current stack). If the data is copied to a 32-bit location other than local storage, memory leaks and reentrancy issues must be considered. When new routines are developed, pointers to code and all data pointers passed to the new routines should be accommodated in 64-bit address spaces where possible. This is desirable even if the data is a routine or is typically considered static data, which the programmer, compiler, or linker would not normally put in a 64-bit address space. When code and static data is supported in 64-bit address spaces, this routine should not need additional changes. 32-bit descriptor arguments should be validated to be 32-bit descriptors. Routines that accept descriptors should test the elds that allow you to distinguish the 32-bit and 64-bit descriptor forms. If a 64-bit descriptor is received, the routine should return an error. Most existing 32-bit routines will return or signal the error status SS$_ACCVIO when incorrectly presented with a 64-bit descriptor for the following reasons: The 64-bit form of a descriptor contains an MBO (must be one) word at offset 0, where the 32-bit descriptor LENGTH is located, and An MBMO (must be minus one) longword at offset 4, where the 32-bit descriptors POINTER is located, as shown in the following gure:
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
CLASS
DTYPE (MBMO)
(MBO)
:0
:8 LENGTH
:16 POINTER
ZK8489AGE
Routines that accept arguments passed by 64-bit descriptors should accommodate 32-bit descriptors as well as 64-bit descriptors. New routines should accommodate 32-bit and 64-bit descriptors within the same routine. The same argument can point to either a 32-bit or 64-bit descriptor. The 64-bit descriptor MBO word at offset 0 should be tested for 1, and the 64-bit descriptor MBMO longword at offset 4 should be tested for a -1 to distinguish between a 64-bit and 32-bit descriptor. Consider an existing 32-bit routine that is being converted to handle 64-bit as well as 32-bit descriptors. If the input descriptor is determined to be a 64-bit descriptor, the data being pointed to by the 64-bit descriptor can rst be copied to a 32-bit memory location, then a 32-bit descriptor would be created in 32-bit memory. This new 32-bit descriptor can then be passed to the existing 32-bit code, so that no further modications need to be made internally to the routine. 32-bit item list arguments should be validated to be 32-bit item lists. Two forms of item lists are dened: item_list_2 and item_list_3. The item_list_2 form of an item list consists of two longwords with the rst longword containing a length and item code elds, while the second longword typically contains a buffer address. The item_list_3 form of an item list consists of three longwords with the rst longword containing a length and item code elds, while the second and third longwords typically contain a buffer address and a return length address eld. Since two forms of 32-bit item lists exist, two forms of a 64-bit item list are dened. Dubbed item_list_64a and item_list_64b, these item list forms parallel their 32-bit counterparts. Both forms of item list contain the MBO and MBMO elds at offsets 0 and 4 respectively. They also each contain a word-sized item code eld, a quadword-sized length eld, and a quadword-sized buffer address eld. The item_list_64b form of an item list contains an additional quadword for the return length address eld. The returned length is 64-bits. Routines that accept item lists should test the elds that allow you to distinguish the 32-bit and 64-bit item list forms. If a 64-bit item list is received, the routine should return an error. Most existing 32-bit routines will return or signal the error status SS$_ACCVIO when incorrectly presented with a 64-bit item list for the following reasons: The 64-bit form of an item list contains an MBO (must be one) word at offset 0, where the 32-bit item list LENGTH is located, and
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
An MBMO (must be minus one) longword at offset 4, where the 32-bit item lists BUFFER ADDRESS is located as shown in Figure 117 and Figure 118.
:0 :4 :8
BUFFER LENGTH
ZK9016AGE
:0 :4 :8
BUFFER LENGTH
ZK9017AGE
Routines that accept arguments passed by 64-bit item list arguments should accommodate 32-bit item lists as well as 64-bit item lists. New routines should accommodate 32-bit and 64-bit item lists within the same routine. The same argument can point to either a 32-bit or 64-bit item list. The 64-bit item list MBO word at offset 0 should be tested for 1, and the 64-bit item list MBMO longword at offset 4 should be tested for a -1 to distinguish between a 64-bit and 32-bit item list. Avoid passing pointers by reference. If passing a pointer by reference is necessary, as with certain memory management routines, the pointer should be dened to be 64-bit wide. Mixing 32-bit and 64-bit pointers can cause programming errors when the caller incorrectly passes a 32-bit wide pointer by reference when a 64-bit wide pointer is expected.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
If the called routine reads a 64-bit wide pointer that was allocated only one longword by the programmer, the wrong address could be used by the routine. If the called routine returns a 64-bit pointer, and therefore writes a 64-bit wide address into a longword allocated by the programmer, data corruption can occur. Existing routines that are passed pointers by reference require new interfaces for 64-bit support. Old routine interfaces would still be passed the pointer in a 32-bit wide memory location and the new routine interface would require that the pointer be passed in a 64-bit wide memory location. Keeping the same interface and passing it 64-bit wide pointers would break existing programs. Example: The return virtual address used in the SYS$CRETVA_64 service is an example of when it is acceptable to pass a pointer by reference. Virtual addresses created in P0 and P1 space are guaranteed to have only 32 bits of signicance, however all 64 bits are returned. SYS$CRETVA_64 can also create address space in 64-bit space and thus return a 64-bit address. The value that is returned must always be 64 bits because a 64-bit address can be returned. Memory allocation routines should return the pointer to the data allocated by value (that is, in R0), if possible. The C allocation routines, malloc, calloc, and realloc are examples of this. New interfaces for routines that are not memory management routines should avoid dening output arguments to receive addresses. Problems will arise whenever a 64-bit subsystem allocates memory and then returns a pointer back to a 32-bit caller in an output argument. The caller may not be able to support or express a 64-bit pointer. Instead of returning a pointer to some data, the caller should provide a pointer to a buffer and the called routine should copy the data into the users buffer. A 64-bit pointer passed by reference should be dened by the programmer in such a way that a call to the routine can be written in a 64-bit language or a 32-bit language. It should be clearly indicated that a 64-bit pointer is required to be passed by all callers. Routines must not return 64-bit addresses unless they are specically requested. It is extremely important that routines that allocate memory and return an address to their callers always allocate 32-bit addressable memory, unless it is known absolutely that the caller is capable of handling 64-bit addresses. This is true for both function return values and output parameters. This rule prevents 64-bit addresses from creeping in to applications that do not expect them. As a result, programmers developing callable libraries should be particularly careful to follow this rule. Suppose an existing routine returns the address of memory it has allocated, such as the routine value. If the routine accepts an input parameter that in some way allows it to determine that the caller is 64-bit capable, it is safe to return a 64-bit address. Otherwise, it must continue to return a 32-bit, sign-extended address. In the latter case, a new version of the routine could be provided, which 64-bit callers could invoke instead of the existing version if they prefer that 64-bit memory be allocated. Example: The routines in LIBRTL that manipulate string descriptors can be sure that a caller is 64-bit capable if the descriptor passed in is in the new 64bit format. As a result, it is safe for them to allocate 64-bit memory for string data, in that case. Otherwise, they will continue to use only 32-bit addressable memory.
1120 Support for 64-Bit Addressing (Alpha and I64 Only)
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
Avoid embedded pointers in data structures in public interfaces. If embedded pointers are necessary for a new structure in a new interface, provide storage within the structure for a 64-bit pointer (quadword aligned). The called routine, which may have to read the pointer from the structure, simply reads all 64 bits. If the pointer must be a 32-bit, sign-extended address (for example, because the pointer will be passed to a 32-bit routine) a sign-extension check should be performed on the 64-bit pointer at the entrance to the routine. If the signextension check fails, the error status SS$_ARG_GTR_32_BITS may be returned to the caller, or the data in a 64-bit address space may be copied to a 32-bit address space. The new structure should be dened by the programmer in such a way that a 64-bit caller or a 32-bit caller does not contain awkward code. The structure should provide a quadword eld for the 64-bit caller overlaid with two longword elds for the 32-bit caller. The rst of these longwords is the 32-bit pointer eld and the next is an MBSE (must be sign-extension) eld. For most 32-bit callers, the MBSE eld will be zero because the pointer will be a 32-bit process space address. The key here is to dene the pointer as a 64-bit value and make it clear to the 32-bit caller that the full quadword must be lled in. In the following example, both 64-bit and 32-bit callers would pass a pointer to the block structure and use the same function prototype when calling the function routine. (Assume data is an unknown structure dened in another module.) #pragma required_pointer_size save #pragma required_pointer_size 32 typedef struct block { int blk_l_size; int blk_l_flags; union { #pragma required_pointer_size 64 struct data *blk_pq_pointer; #pragma required_pointer_size 32 struct { struct data *blk_ps_pointer; int blk_l_mbse; } blk_r_long_struct; } blk_r_pointer_union; } BLOCK; #define #define #define #define blk_pq_pointer blk_r_long_struct blk_ps_pointer blk_l_mbse blk_r_pointer_union.blk_pq_pointer blk_r_pointer_union.blk_r_long_struct blk_r_long_struct.blk_ps_pointer blk_r_long_struct.blk_l_mbse
/* Routine accepts 64-bit pointer to the "block" structure */ #pragma required_pointer_size 64 int routine(struct block*); #pragma required_pointer_size restore For an existing 32-bit routine specifying an input argument, which is a structure that embeds a pointer, you can use a different approach to preserve the existing 32-bit interface. You can develop a 64-bit form of the data structure that is distinguished from the 32-bit form of the structure at run time. Existing code that accepts only the 32-bit form of the structure should automatically fail when presented with the 64-bit form.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
The structure denition for the new 64-bit structure should contain the 32-bit form of the structure. Including the 32-bit form of the structure allows the called routine to declare the input argument as a pointer to the 64-bit form of the structure and cleanly handle both cases. Two different function prototypes can be provided for languages that provide type checking. The default function prototype should specify the argument as a pointer to the 32-bit form of the structure. The programmer can select the 64-bit form of the function prototype by dening a symbol, specied by documentation. The 64-bit versus 32-bit descriptor is an example of how this can be done. Example: In the following example, the state of the symbol FOODEF64 selects the 64-bit form of the structure along with the proper function prototype. If the symbol FOODEF64 is undened, the old 32-bit structure is dened and the old 32-bit function prototype is used. The source module that implements the function foo_print would dene the symbol FOODEF64 and be able to handle calls from 32-bit and 64-bit callers. The 64-bit caller would set the eld foo64$l_mbmo to -1. The routine foo_print would test the eld foo64$l_mbmo for -1 to determine if the caller used either the 64-bit form of the structure or the 32-bit form of the structure. #pragma required_pointer_size save #pragma required_pointer_size 32 typedef struct foo { short int foo$w_flags; short int foo$w_type; struct data * foo$ps_pointer; } FOO; #ifndef FOODEF64 /* Routine accepts 32-bit pointer to "foo" structure */ int foo_print(struct foo * foo_ptr); #endif #ifdef FOODEF64 typedef struct foo64 { union { struct { short int foo64$w_flags; short int foo64$w_type; int foo64$l_mbmo; #pragma required_pointer_size 64 struct data * foo64$pq_pointer; #pragma required_pointer_size 32 } foo64$r_foo64_struct; FOO foo64$r_foo32; } foo64$r_foo_union; } FOO64; #define #define #define #define #define foo64$w_flags foo64$w_type foo64$l_mbmo foo64$pq_pointer foo64$r_foo32 foo64$r_foo_union.foo64$r_foo64_struct.foo64$w_flags foo64$r_foo_union.foo64$r_foo64_struct.foo64$w_type foo64$r_foo_union.foo64$r_foo64_struct.foo64$l_mbmo foo64$r_foo_union.foo64$r_foo64_struct.foo64$pq_pointer foo64$r_foo_union.foo64$r_foo32
/* Routine accepts 64-bit pointer to "foo64" structure */ #pragma required_pointer_size 64 int foo_print(struct foo64 * foo64_ptr); #endif
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
#pragma required_pointer_size restore In the previous example, if the structures foo and foo64 will be used interchangeably within the same source module, you can eliminate the symbol FOODEF64. The routine foo_print would then be dened as follows: int foo_print (void * foo_ptr); Eliminating the FOODEF64 symbol allows 32-bit and 64-bit callers to use the same function prototype; however less strict type checking is then available during the C source compilation.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
64-bit routines should accept 32-bit forms of structures as well as 64-bit forms. To make it easy to modify calls to an API, the 32-bit form of a structure should be accepted by the interface as well as the 64-bit form. Example: If the 32-bit API passed information by descriptor, the new interface should pass the same information by descriptor. 64-bit routines should provide the same functionality as the 32-bit routines. An application currently calling the 32-bit API should be able to completely upgrade to calling the 64-bit API without having to preserve some of the old calls to the old 32-bit API just because the new 64-bit API is not a functional superset of the old API. Example: SYS$EXPREG_64 works for P0, P1 and P2 process space. Callers can replace all calls to SYS$EXPREG since SYS$EXPREG_64 is a functional superset of $EXPREG. Use the sufx _64 when appropriate. For system services, this sufx is used for routines that accept 64-bit addresses by reference. For promoted routines, this distinguishes the 64-bit capable version from its 32-bit counterpart. For new routines, it is a visible reminder that a 64-bit wide address cell will be read/written. This is also used when a structure is passed that contains an embedded 64-bit address, if the structure is not selfidentifying as a 64-bit structure. Hence, a routine name need not include "_ 64" simply because it receives a 64-bit descriptor. Remember that passing an arbitrary value by reference does not mean the sufx is required, passing a 64-bit address by reference does. This practice is recommended for other routines as well. Examples: SYS$EXPREG_64 (region_id_64, length_64, acmode, return_va_64, return_ length_64) SYS$CMKRNL_64 (routine_64, quad_arglst_64)
Support for 64-Bit Addressing (Alpha and I64 Only) 11.4 OpenVMS Alpha and OpenVMS I64 64-Bit API Guidelines
#pragma required_pointer_size save #pragma required_pointer_size 64 int sys$cretva_64 ( struct _generic_64 * region_id_64, void * start_va_64, unsigned __int64 length_64, unsigned int acmode, void ** return_va_64, unsigned __int64 * return_length_64); #pragma required_pointer_size restore The new routine interface for SYS$CRETVA_64 corrects the embedded pointers within the _va_range structure, passes the 64-bit region_id_64 argument by reference and passes the 64-bit length_64 argument by value.
11.5 OpenVMS Alpha and OpenVMS I64 Tools and Utilities That Support 64-Bit Addressing
This section briey describes the following OpenVMS Alpha and OpenVMS I64 tools that support 64-bit virtual addressing: OpenVMS Debugger System-code debugger XDELTA LIB$ and CVT$ facilities of the OpenVMS Run-Time Library Watchpoint utility (The Watchpoint utility has not been ported to OpenVMS I64.) SDA
Support for 64-Bit Addressing (Alpha and I64 Only) 11.5 OpenVMS Alpha and OpenVMS I64 Tools and Utilities That Support 64-Bit Addressing 11.5.2 OpenVMS Alpha System-Code Debugger
The OpenVMS Alpha system-code debugger accepts 64-bit addresses and uses full 64-bit addresses to retrieve information.
11.5.3 Delta/XDelta
XDELTA supports 64-bit addressing on OpenVMS Alpha and OpenVMS I64. Quadword display mode displays full quadwords of information. 64-bit address display mode accepts and displays all addresses as 64-bit quantities. XDELTA has predened command strings for displaying the contents of the PFN database. For more information about Delta/XDelta, see the HP OpenVMS Delta/XDelta Debugger Manual.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.5 OpenVMS Alpha and OpenVMS I64 Tools and Utilities That Support 64-Bit Addressing 11.5.6 SDA
SDA allows a user to specify 64-bit addresses and 64-bit values in expressions. It also displays full 64-bit values where appropriate. The following commands have been enhanced or are new in OpenVMS Version 8.2 for I64 use. EVALUATE EXAMINE FORMAT READ SET CPU SHOW CALL_FRAME CPU CRASH DEVICE EXCEPTION_FRAME EXECUTIVE PAGE_TABLE PARAMETER PROCESS SWIS UNWIND For more information about using SDA 64-bit addressing support, see the HP OpenVMS System Analysis Tools Manual.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.6 Language and Pointer Support for 64-Bit Addressing
The OpenVMS Calling Standard describes the techniques used by all OpenVMS languages for invoking routines and passing data between them. The standard also denes the mechanisms that ensure consistency in error and exception handling routines. The OpenVMS Calling Standard provides the following support for 64-bit addresses: Called routines can start to use complete 64-bit addresses. Callers can pass either 32-bit or 64-bit pointers. Pointers passed by reference often require a new 64-bit variant of the original routine. Self-identifying structures, such as those dened for descriptors and item lists, enable an existing API to be enhanced compatibly.
OpenVMS Alpha and OpenVMS I64 64-bit addressing support for mixed pointers also includes the following features: OpenVMS Alpha and OpenVMS I64 64-bit virtual address space layout that applies to all processes. (There are no special 64-bit processes or 32-bit processes.) 64-bit pointer support for addressing the entire 64-bit OpenVMS Alpha and OpenVMS I64 address space layout including P0, P1, and P2 address spaces and S0/S1, S2, and page table address spaces. 32-bit pointer compatibility for addressing P0, P1, and S0/S1 address spaces. 64-bit system services that support P0, P1, and P2 space addresses. 32-bit sign-extension checking for all arguments passed to 32-bit, pointeronly system services. C and MACRO-32 macros for handling 64-bit addresses.
Support for 64-Bit Addressing (Alpha and I64 Only) 11.7 HP C RTL Support for 64-Bit Addressing
Ability to explicitly call either the 32-bit or 64-bit form of functions for applications that mix pointer sizes A single shareable image for use by 32-bit and 64-bit applications
See the HP C Run-Time Library Reference Manual for OpenVMS Systems for a description of the 64-bit addressing support provided by the HP C Run-Time Library.
12
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
This chapter describes the use of memory management system services and run-time routines on Alpha and I64 systems. Although the operating systems memory management concepts are much the same on VAX, Alpha, and I64 systems, details of the memory management system are different. These details may be critical to certain uses of the operating systems memory management system services and routines on an Alpha and I64 system. This chapter contains the following sections: Section 12.1 describes the page sizes of Alpha and I64 systems. Section 12.2 describes the three levels of the operating systems memory allocation routines. Section 12.3 discusses how to use system services to add virtual address space, adjust working sets, control process swapping, and create and manage sections. Section 12.4 describes large page-le sections.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 121
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.1 Virtual Page Sizes
To determine system page size, you make a call to the SYS$GETSYI system service, specifying the SYI$_PAGE_SIZE item code. See the description of SYS$GETSYI and SYI$_PAGE_SIZE in the HP OpenVMS System Services Reference Manual for details.
122 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.2 Levels of Memory Allocation Routines
SYS$ULWSET_64 (Unlock Pages from Working Set) SYS$UPDSEC_64(W) (Update Global Section File on Disk) SYS$EXPREG (Expand Region) SYS$CRETVA (Create Virtual Address Space) SYS$DELTVA (Delete Virtual Address Space) SYS$CRMPSC (Create and Map Section) SYS$MGBLSC (Map Global Section)
32-bit services include, but are not limited to, the following:
For most cases in which a system service is used for memory allocation, the Expand Region (SYS$EXPREG or SYS$EXPREG_64) system service is used to create pages of virtual memory. Because system services provide more control over allocation procedures than RTL routines, you must manage the allocation precisely. System services provide extensive control over address space allocation by allowing you to do the following types of tasks: Add or delete virtual address space to the processs program region (P0), control region (P1), 64-bit program region (P2), or user-created virtual region. Add or delete virtual address space at a specic range of addresses Dene memory resident demand-zero sections and map them in to the virtual address space of a process. Increase or decrease the number of pages in a programs working set Lock or delete pages of a programs working set in memory Lock the entire programs working set in memory (by disabling process swapping) Dene disk les containing data or shareable images and map the les into the virtual address space of a process
2. RTL page management routines The RTL routines exist for creating, deleting, and accessing information about virtual address space. You can either allocate a specied number of contiguous pages or create a zone of virtual address space. A zone is a logical unit of the memory pool or subheap that you can control as an independent area. It can be any size required by your program. Refer to Chapter 14 for more information about zones. The RTL page management routines LIB$GET_VM_PAGE, LIB$GET_VM_ PAGE_64, LIB$FREE_VM_PAGE, and LIB$FREE_VM_PAGE_64 provide a convenient mechanism for allocating and freeing pages of memory. These routines maintain a processwide pool of free pages. If unallocated pages are not available when LIB$GET_VM_PAGE is called, it calls SYS$EXPREG to create the required pages in the program region (P0 space). For LIB$GET_VM_PAGE_64, if there are not enough contiguous free pagelets to satisfy an allocation request, additional pagelets are created by calling the system service SYS$EXPREG_64.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 123
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.2 Levels of Memory Allocation Routines
3. RTL heap management routines The RTL heap management routines LIB$GET_VM, LIB$GET_VM_64, LIB$FREE_VM, and LIB$FREE_VM_64 provide a mechanism for allocating and freeing blocks of memory of arbitrary size. The following are heap management routines based on the concept of zones: LIB$CREATE_VM_ZONE LIB$CREATE_VM_ZONE_64 LIB$CREATE_USER_VM_ZONE LIB$CREATE_USER_VM_ZONE_64 LIB$DELETE_VM_ZONE LIB$DELETE_VM_ZONE_64 LIB$FIND_VM_ZONE LIB$FIND_VM_ZONE_64 LIB$RESET_VM_ZONE LIB$RESET_VM_ZONE_64 LIB$SHOW_VM_ZONE LIB$SHOW_VM_ZONE_64 LIB$VERIFY_VM_ZONE LIB$VERIFY_VM_ZONE_64 Modular application programs can call routines in any or all levels of the hierarchy, depending on the kinds of services the application program needs. You must observe the following basic rule when using multiple levels of the hierarchy: Memory that is allocated by an allocation routine at one level of the hierarchy must be freed by calling a deallocation routine at the same level of the hierarchy. For example, if you allocated a page of memory by calling LIB$GET_VM_PAGE, you can free it only by calling LIB$FREE_VM_PAGE. For information about using memory management RTLs, see Chapter 14.
12.3.1 Increasing and Decreasing Virtual Address Space with 64-Bit System Services
To add address space at the end of P0, P1, P2 or a user created region, use the 64-bit Expand Region (SYS$EXPREG_64) system service. SYS$EXPREG_64 returns the range of virtual addresses for the new pages. To add address space in other portions of P0, P1, P2 or user created virtual regions, use SYS$CRETVA_64.
124 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
The format for SYS$EXPREG_64 is as follows: SYS$EXPREG_64 region_id_64, length_64, acmode, ags, return_va_64, return_length_64 The following example illustrates the addition of 4 pagelets to the 64-bit program region of a process by writing a call to the SYS$EXPREG_64 system service. #define __NEW_STARTLET 1 #pragma pointer_size 64 #include #include #include #include #include <gen64def.h> <stdio.h> <ssdef.h> <starlet.h> <vadef.h>
int main (void) { int status; GENERIC_64 region_id = {VA$C_P2}; void * start_va; unsigned __int64 length; unsigned int pagcnt = 4; /* Add 4 pagelets to P0 space */ status = sys$expreg_64 (®ion_id, pagcnt*512, 0, 0, &start_va, &length); if (( status&1) != 1) LIB$SIGNAL( status); else printf ("Starting address %016LX Length %016LXn", start_va, length); } The value VA$C_P2 is passed in the region_id argument to specify that the pages are to be added to the 64-bit program region. To add the same number of pages to the 32-bit program region, you would specify VA$C_P0. To add pages to the control region, you would specify VA$C_P1. To add pages to a user created virtual region, you would specify the region_id returned by the SYS$CREATE_ REGION_64 system service. On Alpha and I64 systems the SYS$EXPREG_64 system service can add pagelets only in the direction of the growth of a particular region.
12.3.2 Increasing and Decreasing Virtual Address Space with 32-bit System Services
The system services allow you to add address space anywhere within the processs program region (P0) or control region (P1). To add address space at the end of P0 or P1, use the Expand Program/Control Region (SYS$EXPREG) system service. SYS$EXPREG optionally returns the range of virtual addresses for the new pages. To add address space in other portions of P0 or P1, use SYS$CRETVA. The format for SYS$EXPREG is as follows: SYS$EXPREG (pagcnt ,[retadr] ,[acmode] ,[region]) Specifying the Number of Pages Use the pagcnt argument to specify the number of pagelets to add to the end of the region. The Alpha and I64 systems round the specied pagelet value to the next integral number of pages for the system where it is executing. To check the exact boundaries of the memory allocated by the system, specify the optional retadr argument. The retadr argument contains the start address and the end address of the memory allocated by the system service.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 125
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
Specifying the Access Mode Use the acmode argument to specify the access to be assigned to the newly created pages. Specifying the Region Use the region argument to specify whether to add the pages to the end of the P0 or P1 region. To deallocate pages allocated with SYS$EXPREG and SYS$CRETVA, use SYS$DELTVA. For Alpha systems, the following example illustrates the addition of 4 pagelets to the program region of a process by writing a call to the SYS$EXPREG system service. #include <stdio.h> #include <ssdef.h> main() { unsigned int status, retadr[2],pagcnt=4, region=0; /* Add 4 pages to P0 space */ status = SYS$EXPREG( pagcnt, &retadr, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d Ending address: %d\n", retadr[0],retadr[1]; } The value 0 is passed in the region argument to specify that the pages are to be added to the program region. To add the same number of pages to the control region, you would specify REGION=1. Note that the region argument to the SYS$EXPREG service is optional; if it is not specied, the pages are added to or deleted from the program region by default. The SYS$EXPREG service can add pagelets only in the direction of the growth of a particular region. When you need to add pages to the middle of these regions, you can use the Create Virtual Address Space (SYS$CRETVA) system service. Likewise, when you need to delete pages created by either SYS$EXPREG or SYS$CRETVA, you can use the Delete Virtual Address Space (SYS$DELTVA) system service. For example, if you have used the SYS$EXPREG service twice to add pages to the program region and want to delete the rst range of pages but not the second, you could use the SYS$DELTVA system service, as shown in the following example: #include <stdio.h> #include <ssdef.h> struct { unsigned int lower, upper; }retadr1, retadr2, retadr3; main() { unsigned int status, pagcnt=4, region=0;
126 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
/* Add 4 pages to P0 space */ status = SYS$EXPREG( pagcnt, &retadr1, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr1.lower,retadr1.upper); /* Add 3 more pages to P0 space */ pagcnt = 3; status = SYS$EXPREG( pagcnt, &retadr2, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr2.lower,retadr2.upper); /* Delete original allocation */ status = SYS$DELTVA( &retadr1, &retadr3, 0 ); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr1.lower,retadr1.upper); } In this example, the rst call to SYS$EXPREG rounds up the requested pagelet count to an integral number of CPU-specic pages and adds that number of pages to the program region; the virtual addresses of the created pages are returned in the 2-longword array at retadr1. The second request converts the pagelet count to pages, adds them to the program region, and returns the addresses at retadr2. The call to SYS$DELTVA deletes the area created by the rst SYS$EXPREG call.
Caution Be aware that using SYS$CRETVA presents some risk because it can delete pages that already exist if those pages are not owned by a more privileged access mode. Further, if those pages are deleted, notication is not sent. Therefore, unless you have complete control over an entire system, use SYS$EXPREG or the RTL routines to allocate address space.
Section 12.3.5 mentions some other possible risks in using SYS$CRETVA for allocating memory.
12.3.3 Input Address Arrays and Return Address Arrays for the 64-Bit System Services
When the SYS$EXPREG_64 system service adds pages to a region, it adds them in the normal direction of growth for the region. The return address always indicates the lowest-addressed byte in the added address range. To calculate the highest-addressed byte in the added address range, add the returned length to the returned address and subtract 1.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 127
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
When the SYS$DELTVA_64 system service deletes pages from a region, it deletes them in the opposite direction of growth for the region. The return address always indicates the lowest-addressed byte in the deleted address range. To calculate the highest-addressed byte in the deleted address range, add the returned length to the returned address and subtract 1. Table 121 Sample Virtual Address Arrays for 64-Bit Services
Start_va 1010 2450 4200 7FFEC010 08000A000 Length 660 1 6300 90 4000 Return_va 0 2000 4000 7FFEC000 08000A000 Return_length 2000 2000 8000 2000 4000 Number of Pages 1 1 4 1 2
12.3.4 Input Address Arrays and Return Address Arrays for the 32-Bit System Services
When the SYS$EXPREG system service adds pages to a region, it adds them in the normal direction of growth for the region. The return address array, if requested, indicates the order in which the pages were added. For example: If the program region is expanded, the starting virtual address is smaller than the ending virtual address. If the control region is expanded, the starting virtual address is larger than the ending virtual address.
The addresses returned indicate the rst byte in the rst page that was added or deleted and the last byte in the last page that was added or deleted, respectively. When input address arrays are specied for the Create and Delete Virtual Address Space (SYS$CRETVA and SYS$DELTVA, respectively) system services, these services add or delete pages beginning with the address specied in the rst longword and ending with the address specied in the second longword. On Alpha and I64 systems, the order in which the pages are added or deleted does not have to be in the normal direction of growth for the region. Moreover, because these services add or delete only whole pages, they ignore the low-order bits of the specied virtual address (the low-order bits contain the byte offset within the page). Table 122 shows the page size and byte offset. Table 122 Page and Byte Offset Within Pages on Alpha and I64 Systems
Page Size (Bytes) 8K 16K 32K 64K Byte Within Page (Bits) 13 14 15 16
Table 123 shows some sample virtual addresses in hexadecimal that may be specied as input to SYS$CRETVA or SYS$DELTVA and shows the return
128 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
address arrays if all pages are successfully added or deleted. Table 123 assumes a page size of 8 KB = 2000 hex. Table 123 Sample Virtual Address Arrays on Alpha and I64 Systems
Input Array Output Array Number of Pages 1 1 4 1 1 2
Region P0 P0 P0 P0 P1 P1
For SYS$CRETVA and SYS$DELTVA, note that if the input virtual addresses are the same, as in the fourth and fth items in Table 123, a single page is added or deleted. The return address array indicates that the page was added or deleted in the normal direction of growth for the region. Note that for SYS$CRMPSC and SYS$MGBLSC, which are discussed in Section 12.3.9, the sample virtual address arrays in Table 123 do not apply. The reason is that the lower address value has to be an even multiple of the machine page size; that is, it must be rounded down to an even multiple page size. In addition, the higher address value must be one less than the even multiple page size, representing the last byte on the last page. That is, it must be rounded up to an even multiple page size, minus 1. The procedure for determining start and end virtual addresses is as follows: 1. Obtain the page size in bytes. 2. Subtract 1 to obtain the byte-with-page mask. 3. Mask the low bits of lower virtual address, which is a round-down operation to round it to the next lower page boundary. 4. Perform a logical OR operation on the higher virtual address, which is a round-up operation to round it to the highest address in the last page.
12.3.5 Allocating Memory in Existing Virtual Address Space on Alpha and I64 Systems Using the 32-Bit System Service
Note On Alpha and I64 systems, SYS$CRETVA_64 adds a range of demandzero allocation pages to a processs virtual address space for the execution of the current image. The new pages are added at the virtual address specied by the caller. SYS$CRETVA_64 is the preferred method of adding these pages.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 129
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
On Alpha and I64 systems, if you reallocate memory that is already in its virtual address space by using the SYS$CRETVA system service, you may need to modify the values of the following arguments to SYS$CRETVA: If your application explicitly rounds the lower address specied in the inadr argument to be a multiple of 512 in order to align on a page boundary, you need to modify the address. The Alpha and I64 systems version of the SYS$CRETVA system service rounds down the start address to a CPU-specic page boundary, which varies with different implementations. It also rounds up the end address to the last byte in a CPU-specic page boundary. The size of the reallocation, specied by the address range in the inadr argument, may be larger on an Alpha and I64 system than on a VAX system because the request is rounded up to CPU-specic pages. This can cause the unintended destruction of neighboring data, which may also occur with singlepage allocations. (When the start address and the end address specied in the inadr argument match, a single page is allocated.)
To determine whether you must modify the address as specied in inadr, specify the optional retadr argument to determine the exact boundaries of the memory allocated by the call to SYS$CRETVA.
1210 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
The 64-bit system services return the address range (return_va and return_ length) of the addresses of the pages changed (added, deleted, or modied) before the error.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1211
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
12.3.7.3 SYS$LKWSET and SYS$LKWSET_64 System Services The Lock Pages in Working Set (SYS$LKWSET) system service makes one or more pages in the working set ineligible for paging by locking them in the working set. Once locked into the working set, those pages remain in the working set until they are unlocked explicitly with the Unlock Pages in Working Set (SYS$ULWSET) system service, or program execution ends. The format is as follows: SYS$LKWSET (inadr ,[retadr] ,[acmode]) On Alpha and I64 systems, SYS$LKWSET_64 locks a range of virtual addresses in the working set. If the pages are not already in the working set, the service brings them in and locks them. A page locked in the working set does not become a candidate for replacement. SYS$LKWSET_64 start_va_64 ,length_64 ,acmode ,return_va_64 ,return_length_64 12.3.7.4 Specifying a Range of Addresses Locking a range of pages in the working set is problematic on I64 because the linker generates additional code that must also be locked and determining the address of that linker code is nontrivial. The solution, applicable for both Alpha and I64, is to use the LIB$LOCK_IMAGE and LIB$UNLOCK_IMAGE LIBRTL routines to lock the entire image in to the working set. You can specify an address of a byte within the image to be locked in the working set, or zero for the current image. If your privileged program runs on Alpha and I64 and not on VAX, you can remove all the code that nds the code, data and linkage data and locks these areas in the working set. You can replace this code with calls to LIB$LOCK_ IMAGE and LIB$UNLOCK_IMAGE. These routines are simpler to program correctly and make your code easier to understand and maintain. LIB$LOCK_IMAGE and LIB$UNLOCK_IMAGE are preferable to SYS$LKWSET and SYS$ULKWSET for locking code and related data in the working set. For more information about locking images in the working set, refer to the HP OpenVMS RTL Library (LIB$) Manual and to the descriptions of LIB$LOCK_ IMAGE and LIB$UNLOCK_IMAGE in this manual. 12.3.7.5 Specifying a Range of Addresses In OpenVMS Version 8.1 Programs that enter kernel mode and increase IPL to higher than 2 must lock program code and data in the working set. Locking code and data is necessary to avoid crashing the system with a PGFIPLHI bugcheck. On VAX systems, typically only the code and data explicitly referenced by the program need to be locked. On Alpha, the code, data and linkage data referenced by the program need to be locked. On I64 systems, code, data, short data, and linker generated code need to be locked. To make porting easier and because the addresses of short data and linker generated data cannot be easily found within an image, changes were made to the SYS$LKWSET and SYS$LKWSET_ 64 system servics. As of OpenVMS Alpha Version 8.1 and OpenVMS I64 Version 8.1, the SYS$LKWSET and SYS$LKWSET_64 system services test the rst address passed in. If this address is within an image, these services attempt to lock the entire image in the working set. If a successful status code is returned, the program can increase IPL to higher than 2 without crashing the system with a PGFIPLHI bugcheck.
1212 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
A counter is maintained within the internal OpenVMS image structures that counts the number of times the image has been successfully locked in the working set. The counter is incremented when locked and decremented when unlocked. When the counter becomes zero, the entire image is unlocked from the working set. If the programs image is too large to be locked in the working set, the status SS$_LKWSETFUL is returned. If you encounter this status, you can increase the users working set quota. 12.3.7.6 Specifying a Range of Addresses In OpenVMS Versions Prior to V8.1 For OpenVMS versions prior to OpenVMS Alpha Version 8.1, you can use the inadr argument to specify the range of addresses to be locked. SYS$LKWSET rounds the addresses to CPU-specic page boundaries, if necessary. The range of addresses of the pages actually locked are returned in the retadr argument. However, because the Alpha systems instructions cannot contain full virtual addresses, the Alpha systems images must reference procedures and data indirectly through a pointer to a procedure descriptor. The procedure descriptor contains information about the procedure, including the actual code address. These pointers to procedure descriptors and data are collected into a program section called a linkage section. Therefore, it is not sufcient simply to lock a section of code into memory to improve performance. You must also lock the associated linkage section into the working set. To lock the linkage section into memory, you must determine the start and end addresses that encompass the linkage section and pass these addresses as values in the inadr argument to a call to SYS$LKWSET. For more information about linking, see Migrating to an OpenVMS AXP System: Recompiling and Relinking Applications. Note that this manual has been archived but is available on the OpenVMS Documentation Web site at: http://www.hp.com/go/openvms/doc 12.3.7.7 Specifying the Access Mode If you use the SYS$LKWSET or SYS$LKWSET_64 system service, use the acmode argument to specify the access mode to be associated with the pages you want locked.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1213
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
When a process is swapped out of the balance set, all the pages (both modied and unmodied) of its working set are swapped, including any pages that had been locked in the working set. A privileged process may lock itself in the balance set. While pages can still be paged in and out of the working set, the process remains in memory even when it is inactive. To lock itself in the balance set, the process issues the Set Process Swap Mode (SYS$SETSWM) system service, as follows: $SETSWM_S SWPFLG=#1 This call to SYS$SETSWM disables process swap mode. You can also disable swap mode by setting the appropriate bit in the STSFLG argument to the Create Process (SYS$CREPRC) system service; however, you need the PSWAPM privilege to alter process swap mode. A process can also lock particular pages in memory with the Lock Pages in Memory (SYS$LCKPAG or SYS$LCKPAG_64) system service. These pages are forced into the processs working set if they are not already there. When pages are locked in memory with these services, the pages remain in memory even when the remainder of the processs working set is swapped out of the balance set. These remaining pages stay in memory until they are unlocked with SYS$ULKPAG or SYS$ULKPAG_64. The SYS$LCKPAG and SYS$LCKPAG_64 system services can be useful in special circumstances, for example, for routines that perform I/O operations to devices without using the operating systems I/O system. On Alpha and I64 systems, if you are attempting to lock executable code with $LCKPAG, you should examine if locking these pages in the working set is more correct. See the descriptions of $LKWSET and LIB$LOCK_IMAGE. You need the PSWAPM privilege to issue the SYS$LCKPAG, SYS$LCKPAG_64, SYS$ULKPAG, or SYS$ULKPAG_64 system service.
12.3.9 Sections
A section is a disk le or a portion of a disk le containing data or instructions that can be brought into memory and made available to a process for manipulation and execution. A section can also be one or more consecutive page frames in physical memory or I/O space; such sections, which require you to specify page frame number (PFN) mapping, are discussed in Chapter 13, Section 13.5.6.15. Sections are either private or global (shared). Private sections are accessible only by the process that creates them. A process can dene a disk data le as a section, map it into its virtual address space, and manipulate it. Global sections can be shared by more than one process. One copy of the global section resides in physical memory, and each process sharing it refers to the same copy, except for copy-on-reference sections. For a copyon-reference section, each process refers to the same global section, but each process gets its own copy of each page upon reference. A global section can contain shareable code or data that can be read, or read and written, by more than one process. Global sections are either temporary or permanent and can be dened for use within a group or on a systemwide basis. Global sections can be mapped to a disk le or created as a global page-le section, or they can be a PFN mapped section.
1214 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
When modied pages in writable disk le sections are paged out of memory during image execution, they are written back into the section le rather than into the paging le, as is the normal case with les. (However, copy-on-reference sections are not written back into the section le.) The use of disk le sections involves these two distinct operations: 1. The creation of a section denes a disk le as a section and informs the system what portions of the le contain the section. 2. The mapping of a section makes it available to a process and establishes the correspondence between virtual blocks in the le and specic addresses in the virtual address space of a process. The Create and Map Section (SYS$CRMPSC) system service creates and maps a private section or a global section. Because a private section is used only by a single process, creation and mapping are simultaneous operations. In the case of a global section, one process can create a permanent global section and not map to it; other processes can map to it. A process can also create and map a global section in one operation. The following sections describe the creation, mapping, and use of disk le sections. In each case, operations and requirements that are common to both private sections and global sections are described rst, followed by additional notes and requirements for the use of global sections. Section 12.3.9.6 discusses global page-le sections. 12.3.9.1 Creating Sections with 64-Bit System Services The $CRMPSC system service allows a process to create a private or global section and to map a section of its address space to the private or global section. However, although this system service is powerful and exible, it is complex. If you are using an Alpha or I64 system, the following routines provide an easier method of creating and mapping sections: $CRMPSC_FILE_64 Allows a process to map a section of its address space to a specied portion of a le. This service maps a private disk le section. $CRMPSC_GFILE_64 Allows a process to create a global disk le section and to map a section of its address space to the global section. $CRMPSC_GPFILE_64 Allows a process to create a global page le section and to map a section of its address space to the global section. $CRMPSC_GPFN_64 Allows a process to create a permanent global page frame section and to map a section of its address space to the global page frame section. $CRMPSC_PFN_64 Allows a process to map a section of its address space to a specied physical address range represented by page frame numbers. This service creates and maps a private page frame section.
12.3.9.2 PFN-Mapped Sections Mapped I/O space on an OpenVMS I64 system may require non-cached access. You must set the SEC$M_UNCACHED ag when a PFN-mapped section is created if this section must be treated as uncached memory. The following system services accept this ag: SYS$CRMPSC_PFN_64 SYS$CREATE_GPFN
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1215
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
SYS$CRMPSC_GPFN_64
In addition, the SYS$MGBLSC_GPFN_64 service accepts, but ignores the ag. The cached/uncached characteristic is stored as a section attribute, and the system uses this attribute when the section is mapped. On OpenVMS Alpha systems, all four services accept but ignore the SEC$M_UNCACHED ag. Note that the older services, SYS$CRMPSC and SYS$MGBLSC were not updated and do not accept the new ag. See the Intel Itanium Architecture Software Developers Manual for additional information regarding virtual-addressing memory attributes. 12.3.9.3 Creating Sections with 32-Bit System Services To create a disk le section, you must follow these steps: 1. Open or create the disk le containing the section. 2. Dene which virtual blocks in the le comprise the section. 3. Dene the characteristics of the section. 12.3.9.3.1 Opening the Disk File Before you can use a le as a section, you must open it using OpenVMS RMS. The following example shows the OpenVMS RMS le access block ($FAB) and $OPEN macros used to open the le and the channel specication to the SYS$CRMPSC system service necessary for reading an existing le: SECFAB: $FAB FNM=<SECTION.TST>, ; File access block FOP=UFO RTV= -1
. . . $OPEN FAB=SECFAB $CRMPSC_S CHAN=SECFAB+FAB$L_STV,... The le options parameter (FOP) indicates that the le is to be opened for user I/O; this option is required so that OpenVMS RMS assigns the channel using the access mode of the caller. OpenVMS RMS returns the channel number on which the le is accessed; this channel number is specied as input to the SYS$CRMPSC system service (chan argument). The same channel number can be used for multiple create and map section operations. The option RTV=01 tells the le system to keep all of the pointers to be mapped in memory at all times. If this option is omitted, the SYS$CRMPSC service requests the le system to expand the pointer areas if necessary. Storage for these pointers is charged to the BYTLM quota, which means that opening a badly fragmented le can fail with an EXBYTLM failure status. Too many fragmented sections may cause the byte limit to be exceeded. The le may be a new le that is to be created while it is in use as a section. In this case, use the $CREATE macro to open the le. If you are creating a new le, the le access block (FAB) for the le must specify an allocation quantity (ALQ parameter). You can also use SYS$CREATE to open an existing le; if the le does not exist, it is created. The following example shows the required elds in the FAB for the conditional creation of a le:
1216 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
GBLFAB: $FAB FNM=<GLOBAL.TST>, ALQ=4, FAC=PUT,FOP=<UFO,CIF,CBT>, SHR=<PUT,UPI>
. . . $CREATE FAB=GBLFAB When the $CREATE macro is invoked, it creates the le GLOBAL.TST if the le does not currently exist. The CBT (contiguous best try) option requests that, if possible, the le be contiguous. Although section les are not required to be contiguous, better performance can result if they are. 12.3.9.3.2 Dening the Section Extents After the le is opened successfully, the SYS$CRMPSC system service can create a section from the entire le or from only certain portions of it. The following arguments to SYS$CRMPSC dene the extents of the le that comprise the section: pagcnt (page count). This argument indicates the number of pages (on VAX systems) or pagelets (on Alpha and I64 systems) in the section. The pagcnt argument is a longword containing this number. On Alpha and I64 systems, the smallest allocation is an Alpha or I64 page, which is 8192 bytes. When requesting pagelets, the size requested is a multiple of 512 bytes, but the actual allocation is rounded to 8192. For example, when requesting 17 pagelets, the allocation is for two Alpha or I64 pages, 16384 bytes. On Alpha and I64 systems, if the SEC$M_PFNMAP ag bit is set, the pagcnt argument is interpreted as CPU-specic pages, not as pagelets. On Alpha or I64 and VAX systems, the specied page count is compared with the number of blocks in the section le; if they are different, the lower value is used. If you do not specify the page count or specify it as 0 (the default), the size of the section le is used. However, for physical page frame sections, this argument must not be 0. vbn (virtual block number). This argument is optional. It denes the number of the virtual block in the le that is the beginning of the section. If you do not specify this argument, the value 1 is passed (the rst virtual block in the le is the beginning of the section). If you specied page frame number mapping (by setting the SEC$M_PFNMAP ag), the vbn argument species the CPU-specic page frame number where the section begins in memory.
12.3.9.3.3 Dening the Section Characteristics The ags argument to the SYS$CRMPSC system service denes the following section characteristics: Whether it is a private section or a global section. The default is to create a private section. How the pages of the section are to be treated when they are copied into physical memory or when a process refers to them. The pages in a section can be either or both of the following: Read/write or read-only Created as demand-zero pages or as copy-on-reference pages, depending on how the processes are going to use the section and whether the le contains any data (see Section 12.3.9.9)
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1217
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
Whether the section is to be mapped to a disk le or to specic physical page frames (see Section 12.3.9.15).
When you specify section characteristics, the following restrictions apply: Global sections cannot be both demand-zero and copy-on-reference. Demand-zero sections must be writable.
12.3.9.3.4 Dening Global Section Characteristics If the section is a global section, you must assign a character string name (gsdnam argument) to it so that other processes can identify it when they map it. The format of this character string name is explained in Section 12.3.9.3.5. The ags argument species the following types of global section: Group temporary (the default) Group permanent System temporary System permanent
Group global sections can be shared only by processes executing with the same group number. The name of a group global section is implicitly qualied by the group number of the process that created it. When other processes map it, their group numbers must match. A temporary global section is automatically deleted when no processes are mapped to it, but a permanent global section remains in existence even when no processes are mapped to it. A permanent global section must be explicitly marked for deletion with the Delete Global Section (SYS$DGBLSC) system service. You need the user privileges PRMGBL and SYSGBL to create permanent group global sections or system global sections (temporary or permanent), respectively. A system global section is available to all processes in the system. Optionally, a process creating a global section can specify a protection mask (prot argument) to restrict all access or a type of access (read, write, execute, delete) to other processes. 12.3.9.3.5 Global Section Name that points to a character string. The gsdnam argument species a descriptor
Translation of the gsdnam argument proceeds in the following manner: 1. The current name string is prexed with GBL$ and the result is subject to logical name translation. 2. If the result is a logical name, step 1 is repeated until translation does not succeed or until the number of translations performed exceeds the number specied by the system parameter LNM$C_MAXDEPTH. 3. The GBL$ prex is stripped from the current name string that could not be translated. This current string is the global section name. For example, assume that you have made the following logical name assignment: $ DEFINE GBL$GSDATA GSDATA_001
1218 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
Your program contains the following statements: #include <descrip.h> . . . $DESCRIPTOR(gsdnam,"GSDATA"); . . . status = sys$crmpsc(&gsdnam, . . . ); The following logical name translation takes place: 1. GBL$ is prexed to GSDATA. 2. GBL$GSDATA is translated to GSDATA_001. (Further translation is not successful. When logical name translation fails, the string is passed to the service.) There are three exceptions to the logical name translation method discussed in this section: If the name string starts with an underscore ( _ ), the operating system strips the underscore and considers the resultant string to be the actual name (that is, further translation is not performed). If the name string is the result of a logical name translation, then the name string is checked to see if it has the terminal attribute. If the name string is marked with the terminal attribute, the operating system considers the resultant string to be the actual name (that is, further translation is not performed). If the global section has a name in the format name_nnn, the operating system rst strips the underscore and the digits (nnn), then translates the resultant name according to the sequence discussed in this section, and nally reappends the underscore and digits. The system uses this method in conjunction with known images and shared les installed by the system manager.
12.3.9.4 Mapping Sections with 32-Bit System Services When you call the SYS$CRMPSC system service to create or map a section, or both, you must provide the service with a range of virtual addresses (inadr argument) into which the section is to be mapped. On Alpha and I64 systems, the inadr argument species the size and location of the section by its start and end addresses. SYS$CRMPSC interprets the inadr argument in the following ways: If both addresses specied in the inadr argument are the same and the SEC$M_EXPREG bit is set in the ags argument, SYS$CRMPSC allocates the memory in whichever program region the addresses fall but does not use the specied location. If both addresses are different, SYS$CRMPSC maps the section into memory using the boundaries specied.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1219
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
On Alpha and I64 systems, if you know specically which pages the section should be mapped into, you provide these addresses in a 2-longword array. For example, to map a private section of 10 pages into virtual pages 10 through 19 of the program region, specify the input address array as follows: unsigned int maprange[1]; /* Assume page size = 8 KB */ maprange[0] = 0x14000; maprange[1] = 0x27FFF; /* Address (hex) of page 10 */ /* Address (hex) of page 19 */
On Alpha and I64 systems, the inadr argument range must have a lower address on an even page boundary and a higher address exactly one less than a page boundary. You do this to avoid programming errors that might arise because of incorrect programming assumptions about page sizes. For example, the range can be expressed as the following on an 8 KB page system: 0 -> 1FFF 2000 -> 7FFF or inadr[0] = rst byte in range inadr[1] = last byte in range If the range is not expressed in terms of page-inclusive boundaries, then an SS$_ INVARG condition value is returned. You do not need to know the explicit addresses to provide an input address range. If you want the section mapped into the rst available virtual address range in the program region ( P0 ) or control region ( P1 ), you can specify the SEC$M_ EXPREG ag bit in the ags argument. In this case, the addresses specied by the inadr argument control whether the service nds the rst available space in the P0 or P1. The value specied or defaulted for the pagcnt argument determines the amount of space mapped. On Alpha and I64 systems, the relpag argument species the location in the section le at which you want mapping to begin. On Alpha and I64 systems, the SYS$CRMPSC and SYS$MGBLSC system services map a minimum of one CPU-specic page. If the section le does not ll a single page, the remainder of the page is lled with zeros after faulting the page into memory. The extra space on the page should not be used by your application because only the data that ts into the section le will be written back to the disk. The following example shows part of a program used to map a section at the current end of the program region: unsigned int status, inadr[1], retadr[1], flags; /* This range used merely to indicate P0 space since SEC$M_EXPREG is specified */ inadr[0]= 0x200; /* Any program (P0) region address */ inadr[1]= 0x200; /* Any P0 address (can be same) */ . . . /* Address range returned in retadr */ flags = SEC$M_EXPREG; status = sys$crmpsc(&inadr, &retadr, flags, . . . );
1220 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
The addresses specied do not have to be currently in the virtual address space of the process. The SYS$CRMPSC system service creates the required virtual address space during the mapping of the section. If you specify the retadr argument, the service returns the range of addresses actually mapped. On Alpha and I64 systems, the starting retadr address should match inadr, plus relpag if specied. The ending (higher) address will be limited by the lower of: The value of the pagcnt argument The actual remaining block count in the le starting with specied starting vbn, or relpag The bound dictated by the inadr argument
After a section is mapped successfully, the image can refer to the pages using one of the following: A base register or pointer and predened symbolic offset names Labels dening offsets of an absolute program section or structure
The following example shows part of a program used to create and map a process section on Alpha and I64 systems: SECFAB: $FAB FNM=<SECTION.TST>, FOP=UFO, FAC=PUT, SHR=<GET,PUT,UPI> ^X14000 ^X27FFF 1 1 ; First 8 KB page ; Last page ; First page mapped ; Last page mapped
; MAPRANGE: .LONG .LONG RETRANGE: .BLKL ENDRANGE: .BLKL . . . $OPEN BLBS BSBW 10$:
20$:
; ; ; ; ;
Input address array Output array Map four pagelets Read/write section Channel number
Notes on Example 1. The OPEN macro opens the section le dened in the le access block SECFAB. (The FOP parameter to the $FAB macro must specify the UFO option.) 2. The SYS$CRMPSC system service uses the addresses specied at MAPRANGE to specify an input range of addresses into which the section will be mapped. The pagcnt argument requests that only 4 pagelets of the le be mapped.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1221
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
3. The ags argument requests that the pages in the section have read/write access. The symbolic ag denitions for this argument are dened in the $SECDEF macro. Note that the le access eld (FAC parameter) in the FAB also indicates that the le is to be opened for writing. 4. When SYS$CRMPSC completes, the addresses of the 4 pagelets that were mapped are returned in the output address array at RETRANGE. The address of the beginning of the section is placed in register 6, which serves as a pointer to the section. 12.3.9.5 Mapping Global Sections with 32-Bit Services Note This section describes the use of the SYS$MGBLSC system service. However, the SYS$MGBLSC_64 system service is the preferred method for mapping global sections for Alpha and I64 systems.
A process that creates a global section can map that global section. Then other processes can map it by calling the Map Global Section (SYS$MGBLSC) system service. When a process maps a global section, it must specify the global section name assigned to the section when it was created, whether it is a group or system global section, and whether it desires read-only or read/write access. The process may also specify the following: A version identication (ident argument), indicating the version number of the global section (when multiple versions exist) and whether more recent versions are acceptable to the process. A relative pagelet number (relpag argument), specifying the pagelet number, relative to the beginning of the section, to begin mapping the section. In this way, processes can use only portions of a section. Additionally, a process can map a piece of a section into a particular address range and subsequently map a different piece of the section into the same virtual address range.
On Alpha and I64 systems, you should specify the retadr argument to determine the exact boundaries of the memory that was mapped by the call. If your application species the relpag argument, you must specify the retadr argument. In this case, it is not an optional argument. Cooperating processes can both issue a SYS$CRMPSC system service to create and map the same global section. The rst process to call the service actually creates the global section; subsequent attempts to create and map the section result only in mapping the section for the caller. The successful return status code SS$_CREATED indicates that the section did not already exist when the SYS$CRMPSC system service was called. If the section did exist, the status code SS$_NORMAL is returned. The example in Section 12.3.9.9 shows one process (ORION) creating a global section and a second process (CYGNUS) mapping the section.
1222 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
12.3.9.6 Global Page-File Sections with 32-Bit System Services Global page-le sections are used to store temporary data in a global section. A global page-le section is a section of virtual memory that is not mapped to a le. The section can be deleted when processes have nished with it. (Contrast this with demand-zero section le pages where no initialization is necessary, but the pages are saved in a le.) The system parameter GBLPAGFIL controls the total number of global page-le pages in the system. To create a global page-le section, you must set the ag bits SEC$M_GBL and SEC$M_PAGFIL in the ags argument to the Create and Map Section (SYS$CRMPSC) system service. The channel (chan argument) must be 0. You cannot specify the ag bit SEC$M_CRF with the ag bit SEC$M_PAGFIL. 12.3.9.7 Mapping into a Dened Address Range With 32-Bit System Services On Alpha and I64 systems, SYS$CRMPSC and SYS$MGBLSC interpret some of the arguments differently than on VAX systems if you are mapping a section into a dened area of virtual address space. The differences are as follows: The addresses specied as values in the inadr argument must be aligned on CPU-specic page boundaries. On VAX systems, SYS$CRMPSC and the SYS$MGBLSC round these addresses to page boundaries for you. On Alpha and I64 systems, SYS$CRMPSC does not round the addresses you specify to page boundaries, because rounding to CPU-specic page boundaries on Alpha and I64 system affects a much larger portion of memory than it does on VAX systems, where page sizes are much smaller. Therefore, on Alpha and I64 systems, you must explicitly state where you want the virtual memory space mapped. If the addresses you specify are not aligned on CPU-specic page boundaries, SYS$CRMPSC returns an invalid arguments error (SS$_ INVARG). In particular, the lower inadr address must be on a CPU-specic page boundary, and the higher inadr address must be one less than a CPU-specic page; that is, it indicates the highest-addressed byte of the inadr range. The addresses returned in the retadr argument reect only the usable portion of the actual memory mapped by the call, not the entire amount mapped. The usable amount is either the value specied in the pagcnt argument (measured in pagelets) or the size of the section le, whichever is smaller. The actual amount mapped depends on how many CPU-specic pages are required to map the section le. If the section le does not ll a CPU-specic page, the remainder of the page is lled with zeros. The excess space on this page should not be used by your application. The end address specied in the retadr argument species the upper limit available to your application. Also note that, when the relpag argument is specied, the retadr argument must be included. It is not optional on Alpha and I64 systems.
12.3.9.8 Mapping from an Offset into a Section File With 32-Bit System Services On Alpha and I64 systems, you can map a portion of a section le by specifying the address at which to start the mapping as an offset from the beginning of the section le. You specify this offset by supplying a value to the relpag argument of SYS$CRMPSC. The value of the relpag argument species the pagelet number relative to the beginning of the le at which the mapping should begin.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1223
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
To preserve compatibility, SYS$CRMPSC interprets the value of the relpag argument in 512-byte units on VAX, Alpha, and I64 systems. However, because the CPU-specic page size on the Alpha and I64 system is larger than 512 bytes, the address specied by the offset in the relpag argument probably does not fall on a CPU-specic page boundary on an Alpha and I64 system. SYS$CRMPSC can map virtual memory in CPU-specic page increments only. Therefore, on Alpha and I64 systems, the mapping of the section le will start at the beginning of the CPU-specic page that contains the offset address, not at the address specied by the offset. Note Even though the routine starts mapping at the beginning of the CPUspecic page that contains the address specied by the offset, the start address returned in the retadr argument is the address specied by the offset, not the address at which mapping actually starts.
If you map from an offset into a section le, you must still provide an inadr argument that abides by the requirements presented in Section 12.3.9.7 when mapping into a dened address range. 12.3.9.9 Section Paging Resulting from SYS$CRMPSC The rst time an image executing in a process refers to a page that was created during the mapping of a disk le section, the page is copied into physical memory. The address of the page in the virtual address space of a process is mapped to the physical page. During the execution of the image, normal paging can occur; however, pages in sections are not written into the page le when they are paged out, as is the normal case. Rather, if they have been modied, they are written back into the section le on disk. The next time a page fault occurs for the page, the page is brought back from the section le. If the pages in a section were dened as demand-zero pages or copy-on-reference pages when the section was created, the pages are treated differently, as follows: If the call to SYS$CRMPSC requested that pages in the section be treated as demand-zero pages, these pages are initialized to zeros when they are created in physical memory. If the le is either a new le being created as a section or a le being completely rewritten, demand-zero pages provide a convenient way of initializing the pages. The pages are paged back into the section le. When the section is deleted, all unreferenced pages are written back to the le as zeros. This causes the le to be initialized, no matter how few pages were modied. See Section 12.3.9.11 for details about deleting sections. If the call to SYS$CRMPSC requested that pages in the section be copy-onreference pages, each process that maps to the section receives its own copy of the section, on a page-by-page basis from the le, as it refers to them. These pages are never written back into the section le but are paged to the paging le as needed.
In the case of global sections, more than one process can be mapped to the same physical pages. If these pages need to be paged out or written back to the disk le dened as the section, these operations are done only when the pages are not in the working set of any process.
1224 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
In the following example for Alpha and I64 systems, process ORION creates a global section and process CYGNUS maps to that section: /* Process ORION */ #include #include #include #include #include <rms.h> <rmsdef.h> <literal>(<string.h>) <secdef.h> <descrip.h>
struct FAB gblfab; main() { unsigned short chan; unsigned int status, flags, efn=65; char *fn = "SECTION.TST"; $DESCRIPTOR(name, "FLAG_CLUSTER"); /* Common event flag cluster name */ $DESCRIPTOR(gsdnam, "GLOBAL_SECTION"); /* Global section name */
!status = SYS$ASCEFC(efn, &name, 0);
if ((status & 1) != 1) LIB$SIGNAL( status ); /* Initialize FAB fields */ gblfab = cc$rms_fab; gblfab.fab$l_alq = 4; gblfab.fab$b_fac = FAB$M_PUT; gblfab.fab$l_fnm = fn; gblfab.fab$l_fop = FAB$M_CIF || FAB$M_CBT; . . . /* Create a file if none exists */
"status = SYS$CREATE( &gblfab, 0, 0 );
if ((status & 1) != 1) LIB$SIGNAL( status ); flags = SEC$M_GBL | SEC$M_WRT; status = SYS$CRMPSC(0, 0, 0, flags, &gsdnam, . . . ); if ((status & 1) != 1) LIB$SIGNAL( status ); status = SYS$SETEF(efn); if ((status & 1) != 1) LIB$SIGNAL( status ); . . . } /* Process CYGNUS */ unsigned int status, efn=65; $DESCRIPTOR(cluster,"FLAG_CLUSTER"); $DESCRIPTOR(section,"GLOBAL_SECTION"); . . .
#status = SYS$ASCEFC(efn, &cluster, 0);
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1225
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
status = SYS$WAITFR(efn); if ((status & 1) != 1) LIB$SIGNAL( status ); status = SYS$MGBLSC(&inadr, &retadr, 0, flags, §ion, 0, 0); if ((status & 1) != 1) LIB$SIGNAL( status ); }
! The processes ORION and CYGNUS are in the same group. Each process
rst associates with a common event ag cluster named FLAG_CLUSTER to use common event ags to synchronize its use of the section.
" The process ORION creates the global section named GLOBAL_SECTION,
specifying section ags that indicate that it is a global section (SEC$M_GBL) and has read/write access. Input and output address arrays, the page count parameter, and the channel number arguments are not shown; procedures for specifying them are the same, as shown in this example.
# The process CYGNUS associates with the common event ag cluster and
waits for the ag dened as FLGSET; ORION sets this ag when it has nished creating the section. To map the section, CYGNUS species the input and output address arrays, the ag indicating that it is a global section, and the global section name. The number of pages mapped is the same as that specied by the creator of the section. 12.3.9.10 Reading and Writing Data Sections Read/write sections provide a way for a process or cooperating processes to share data les in virtual memory. The sharing of global sections may involve application-dependent synchronization techniques. For example, one process can create and map to a global section in read/write fashion; other processes can map to it in read-only fashion and interpret data written by the rst process. Alternatively, two or more processes can write to the section concurrently. (In this case, the application must provide the necessary synchronization and protection.) After data in a process private section is modied, the process can release (or unmap) the section. The modied pages are then written back into the disk le dened as a section. After data in a global section is modied, the process or processes can release (or unmap) the section. The modied pages are still maintained in memory until the section is deleted. The data is then written back into the disk le dened as a section. Applications relying on modied data to be in the le at a specic point in time must use the SYS$UPDSEC_64(W) or SYS$UPDSEC(W) system service to force the write action. See Section 12.3.9.12. When the section is deleted, the revision number of the le is incremented, and the version number of the le remains unchanged. A full directory listing indicates the revision number of the le and the date and time that the le was last updated.
1226 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
12.3.9.11 Releasing and Deleting Sections For Alpha and I64 systems, the SYS$DELTVA_64 and SYS$UPDSEC(W)_64 system service are the preferred methods for deleting a range of virtual addresses from a processs virtual address space and for writing all pages (or only those pages modied by the current process) in an active private or global disk le section back into the section le on disk. A process unmaps a section by deleting the virtual addresses in its own virtual address space to which it has mapped the section. If a return address range was specied to receive the virtual addresses of the mapped pages, this address range can be used as input to the Delete Virtual Address Space (SYS$DELTVA_64 or SYS$DELTVA) system service. For exaple, in the case of SYS$DELTVA: $DELTVA_S INADR=RETRANGE When a process unmaps a private section, the section is deleted; that is, all control information maintained by the system is deleted. A temporary global section is deleted when all processes that have mapped to it have unmapped it. Permanent global sections are not deleted until they are specically marked for deletion with the Delete Global Section (SYS$DGBLSC) system service; they are then deleted when no more processes are mapped. Note that deleting the pages occupied by a section does not delete the section le, but rather cancels the processs association with the le. Moreover, when a process deletes pages mapped to a process private read/write section, all modied pages are written back into the section le. For global sections, the systems modied page writer starts writing back modied pages when the section is deleted and all mapping processes have deleted their associated virtual address space. Applications relying on modied data to be in the le at a specic point in time must use the SYS$UPDSEC_64(W) or SYS$UPDSEC(W) system service to force the write action. See Section 12.3.9.12. After a process private section is deleted, the channel assigned to it can be deassigned. The process that created the section can deassign the channel with the Deassign I/O Channel (SYS$DASSGN) system service, as follows: $DASSGN_S CHAN=GBLFAB+FAB$L_STV For global sections, the channel is only used to identify the le to the system. The system then assigns a different channel to use for future paging I/O to the le. The used assigned channel can be deleted immediately after the global section is created. 12.3.9.12 Writing Back Sections For Alpha and I64 systems, the SYS$UPDSEC(W)_64 system service is the preferred method for writing all pages (or only those pages modied by the current process) in an active private or global disk le section back into the section le on disk. Because read/write sections are not normally updated on disk until either the physical pages they occupy are paged out, or until the section is deleted, a process should ensure that all modied pages are successfully written back into the section le at regular intervals. The Update Section File on Disk (SYS$UPDSEC_64 or SYS$UPDSEC) system service writes the modied pages in a section into the disk le. The SYS$UPDSEC_64 and SYS$UPDSEC system services are described in the HP OpenVMS System Services Reference Manual.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1227
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
12.3.9.13 Memory-Resident Global Sections Memory-resident global sections allow a database server to keep larger amounts of currently used data cached in physical memory. The database server then accesses the data directly from physical memory without performing I/O read operations from the database les on disk. With faster access to the data in physical memory, runtime performance increases dramatically. Memory-resident global sections are non-le-backed global sections. Pages within a memory-resident global section are not backed by the pagele or by any other le on disk. Thus, no pagele quota is charged to any process or to the system. When a process maps to a memory-resident global section and references the pages, working set list entries are not created for the pages. No working set quota is charged to the process. For further information about memory-resident global sections, see Chapter 16. 12.3.9.14 Image Sections Global sections can contain shareable code. The operating system uses global sections to implement shareable code, as follows: 1. The object module containing code to be shared is linked to produce a shareable image. The shareable image is not, in itself, executable. It contains a series of sections, called image sections. 2. You link private object modules with the shareable image to produce an executable image. No code or data from the shareable image is put into the executable image. 3. The system manager uses the INSTALL command to create a permanent global section from the shareable image le, making the image sections available for sharing. 4. When you run the executable image, the operating system automatically maps the global sections created by the INSTALL command into the virtual address space of your process. For details on how to create and identify shareable images and how to link them with private object modules, see the HP OpenVMS Linker Utility Manual. For information about how to install shareable images and make them available for sharing as global sections, see the HP OpenVMS System Managers Manual. 12.3.9.15 Page Frame Sections A page frame section is one or more contiguous pages of physical memory or I/O space that have been mapped as a section. One use of page frame sections is to map to an I/O page, thus allowing a process to read device registers. A page frame section differs from a disk le section in that it is not associated with a particular disk le and is not paged. However, it is similar to a disk le section in most other respects: you create, map, and dene the extent and characteristics of a page frame section in essentially the same manner as you do for a disk le section. For Alpha and I64 systems, the $CRMPSC_GPFN_64 and $CRMPSC_PFN_ 64 system services are the preferred method of creating and mapping global and private page frame sections. This section describes the use of the 32-bit SYS$CRMPSC system service.
1228 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
To create a page frame section, you must specify page frame number (PFN) mapping by setting the SEC$M_PFNMAP ag bit in the ags argument to the Create and Map Section (SYS$CRMPSC) system service. The vbn argument is now used to specify that the rst page frame is to be mapped instead of the rst virtual block. You must have the user privilege PFNMAP to either create or delete a page frame section but not to map to an existing one. Because a page frame section is not associated with a disk le, you do not use the chan, and pfc arguments to the SYS$CRMPSC service to create or map this type of section. For the same reason, the SEC$M_CRF (copy-on-reference) and SEC$M_DZRO (demand-zero) bit settings in the ags argument do not apply. Pages in page frame sections are not written back to any disk le (including the paging le). The pagcnt and relpag arguments are in units of CPU-specic pages for page frame sections. Caution You must use caution when working with page frame sections. If you permit write access to the section, each process that writes to it does so at its own risk. Serious errors can occur if a process writes incorrect data or writes to the wrong page, especially if the page is also mapped by the system or by another process. Thus, any user who has the PFNMAP privilege can damage or violate the security of a system.
12.3.9.16 Partial Sections On Alpha and I64 systems, a partial section is one where not all of the dened section, whether private or global, is entirely backed up by disk blocks. In other words, a partial section is where a disk le does not map completely onto an Alpha and I64 system page. For example, suppose a le for which you wish to create a section consists of 17 virtual blocks on disk. To map this section, you would need two whole Alpha and I64 8-KB pages, the smallest size Alpha and I64 page available. The rst Alpha and I64 page would map the rst 16 blocks of the section, and the second Alpha and I64 page would map the 17th block of the section. (A block on disk is 512 bytes, same as on OpenVMS VAX.) This results in 15/16ths of the second Alpha and I64 page not being backed up by the section le. This is called a partial section because the second Alpha and I64 page of the section is only partially backed up. When the partial page is faulted in, a disk read is issued for only as many blocks as actually back up that page, which in this case is 1. When that page is written back, only the one block is actually written. If the upper portion of the second Alpha and I64 page is used, it is done so at some risk, because only the rst block of that page is saved on a write-back operation. This upper portion of the second Alpha and I64 page is not really useful space to the programmer, because it is discarded during page faulting.
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1229
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation 12.3.10 Example of Using 32-Bit Memory Management System Services
In the following example, two programs are communicating through a global section. The rst program creates and maps a global section (by using SYS$CRMPSC) and then writes a device name to the section. This program also denes the device terminal and process names and sets the event ags that synchronize the processes. The second program maps the section (by using SYS$MGBLSC) and then reads the device name and the process that allocated the device and any terminal allocated to that process. This program also writes the process named to the terminal global section where the process name can be read by the rst program. The example program uses the SYS$MGBLSC system service. However, the SYS$MGBLSC_64 system service is the preferred method for mapping global sections for Alpha and I64 systems. The common event cluster is used to synchronize access to the global section. The rst program sets REQ_FLAG to indicate that the device name is in the section. The second program sets INFO_FLAG to indicate that the process and terminal names are available. Data in a section must be page aligned. The following is the option le used at link time that causes the data in the common area named DATA to be page aligned: PSECT_ATTR = DATA, PAGE For high-level language usage, use the solitary attribute of the linker. See the HP OpenVMS Linker Utility Manual for an explanation of how to use the solitary attribute. The address range requested for a section must end on a page boundary, so SYS$GETSYI is used to obtain the system page size. Before executing the rst program, you need to write a user-open routine that sets the user-open bit (FAB$V_UFO) of the FAB options longword (FAB$L_FOP). Because the Fortran OPEN statement species that the le is new, you should use $CREATE to open it rather than $OPEN. No $CONNECT should be issued. The user-open routine reads the channel number that the le is opened on from the status longword (FAB$L_STV) and returns that channel number to the main program by using a common block (CHANNEL in this example). !This is the program that creates the global section. ! Define global section flags INCLUDE ($SECDEF) ! Mask for section flags INTEGER SEC_MASK
1230 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
! Logical unit number for section file INTEGER INFO_LUN ! Channel number for section file ! (returned from useropen routine) INTEGER SEC_CHAN COMMON /CHANNEL/ SEC_CHAN ! Length for the section file INTEGER SEC_LEN ! Data for the section file CHARACTER*12 DEVICE, 2 PROCESS CHARACTER*6 TERMINAL COMMON /DATA/ DEVICE, 2 PROCESS, 2 TERMINAL ! Location of data INTEGER PASS_ADDR (2), 2 RET_ADDR (2) ! Two common event flags INTEGER REQUEST_FLAG, 2 INFO_FLAG DATA REQUEST_FLAG /70/ DATA INFO_FLAG /71/ ! Data for SYS$GETSYI INTEGER PAGE_SIZE INTEGER*2 BUFF_LEN, ITEM_CODE INTEGER BUFF_ADDR, LENGTH, TERMINATOR EXTERNAL SYI$_PAGE_SIZE COMMON /GETSYI_ITEMLST/ BUFF_LEN, 2 ITEM_CODE, 2 BUFF_ADDR, 2 LENGTH, 2 TERMINATOR ! User-open routines INTEGER UFO_CREATE EXTERNAL UFO_CREATE . . . ! Open the section file STATUS = LIB$GET_LUN (INFO_LUN) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) SEC_MASK = SEC$M_WRT .OR. SEC$M_DZRO .OR. SEC$M_GBL ! (Last element - first element + size of last element + 511)/512 SEC_LEN = ( (%LOC(TERMINAL) - %LOC(DEVICE) + 6 + 511)/512 ) OPEN (UNIT=INFO_LUN, 2 FILE=INFO.TMP, 2 STATUS=NEW, 2 INITIALSIZE = SEC_LEN, 2 USEROPEN = UFO_CREATE) ! Free logical unit number and map section CLOSE (INFO_LUN) ! Get the system page size BUFF_LEN = 4 ITEM_CODE = %LOC(SYI$_PAGE_SIZE) BUFF_ADDR = %LOC(PAGE_SIZE) LENGTH = 0 TERMINATOR = 0 STATUS = SYS$GETSYI(,,,BUFF_LEN,,,) ! Get location of data PASS_ADDR (1) = %LOC (DEVICE) PASS_ADDR (2) = PASS_ADDR(1) + PAGE_SIZE - 1
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1231
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
STATUS = SYS$CRMPSC (PASS_ADDR, ! Address of section 2 RET_ADDR, ! Addresses mapped 2 , 2 %VAL(SEC_MASK), ! Section mask 2 GLOBAL_SEC, ! Section name 2 ,, 2 %VAL(SEC_CHAN), ! I/O channel 2 ,,,) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! Create the subprocess STATUS = SYS$CREPRC (, 2 GETDEVINF, ! Image 2 ,,,,, 2 GET_DEVICE, ! Process name 2 %VAL(4),,,) ! Priority IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! Write data to section DEVICE = $DISK1 ! Get common event flag cluster and set flag STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG), 2 CLUSTER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) STATUS = SYS$SETEF (%VAL(REQUEST_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! When GETDEVINF has the information, INFO_FLAG is set STATUS = SYS$WAITFR (%VAL(INFO_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) . . . ! This is the program that maps to the global section ! created by the previous program. ! Define section flags INCLUDE ($SECDEF) ! Mask for section flags INTEGER SEC_MASK ! Data for the section file CHARACTER*12 DEVICE, 2 PROCESS CHARACTER*6 TERMINAL COMMON /DATA/ DEVICE, 2 PROCESS, 2 TERMINAL ! Location of data INTEGER PASS_ADDR (2), 2 RET_ADDR (2) ! Two common event flags INTEGER REQUEST_FLAG, 2 INFO_FLAG DATA REQUEST_FLAG /70/ DATA INFO_FLAG /71/
1232 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.3 Using System Services for Memory Allocation
! Data for SYS$GETSYI INTEGER PAGE_SIZE INTEGER*2 BUFF_LEN, ITEM_CODE INTEGER BUFF_ADDR, LENGTH, TERMINATOR EXTERNAL SYI$_PAGE_SIZE COMMON /GETSYI_ITEMLST/ BUFF_LEN, 2 ITEM_CODE, 2 BUFF_ADDR, 2 LENGTH, 2 TERMINATOR . . . ! Get the system page size BUFF_LEN = 4 ITEM_CODE = %LOC(SYI$_PAGE_SIZE) BUFF_ADDR = %LOC(PAGE_SIZE) LENGTH = 0 TERMINATOR = 0 STATUS = SYS$GETSYI(,,,BUFF_LEN,,,) ! Get common event flag cluster and wait ! for GBL1.FOR to set REQUEST_FLAG STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG), 2 CLUSTER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) STATUS = SYS$WAITFR (%VAL(REQUEST_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Get location of data PASS_ADDR (1) = %LOC (DEVICE) PASS_ADDR (2) = PASS_ADDR(1) + PAGE_SIZE - 1 ! Set write flag SEC_MASK = SEC$M_WRT ! Map the section STATUS = SYS$MGBLSC (PASS_ADDR, ! Address of section 2 RET_ADDR, ! Address mapped 2 , 2 %VAL(SEC_MASK), ! Section mask 2 GLOBAL_SEC,,) ! Section name IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Call GETDVI to get the process ID of the ! process that allocated the device, then ! call GETJPI to get the process name and terminal ! name associated with that process ID. ! Set PROCESS equal to the process name and ! set TERMINAL equal to the terminal name. . . . ! After information is in GLOBAL_SEC STATUS = SYS$SETEF (%VAL(INFO_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) END
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1233
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.4 Large Page-File Sections
count.
" Number of page les. Begins with an index value of 254 and decreases in
count.
# Total committed page le usage. As in previous releases, more pages can
reside in page-le sections systemwide than would t into installed page les. The SHOW MEMORY/FILES/FULL display no longer contains separate usage information for page and swap les. Because page-le information is no longer reserved, the system does not need to maintain the number of processes interested in a distinct page or swap le. For example:
1234 Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 12.4 Large Page-File Sections
$ SHOW MEMORY/FILES/FULL System Memory Resources on 22-MAY-2000 18:47:10.21 Swap File Usage (8KB pages): Index Free DISK$ALPHASYS:[SYS48.SYSEXE]SWAPFILE.SYS 1 904 Paging File Usage (8KB pages): Index Free DISK$ALPHASYS:[SYS48.SYSEXE]PAGEFILE.SYS 254 16888 Total committed paging file usage: 1960 Up to 254 page and swap les can be installed. Size 904 Size 16888
Memory Management Services and Routines on OpenVMS Alpha and OpenVMS I64 1235
13
Memory Management Services and Routines on OpenVMS VAX
This chapter describes the use of system services and run-time routines that VAX systems use to manage memory. It contains the following sections: Section 13.1 describes the page size on VAX systems. Section 13.2 describes the layout of virtual address space. Section 13.3 describes extended addressing enhancements on selected VAX systems. Section 13.4 describes the three levels of memory allocation routines. Section 13.5 discusses how to use system services to add virtual address space, adjust working sets, control process swapping, and create and manage sections.
Memory Management Services and Routines on OpenVMS VAX 13.2 Virtual Address Space
Common system region (S0) The common system region is also referred to as S0 space. S0 space contains the operating system. Your program cannot allocate or free memory within the common system region from the user access mode. This common system region (S0) of system virtual address space can have appended to it additional virtual address space, known as a reserved region, or S1 space, that creates a single region of system space. As a result, the system virtual address space increases from 1 GB to 2 GB. A summary of these regions appears in Figure 131. Figure 131 Virtual Address Overview on VAX Systems
ZK4145GE
The memory management routines map and control the relationship between physical memory and the virtual address space of a process. These activities are, for the most part, transparent to you and your programs. In some cases, however, you can make a program more efcient by explicitly controlling its virtual memory usage. The maximum size to which a process can increase its address space is controlled by the system parameter VIRTUALPAGECNT. Using memory management system services, a process can add a specied number of pages to the end of either the program region or the control region. Adding pages to the program region provides the process with additional space for image execution, for example, for the dynamic creation of tables or data areas. Adding pages to the control region increases the size of the user stack.
132 Memory Management Services and Routines on OpenVMS VAX
Memory Management Services and Routines on OpenVMS VAX 13.2 Virtual Address Space
As new pages are referenced, the stack is automatically expanded, as shown in Figure 132. (By using the STACK= option in a linker options le, you can also expand the user stack when you link the image.) Figure 132 illustrates the layout of a processs virtual memory. The initial size of a processs virtual address space depends on the size of the image being executed. Figure 132 Layout of VAX Process Virtual Address Space
Virtual Address 00000000 Program Region (P0) Direction of Growth
Length
Length
Direction of Growth
7FFFFFFF ZK0861GE
Memory Management Services and Routines on OpenVMS VAX 13.3 Extended Addressing Enhancements on Selected VAX Systems
Extended physical addressing increases the size of a physical address from 30 bits to 32 bits. This increases the capacity for physical memory from 512 MB to 3.5 GB as shown in Figure 133. The 512 MB is still reserved for I/O and adapter space. Figure 133 Physical Address Space for VAX Systems with XPA VAX without Extended Addressing 30bit Address Space 0 512 MB Memory Space 2000 0000 512 MB I/O 1 GB 3FFF FFFF 3.5 GB 512 MB I/O 4 GB FFFF FFFF
ZK5065AGE
0000 0000
Memory Space
E000 0000
Extended virtual addressing (XVA) increases the size of the virtual page number eld in the format of a system space address from 21 bits to 22 bits. The region of system virtual address space, known as the reserved region or S1 space, is appended to the existing region of system virtual address space known as S0 space, thereby creating a single region of system space. As a result, the system virtual address space increases from 1 GB to 2 GB as shown in Figure 134.
Memory Management Services and Routines on OpenVMS VAX 13.3 Extended Addressing Enhancements on Selected VAX Systems
Figure 134 Virtual Address Space for VAX Systems with XVA
VAX without Extended Addressing Virtual Space 0000 0000 P0 Space 4000 0000 P1 Space 8000 0000 1 GB System Region (S0) C000 0000 Reserved Region (S1) FFFF FFFF FFFF FFFF
ZK5066AGE
VAX with Extended Addressing Virtual Space 0000 0000 P0 Space 4000 0000 P1 Space 8000 0000
2 GB System Space
Memory Management Services and Routines on OpenVMS VAX 13.4 Levels of Memory Allocation Routines
SYS$CRMPSC (Create and Map Section) SYS$MGBLSC (Map Global Section) SYS$DGBLSC (Delete Global Section) For most cases in which a system service is used for memory allocation, the Expand Region (SYS$EXPREG) system service is used to create pages of virtual memory. Because system services provide more control over allocation procedures than RTL routines, you must manage the allocation precisely. System services provide extensive control over address space allocation by allowing you to do the following types of tasks: Add or delete virtual address space to the process program region (P0) or process control region (P1) Add or delete virtual address space at a specic range of addresses Increase or decrease the number of pages in a programs working set Lock or delete pages of a programs working set in memory Lock the entire programs working set in memory (by disabling process swapping) Dene disk les containing data or shareable images and map the les into the virtual address space of a process
2. RTL page management routines RTL routines are available for creating, deleting, and accessing information about virtual address space. You can either allocate a specied number of contiguous pages or create a zone of virtual address space. A zone is a logical unit of the memory pool or subheap that you can control as an independent area. It can be any size required by your program. Refer to Chapter 14 for more information about zones. The RTL page management routines LIB$GET_VM_PAGE and LIB$FREE_ VM_PAGE provide a convenient mechanism for allocating and freeing pages of memory. These routines maintain a processwide pool of free pages. If unallocated pages are not available when LIB$GET_VM_PAGE is called, it calls SYS$EXPREG to create the required pages in the program region (P0 space). 3. RTL heap management routines The RTL heap management routines LIB$GET_VM and LIB$FREE_VM provide a mechanism for allocating and freeing blocks of memory of arbitrary size. The following are heap management routines based on the concept of zones: LIB$CREATE_VM_ZONE LIB$CREATE_USER_VM_ZONE LIB$DELETE_VM_ZONE LIB$FIND_VM_ZONE LIB$RESET_VM_ZONE LIB$SHOW_VM_ZONE LIB$VERIFY_VM_ZONE If an unallocated block is not available to satisfy a call to LIB$GET_VM, LIB$GET_VM calls LIB$GET_VM_PAGE to allocate additional pages.
Memory Management Services and Routines on OpenVMS VAX 13.4 Levels of Memory Allocation Routines
Modular application programs can call routines at any or all levels of the hierarchy, depending on the kinds of services the application program needs. You must observe the following basic rule when using multiple levels of the hierarchy: Memory that is allocated by an allocation routine at one level of the hierarchy must be freed by calling a deallocation routine at the same level of the hierarchy. For example, if you allocated a page of memory by calling LIB$GET_VM_PAGE, you can free it only by calling LIB$FREE_VM_PAGE. Figure 135 shows the three levels of memory allocation routines. Figure 135 Hierarchy of VAX Memory Management Routines
RTL Heap Management Routines LIB$CREATE_USER_VM_ZONE LIB$CREATE_VM_ZONE LIB$DELETE_VM_ZONE LIB$FIND_VM_ZONE LIB$FREE_VM LIB$GET_VM LIB$RESET_VM_ZONE LIB$SHOW_VM_ZONE LIB$VERIFY_VM_ZONE
Memory Management System Services $CRETVA $CRMPSC $DELTVA $DGBLSC $EXPREG $MGBLSC
ZK4146GE For information about using memory management RTLs, see Chapter 14.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation 13.5.1 Increasing and Decreasing Virtual Address Space
The system services allow you to add address space anywhere within the processs program region (P0) or control region (P1). To add address space at the end of P0 or P1, use the Expand Program/Control Region (SYS$EXPREG) system service. SYS$EXPREG optionally returns the range of virtual addresses for the new pages. To add address space in other portions of P0 or P1, use SYS$CRETVA. The format for SYS$EXPREG is as follows: SYS$EXPREG (pagcnt ,[retadr] ,[acmode] ,[region]) Specifying the Number of Pages Use the pagcnt argument to specify the number of pages to add to the end of the region. The range of addresses where the new pages are added is returned in retadr. Specifying the Access Mode Use the acmode argument to specify the access to be assigned to the newly created pages. Specifying the Region Use the region argument to specify whether to add the pages to the end of the P0 or P1 region. This argument is optional. To deallocate pages allocated with SYS$EXPREG, use SYS$DELTVA. The following example illustrates how to add 4 pages to the program region of a process by writing a call to the SYS$EXPREG system service: #include <stdio.h> #include <ssdef.h> main() { unsigned int status, retadr[1],pagcnt=4, region=0; /* Add 4 pages to P0 space */ status = SYS$EXPREG( pagcnt, &retadr, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d Ending address: %d\n", retadr.lower,retadr.upper); } The value 0 is passed in the region argument to specify that the pages are to be added to the program region. To add the same number of pages to the control region, you would specify REGION=#1. Note that the region argument to SYS$EXPREG is optional; if it is not specied, the pages are added to or deleted from the program region by default. The SYS$EXPREG service can add pages only to the end of a particular region. When you need to add pages to the middle of these regions, you can use the Create Virtual Address Space (SYS$CRETVA) system service. Likewise, when you need to delete pages created by either SYS$EXPREG or SYS$CRETVA, you can use the Delete Virtual Address Space (SYS$DELTVA) system service. For example, if you have used the SYS$EXPREG service twice to add pages to the program region and want to delete the rst range of pages but not the second, you could use the SYS$DELTVA system service, as shown in the following example:
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
#include <stdio.h> #include <ssdef.h> struct { unsigned int lower, upper; }retadr1, retadr2, retadr3; main() { unsigned int status, pagcnt=4, region=0; /* Add 4 pages to P0 space */ status = SYS$EXPREG( pagcnt, &retadr1, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr1.lower,retadr1.upper); /* Add 3 more pages to P0 space */ pagcnt = 3; status = SYS$EXPREG( pagcnt, &retadr2, 0, region); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr2.lower,retadr2.upper); /* Delete original allocation */ status = SYS$DELTVA( &retadr1, &retadr3, 0 ); if (( status & 1) != 1) LIB$SIGNAL( status ); else printf("Starting address: %d ending address: %d\n", retadr1.lower,retadr1.upper); } In this example, the rst call to SYS$EXPREG adds 4 pages to the program region; the virtual addresses of the created pages are returned in the 2-longword array at retadr1. The second call adds 3 pages and returns the addresses at retadr2. The call to SYS$DELTVA deletes the rst 4 pages that were added. Caution Be aware that using SYS$CRETVA presents some risk because it can delete pages that already exist if those pages are not owned by a more privileged access mode. Further, if those pages are deleted, no notication is sent. Therefore, unless you have complete control over an entire system, use SYS$EXPREG or the RTL routines to allocate address space.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
The addresses returned indicate the rst byte in the rst page that was added or deleted and the last byte in the last page that was added or deleted. When input address arrays are specied for the Create and Delete Virtual Address Space (SYS$CRETVA and SYS$DELTVA, respectively) system services, these services add or delete pages beginning with the address specied in the rst longword and ending with the address specied in the second longword. Note The operating system always adjusts the starting and ending virtual addresses up or down to t page boundaries.
The order in which the pages are added or deleted does not have to be in the normal direction of growth for the region. Moreover, because these services add or delete only whole pages, they ignore the low-order 9 bits of the specied virtual address (the low-order 9 bits contain the byte offset within the page). The virtual addresses returned indicate the byte offsets. Table 131 shows some sample virtual addresses in hexadecimal that may be specied as input to SYS$CRETVA or SYS$DELTVA and shows the return address arrays if all pages are successfully added or deleted. Table 131 Sample Virtual Address Arrays on VAX Systems
Input Array Output Array Number of Pages 4 1 2 1 1 3
Region P0 P0 P0 P0 P1 P1
Note that if the input virtual addresses are the same, as in the fourth and fth items in Table 131, a single page is added or deleted. The return address array indicates that the page was added or deleted in the normal direction of growth for the region.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
The Set Protection on Pages (SYS$SETPRT) system service changes the protection assigned to a page or group of pages. The protection is expressed as a code that indicates the specic type of access (none, read-only, read/write) for each of the four access modes (kernel, executive, supervisor, user). Only the owner access mode or a more privileged access mode can change the protection for a page. When an image attempts to access a page that is protected against the access attempted, a hardware exception called an access violation occurs. When an image calls a system service, the service probes the pages to be used to determine whether an access violation would occur if the image attempts to read or write one of the pages. If an access violation would occur, the service exits with the status code SS$_ACCVIO. Because the memory management services add, delete, or modify a single page at a time, one or more pages can be successfully changed before an access violation is detected. If the retadr argument is specied in the service call, the service returns the addresses of pages changed (added, deleted, or modied) before the error. If no pages are affected, that is, if an access violation would occur on the rst page specied, the service returns a value of 01 in both longwords of the return address array. If the retadr argument is not specied, no information is returned.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
SYS$PURGWS System Service The Purge Working Set (SYS$PURGWS) system service removes one or more pages from the working set. SYS$LKWSET System Service The Lock Pages in Working Set (SYS$LKWSET) system service makes one or more pages in the working set ineligible for paging by locking them in the working set. Once locked into the working set, those pages remain until they are explicitly unlocked with the Unlock Pages in Working Set (SYS$ULWSET) system service or until program execution ends. The format is as follows: SYS$LKWSET (inadr ,[retadr] ,[acmode]) Specifying a Range of Addresses Use the inadr argument to specify the range of addresses to be locked. The range of addresses of the pages actually locked are returned in the retadr argument. Specifying the Access Mode Use the acmode argument to specify the access mode to be associated with the pages you want locked.
When a process is swapped out of the balance set, all the pages (both modied and unmodied) of its working set are swapped, including any pages that had been locked in the working set. A privileged process may lock itself in the balance set. While pages can still be paged in and out of the working set, the process remains in memory even when it is inactive. To lock itself in the balance set, the process issues the Set Process Swap Mode (SYS$SETSWM) system service, as follows: $SETSWM_S SWPFLG=#1 This call to SYS$SETSWM disables process swap mode. You can also disable swap mode by setting the appropriate bit in the STSFLG argument to the Create Process (SYS$CREPRC) system service; however, you need the PSWAPM privilege to alter process swap mode. A process can also lock particular pages in memory with the Lock Pages in Memory (SYS$LCKPAG) system service. These pages are not part of the processs working set, but they are forced into the processs working set. When pages are locked in memory with this service, the pages remain in memory even when the
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
remainder of the processs working set is swapped out of the balance set. These remaining pages stay in memory until they are unlocked with SYS$ULKPAG. SYS$LCKPAG can be useful in special circumstances, for example, for routines that perform I/O operations to devices without using the operating systems I/O system. You need the PSWAPM privilege to issue SYS$LCKPAG or SYS$ULKPAG.
13.5.6 Sections
A section is a disk le or a portion of a disk le containing data or instructions that can be brought into memory and made available to a process for manipulation and execution. A section can also be one or more consecutive page frames in physical memory or I/O space; such sections, which require you to specify page frame number (PFN) mapping, are discussed in Section 13.5.6.15. Sections are either private or global (shared). Private sections are accessible only by the process that creates them. A process can dene a disk data le as a section, map it into its virtual address space, and manipulate it. Global sections can be shared by more than one process. One copy of the global section resides in physical memory, and each process sharing it refers to the same copy. A global section can contain shareable code or data that can be read, or read and written, by more than one process. Global sections are either temporary or permanent and can be dened for use within a group or on a systemwide basis. Global sections can be either mapped to a disk le or created as a global page-le section.
When modied pages in writable disk le sections are paged out of memory during image execution, they are written back into the section le rather than into the paging le, as is the normal case with les. (However, copy-on-reference sections are not written back into the section le.) The use of disk le sections involves these two distinct operations: The creation of a section denes a disk le as a section and informs the system what portions of the le contain the section. The mapping of a section makes it available to a process and establishes the correspondence between virtual blocks in the le and specic addresses in the virtual address space of a process.
The Create and Map Section (SYS$CRMPSC) system service creates and maps a private section or a global section. Because a private section is used only by a single process, creation and mapping are simultaneous operations. In the case of a global section, one process can create a permanent global section and not map to it; other processes can map to it. A process can also create and map a global section in one operation. The following sections describe the creation, mapping, and use of disk le sections. In each case, operations and requirements that are common to both private sections and global sections are described rst, followed by additional notes and requirements for the use of global sections. Section 13.5.6.9 discusses global page-le sections.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
13.5.6.1 Creating Sections To create a disk le section, follow these steps: 1. Open or create the disk le containing the section. 2. Dene which virtual blocks in the le constitute the section. 3. Dene the characteristics of the section. 13.5.6.2 Opening the Disk File Before you can use a le as a section, you must open it using OpenVMS Record Management Services (RMS). The following example shows the OpenVMS RMS le access block ($FAB) and $OPEN macros used to open the le and the channel specication to the SYS$CRMPSC system service necessary for reading an existing le: #include #include #include #include <rms.h> <rmsdef.h> <string.h> <secdef.h>
struct FAB secfab; main() { unsigned short chan; unsigned int status, retadr[1], pagcnt=1, flags; char *fn = "SECTION.TST"; /* Initialize FAB fields */ secfab = cc$rms_fab; secfab.fab$l_fna = fn; secfab.fab$b_fns = strlen(fn); secfab.fab$l_fop = FAB$M_CIF; secfab.fab$b_rtv = -1; /* Create a file if none exists */ status = SYS$CREATE( &secfab, 0, 0 ); if ((status & 1) != 1) LIB$SIGNAL( status ); flags = SEC$M_EXPREG; chan = secfab.fab$l_stv; status = SYS$CRMPSC(0, &retadr, 0, 0, 0, 0, flags, chan, pagcnt, 0, 0, 0); if ((status & 1) != 1) LIB$SIGNAL( status ); } In this example, the le options parameter (FOP) indicates that the le is to be opened for user I/O; this parameter is required so that OpenVMS RMS assigns the channel using the access mode of the caller. OpenVMS RMS returns the channel number on which the le is accessed; this channel number is specied as input to SYS$CRMPSC (chan argument). The same channel number can be used for multiple create and map section operations. The option RTV=1 tells the le system to keep all of the pointers to be mapped in memory at all times. If this option is omitted, SYS$CRMPSC requests the le system to expand the pointer areas, if necessary. Storage for these pointers is charged to the BYTLM quota, which means that opening a badly fragmented le can fail with an EXBYTLM failure status. Too many fragmented sections may cause the byte limit to be exceeded.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
The le may be a new le that is to be created while it is in use as a section. In this case, use the $CREATE macro to open the le. If you are creating a new le, the le access block (FAB) for the le must specify an allocation quantity (ALQ parameter). You can also use SYS$CREATE to open an existing le; if the le does not exist, it is created. The following example shows the required elds in the FAB for the conditional creation of a le: GBLFAB: $FAB FNM=<GLOBAL.TST>, ALQ=4, FAC=PUT,FOP=<UFO,CIF,CBT>, SHR=<PUT,UPI>
. . . $CREATE FAB=GBLFAB When the $CREATE macro is invoked, it creates the le GLOBAL.TST if the le does not currently exist. The CBT (contiguous best try) option requests that, if possible, the le be contiguous. Although section les are not required to be contiguous, better performance can result if they are. 13.5.6.3 Dening the Section Extents After the le is opened successfully, SYS$CRMPSC can create a section either from the entire le or from certain portions of it. The following arguments to SYS$CRMPSC dene the extents of the le that constitute the section: pagcnt (page count). This argument is required. It indicates the number of virtual blocks that will be mapped. These blocks correspond to pages in the section. vbn (virtual block number). This argument is optional. It denes the number of the virtual block in the le that is the beginning of the section. If you do not specify this argument, the value 1 is passed (the rst virtual block in the le is the beginning of the section). If you have specied physical page frame number (PFN) mapping, the vbn argument species the starting PFN. The system does not allow you to specify a virtual block number outside of the le.
13.5.6.4 Dening the Section Characteristics The ags argument to SYS$CRMPSC denes the following section characteristics: Whether it is a private section or a global section. The default is to create a private section. How the pages of the section are to be treated when they are copied into physical memory or when a process refers to them. The pages in a section can be either or both of the following: Read/write or read-only Created as demand-zero pages or as copy-on-reference pages, depending on how the processes are going to use the section and whether the le contains any data (see Section 13.5.6.10) Whether the section is to be mapped to a disk le or to specic physical page frames (see Section 13.5.6.15).
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
Table 132 shows the ag bits that must be set for specic characteristics. Table 132 Flag Bits to Set for Specic Section Characteristics on VAX Systems
Section to Be Created Correct Flag Combinations SEC$M_GBL SEC$M_CRF SEC$M_DZRO SEC$M_WRT SEC$M_PERM SEC$M_SYSGBL SEC$M_PFNMAP SEC$M_EXPREG SEC$M_PAGFIL Private 0 Optional Optional Optional Not used Not used 0 Optional 0 Global 1 Optional Optional Optional Optional Optional 0 Optional Optional PFN Private 0 0 0 Optional Optional Not used 1 Optional 0 PFN Global 1 0 0 Optional 1 Optional 1 Optional 0 Shared Memory 1 0 Optional Optional 1 Optional 0 Optional 0
When you specify section characteristics, the following restrictions apply: Global sections cannot be both demand-zero and copy-on-reference. Demand-zero sections must be writable. Shared memory private sections are not allowed.
13.5.6.5 Dening Global Section Characteristics If the section is a global section, you must assign a character string name (gsdnam argument) to it so that other processes can identify it when they map it. The format of this character string name is explained in Section 13.5.6.6. The ags argument species the following types of global sections: Group temporary (the default) Group permanent System temporary System permanent
Group global sections can be shared only by processes executing with the same group number. The name of a group global section is implicitly qualied by the group number of the process that created it. When other processes map it, their group numbers must match. A temporary global section is automatically deleted when no processes are mapped to it, but a permanent global section remains in existence even when no processes are mapped to it. A permanent global section must be explicitly marked for deletion with the Delete Global Section (SYS$DGBLSC) system service. You need the user privileges PRMGBL and SYSGBL to create permanent group global sections or system global sections (temporary or permanent), respectively. A system global section is available to all processes in the system.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
Optionally, a process creating a global section can specify a protection mask (prot argument), restricting all access or a type of access (read, write, execute, delete) to other processes. 13.5.6.6 Global Section Name The gsdnam argument species a descriptor that points to a character string. Translation of the gsdnam argument proceeds in the following manner: 1. The current name string is prexed with GBL$ and the result is subject to logical name translation. 2. If the result is a logical name, step 1 is repeated until translation does not succeed or until the number of translations performed exceeds the number specied by the system parameter LNM$C_MAXDEPTH. 3. The GBL$ prex is stripped from the current name string that could not be translated. This current string is the name of the global section. For example, assume that you have made the following logical name assignment: $ DEFINE GBL$GSDATA GSDATA_001 Your program contains the following statements: #include <descrip.h> . . . $DESCRIPTOR(gsdnam,"GSDATA"); . . . status = sys$crmpsc(&gsdnam, . . . ); The following logical name translation takes place: 1. GBL$ is prexed to GDSDATA. 2. GBL$GSDATA is translated to GSDATA_001. (Further translation is not successful. When logical name translation fails, the string is passed to the service.) There are three exceptions to the logical name translation method discussed in this section: If the name string starts with an underscore ( _ ), the operating system strips the underscore and considers the resultant string to be the actual name (that is, further translation is not performed). If the name string is the result of a logical name translation, then the name string is checked to see whether it has the terminal attribute. If the name string is marked with the terminal attribute, the operating system considers the resultant string to be the actual name (that is, further translation is not performed). If the global section has a name in the format name_nnn, the operating system rst strips the underscore and the digits (nnn), then translates the resultant name according to the sequence discussed in this section, and nally reappends the underscore and digits. The system uses this method in conjunction with known images and shared les installed by the system manager.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
13.5.6.7 Mapping Sections When you call SYS$CRMPSC to create or map a section, or both, you must provide the service with a range of virtual addresses (inadr argument) into which the section is to be mapped. If you know specically which pages the section should be mapped into, you provide these addresses in a 2-longword array. For example, to map a private section of 10 pages into virtual pages 10 through 19 of the program region, specify the input address array as follows: unsigned int maprange[1]; maprange[0]= 0x1400; /* Address (hex) of page 10 */ maprange[1]= 0x2300; /* Address (hex) of page 19 */ You do not need to know the explicit addresses to provide an input address range. If you want the section mapped into the rst available virtual address range in the program region ( P0 ) or the control region ( P1 ), you can specify the SEC$M_ EXPREG ag bit in the ags argument. In this case, the addresses specied by the inadr argument control whether the service nds the rst available space in P0 or P1. The value specied or defaulted for the pagcnt argument determines the number of pages mapped. The following example shows part of a program used to map a section at the current end of the program region: unsigned int status, inadr[1], retadr[1], flags; inadr[0]= 0x200; /* Any program (P0) region address */ inadr[1]= 0x200; /* Any P0 address (can be same) */ . . . /* Address range returned in retadr */ flags = SEC$M_EXPREG; status = sys$crmpsc(&inadr, &retadr, flags, . . . ); The addresses specied do not have to be currently in the virtual address space of the process. SYS$CRMPSC creates the required virtual address space during the mapping of the section. If you specify the retadr argument, the service returns the range of addresses actually mapped. After a section is mapped successfully, the image can refer to the pages using one of the following: A base register or pointer and predened symbolic offset names Labels dening offsets of an absolute program section or structure
The following example shows part of a program used to create and map a process section: #include #include #include #include <rms.h> <rmsdef.h> <string.h> <secdef.h>
struct FAB secfab; main() { unsigned short chan; unsigned int status, inadr[1], retadr[1], pagcnt=1, flags; char *fn = "SECTION.TST";
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
/* Initialize FAB fields */ secfab = cc$rms_fab; secfab.fab$b_fac = FAB$M_PUT; secfab.fab$b_shr = FAB$M_SHRGET || FAB$V_SHRPUT || FAB$V_UPI; secfab.fab$l_fna = fn; secfab.fab$b_fns = strlen(fn); secfab.fab$l_fop = FAB$V_CIF; secfab.fab$b_rtv = -1; /* Create a file if none exists */ status = SYS$CREATE( &secfab, 0, 0 ); if ((status & 1) != 1) LIB$SIGNAL( status ); inadr[0] = X1400; inadr[1] = X2300; flags = SEC$M_WRT; chan = secfab.fab$l_stv; status = SYS$CRMPSC(&inadr, &retadr, 0, 0, 0, 0, flags, chan, pagcnt, 0, 0, 0); if ((status & 1) != 1) LIB$SIGNAL( status ); } Notes on Example 1. The OPEN macro opens the section le dened in the le access block SECFAB. (The FOP parameter to the $FAB macro must specify the UFO option.) 2. SYS$CRMPSC uses the addresses specied at MAPRANGE to specify an input range of addresses into which the section will be mapped. The pagcnt argument requests that only 4 pages of the le be mapped. 3. The ags argument requests that the pages in the section have read/write access. The symbolic ag denitions for this argument are dened in the $SECDEF macro. Note that the le access eld (FAC parameter) in the FAB also indicates that the le is to be opened for writing. 4. When SYS$CRMPSC completes, the addresses of the 4 pages that were mapped are returned in the output address array at RETRANGE. The address of the beginning of the section is placed in general register 6, which serves as a pointer to the section. 13.5.6.8 Mapping Global Sections A process that creates a global section can map that global section. Then other processes can map it by calling the Map Global Section (SYS$MGBLSC) system service. When a process maps a global section, it must specify the global section name assigned to the section when it was created, whether it is a group or system global section, and whether it wants read-only or read/write access. The process may also specify the following: A version identication (ident argument), indicating the version number of the global section (when multiple versions exist) and whether more recent versions are acceptable to the process.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
A relative page number (relpag argument) that species the page number relative to the beginning of the section to begin mapping the section. In this way, processes can use only portions of a section. Additionally, a process can map a piece of a section into a particular address range and subsequently map a different piece of the section into the same virtual address range.
To specify that the global section being mapped is located in physical memory that is being shared by multiple processors, you can include the shared memory name in the gsdnam argument character string (see Section 13.5.6.6). A demand-zero global section in memory shared by multiple processors must be mapped when it is created. Cooperating processes can issue a call to SYS$CRMPSC to create and map the same global section. The rst process to call the service actually creates the global section; subsequent attempts to create and map the section result only in mapping the section for the caller. The successful return status code SS$_CREATED indicates that the section did not already exist when the SYS$CRMPSC system service was called. If the section did exist, the status code SS$_NORMAL is returned. The example in Section 13.5.6.10 shows one process (ORION) creating a global section and a second process (CYGNUS) mapping the section. 13.5.6.9 Global Page-File Sections Global page-le sections are used to store temporary data in a global section. A global page-le section is a section of virtual memory that is not mapped to a le. The section can be deleted when processes have nished with it. (Contrast this to demand-zero pages, where initialization is not necessary but the pages are saved in a le.) The system parameter GBLPAGFIL controls the total number of global page-le pages in the system. To create a global page-le section, you must set the ag bits SEC$M_GBL and SEC$M_PAGFIL in the ags argument to the Create and Map Section (SYS$CRMPSC) system service. The channel (chan argument) must be 0. You cannot specify the ag bit SEC$M_CRF with the ag bit SEC$M_PAGFIL. 13.5.6.10 Section Paging The rst time an image executing in a process refers to a page that was created during the mapping of a disk le section, the page is copied into physical memory. The address of the page in the virtual address space of a process is mapped to the physical page. During the execution of the image, normal paging can occur; however, pages in sections are not written into the page le when they are paged out, as is the normal case. Rather, if they have been modied, they are written back into the section le on disk. The next time a page fault occurs for the page, the page is brought back from the section le. If the pages in a section were dened as demand-zero pages or copy-on-reference pages when the section was created, the pages are treated differently, as follows: If the call to SYS$CRMPSC requested that pages in the section be treated as demand-zero pages, these pages are initialized to zero when they are created in physical memory. If the le is either a new le being created as a section or a le being completely rewritten, demand-zero pages provide a convenient way of initializing the pages. The pages are paged back into the section le. When the virtual address space is deleted, all unreferenced pages are written back to the le as zeros. This causes the le to be initialized, no matter how few pages were modied.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
If the call to SYS$CRMPSC requested that pages in the section be copy-onreference pages, each process that maps to the section receives its own copy of the section, on a page-by-page basis from the le, as it refers to them. These pages are never written back into the section le but are paged to the paging le as needed.
In the case of global sections, more than one process can be mapped to the same physical pages. If these pages need to be paged out or written back to the disk le dened as the section, these operations are done only when the pages are not in the working set of any process. In the following example, process ORION creates a global section, and process CYGNUS maps to that section: /* Process ORION */ #include #include #include #include #include <rms.h> <rmsdef.h> <string.h> <secdef.h> <descrip.h>
struct FAB gblfab; main() { unsigned short chan; unsigned int status, flags, efn=65; char *fn = "SECTION.TST"; $DESCRIPTOR(name, "FLAG_CLUSTER"); /* Common event flag cluster name */ $DESCRIPTOR(gsdnam, "GLOBAL_SECTION"); /* Global section name */
!status = SYS$ASCEFC(efn, &name, 0);
if ((status & 1) != 1) LIB$SIGNAL( status ); /* Initialize FAB fields */ gblfab = cc$rms_fab; gblfab.fab$l_alq = 4; gblfab.fab$b_fac = FAB$M_PUT; gblfab.fab$l_fnm = fn; gblfab.fab$l_fop = FAB$M_CIF | FABM$_CBT; . . . /* Create a file if none exists */
"status = SYS$CREATE( &gblfab, 0, 0 );
if ((status & 1) != 1) LIB$SIGNAL( status ); flags = SEC$M_GBL || SEC$M_WRT; status = SYS$CRMPSC(0, 0, 0, flags, &gsdnam, . . . ); if ((status & 1) != 1) LIB$SIGNAL( status ); status = SYS$SETEF(efn); if ((status & 1) != 1) LIB$SIGNAL( status ); . . . } /* Process CYGNUS */
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
unsigned int status, efn=65; $DESCRIPTOR(cluster,"FLAG_CLUSTER"); $DESCRIPTOR(section,"GLOBAL_SECTION"); . . .
#status = SYS$ASCEFC(efn, &cluster, 0);
if ((status & 1) != 1) LIB$SIGNAL( status ); status = SYS$WAITFR(efn); if ((status & 1) != 1) LIB$SIGNAL( status ); status = SYS$MGBLSC(&inadr, &retadr, 0, flags, §ion, 0, 0); if ((status & 1) != 1) LIB$SIGNAL( status ); }
! The processes ORION and CYGNUS are in the same group. Each process
rst associates with a common event ag cluster named FLAG_CLUSTER to use common event ags to synchronize its use of the section.
" The process ORION creates the global section named GLOBAL_SECTION,
specifying section ags that indicate that it is a global section (SEC$M_GBL) and has read/write access. Input and output address arrays, the page count parameter, and the channel number arguments are not shown; procedures for specifying them are the same, as shown in this example.
# The process CYGNUS associates with the common event ag cluster and
waits for the ag dened as FLGSET; ORION sets this ag when it has nished creating the section. To map the section, CYGNUS species the input and output address arrays, the ag indicating that it is a global section, and the global section name. The number of pages mapped is the same as that specied by the creator of the section. 13.5.6.11 Reading and Writing Data Sections Read/write sections provide a way for a process or cooperating processes to share data les in virtual memory. The sharing of global sections may involve application-dependent synchronization techniques. For example, one process can create and map to a global section in read/write fashion; other processes can map to it in read-only fashion and interpret data written by the rst process. Alternatively, two or more processes can write to the section concurrently. (In this case, the application must provide the necessary synchronization and protection.) After a le is updated, the process or processes can release (or unmap) the section. The modied pages are then written back into the disk le dened as a section. When this is done, the revision number of the le is incremented, and the version number of the le remains unchanged. A full directory listing indicates the revision number of the le and the date and time that the le was last updated.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
13.5.6.12 Releasing and Deleting Sections A process unmaps a section by deleting the virtual addresses in its own virtual address space to which it has mapped the section. If a return address range was specied to receive the virtual addresses of the mapped pages, this address range can be used as input to the Delete Virtual Address Space (SYS$DELTVA) system service, as follows: $DELTVA_S INADR=RETRANGE When a process unmaps a private section, the section is deleted; that is, all control information maintained by the system is deleted. A temporary global section is deleted when all processes that have mapped to it have unmapped it. Permanent global sections are not deleted until they are specically marked for deletion with the Delete Global Section (SYS$DGBLSC) system service; they are then deleted when no more processes are mapped. Note that deleting the pages occupied by a section does not delete the section le but rather cancels the processs association with the le. Moreover, when a process deletes pages mapped to a read/write section and no other processes are mapped to it, all modied pages are written back into the section le. After a section is deleted, the channel assigned to it can be deassigned. The process that created the section can deassign the channel with the Deassign I/O Channel (SYS$DASSGN) system service, as follows: $DASSGN_S CHAN=GBLFAB+FAB$L_STV 13.5.6.13 Writing Back Sections Because read/write sections are not normally updated on disk until the physical pages they occupy are paged out or until all processes referring to the section have unmapped it, a process should ensure that all modied pages are successfully written back into the section le at regular intervals. The Update Section File on Disk (SYS$UPDSEC) system service writes the modied pages in a section into the disk le. SYS$UPDSEC is described in the HP OpenVMS System Services Reference Manual. 13.5.6.14 Image Sections Global sections can contain shareable code. The operating system uses global sections to implement shareable code, as follows: 1. The object module containing code to be shared is linked to produce a shareable image. The shareable image is not, in itself, executable. It contains a series of sections called image sections. 2. You link private object modules with the shareable image to produce an executable image. No code or data from the shareable image is put into the executable image. 3. The system manager uses the INSTALL command to create a permanent global section from the shareable image le, making the image sections available for sharing. 4. When you run the executable image, the operating system automatically maps the global sections created by the INSTALL command into the virtual address space of your process.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
For details about how to create and identify shareable images and how to link them with private object modules, see the HP OpenVMS Linker Utility Manual. For information about how to install shareable images and make them available for sharing as global sections, see the HP OpenVMS System Managers Manual. 13.5.6.15 Page Frame Sections A page frame section is one or more contiguous pages of physical memory or I/O space that have been mapped as a section. One use of page frame sections is to map to an I/O page, thus allowing a process to read device registers. A process mapped to an I/O page can also connect to a device interrupt vector. A page frame section differs from a disk le section in that it is not associated with a particular disk le and is not paged. However, it is similar to a disk le section in most other respects: you create, map, and dene the extent and characteristics of a page frame section in essentially the same manner as you do for a disk le section. To create a page frame section, you must specify page frame number (PFN) mapping by setting the SEC$M_PFNMAP ag bit in the ags argument to the Create and Map Section (SYS$CRMPSC) system service. The vbn argument is now used to specify that the rst page frame is to be mapped instead of the rst virtual block. You must have the user privilege PFNMAP to either create or delete a page frame section but not to map to an existing one. Because a page frame section is not associated with a disk le, you do not use the relpag, chan, and pfc arguments to the SYS$CRMPSC service to create or map this type of section. For the same reason, the SEC$M_CRF (copy-on-reference) and SEC$M_DZRO (demand-zero) bit settings in the ags argument do not apply. Pages in page frame sections are not written back to any disk le (including the paging le). Caution You must use caution when working with page frame sections. If you permit write access to the section, each process that writes to it does so at its own risk. Serious errors can occur if a process writes incorrect data or writes to the wrong page, especially if the page is also mapped by the system or by another process. Thus, any user who has the PFNMAP privilege can damage or violate the security of a system.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
! Two common event flags INTEGER REQUEST_FLAG, 2 INFO_FLAG DATA REQUEST_FLAG /70/ DATA INFO_FLAG /71/ ! User-open routines INTEGER UFO_CREATE EXTERNAL UFO_CREATE . . . ! Open the section file STATUS = LIB$GET_LUN (INFO_LUN) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) SEC_MASK = SEC$M_WRT .OR. SEC$M_DZRO .OR. SEC$M_GBL ! (Last element - first element + size of last element + 511)/512 SEC_LEN = ( (%LOC(TERMINAL) - %LOC(DEVICE) + 6 + 511)/512 ) OPEN (UNIT=INFO_LUN, 2 FILE=INFO.TMP, 2 STATUS=NEW, 2 INITIALSIZE = SEC_LEN, 2 USEROPEN = UFO_CREATE) ! Free logical unit number and map section CLOSE (INFO_LUN) ! Get location of data PASS_ADDR (1) = %LOC (DEVICE) PASS_ADDR (2) = %LOC (TERMINAL) STATUS = SYS$CRMPSC (PASS_ADDR, ! Address of section 2 RET_ADDR, ! Addresses mapped 2 , 2 %VAL(SEC_MASK), ! Section mask 2 GLOBAL_SEC, ! Section name 2 ,, 2 %VAL(SEC_CHAN), ! I/O channel 2 ,,,) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! Create the subprocess STATUS = SYS$CREPRC (, 2 GETDEVINF, ! Image 2 ,,,,, 2 GET_DEVICE, ! Process name 2 %VAL(4),,,) ! Priority IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! Write data to section DEVICE = $FLOPPY1 ! Get common event flag cluster and set flag STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG), 2 CLUSTER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) STATUS = SYS$SETEF (%VAL(REQUEST_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) ! When GETDEVINF has the information, INFO_FLAG is set STATUS = SYS$WAITFR (%VAL(INFO_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) . . . ! This is the program that maps to the global section ! created by the previous program.
Memory Management Services and Routines on OpenVMS VAX 13.5 Using System Services for Memory Allocation
! Define section flags INCLUDE ($SECDEF) ! Mask for section flags INTEGER SEC_MASK ! Data for the section file CHARACTER*12 DEVICE, 2 PROCESS CHARACTER*6 TERMINAL COMMON /DATA/ DEVICE, 2 PROCESS, 2 TERMINAL ! Location of data INTEGER PASS_ADDR (2), 2 RET_ADDR (2) ! Two common event flags INTEGER REQUEST_FLAG, 2 INFO_FLAG DATA REQUEST_FLAG /70/ DATA INFO_FLAG /71/ . . . ! Get common event flag cluster and wait ! for GBL1.FOR to set REQUEST_FLAG STATUS = SYS$ASCEFC (%VAL(REQUEST_FLAG), 2 CLUSTER,,) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) STATUS = SYS$WAITFR (%VAL(REQUEST_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Get location of data PASS_ADDR (1) = %LOC (DEVICE) PASS_ADDR (2) = %LOC (TERMINAL) ! Set write flag SEC_MASK = SEC$M_WRT ! Map the section STATUS = SYS$MGBLSC (PASS_ADDR, ! Address of section 2 RET_ADDR, ! Address mapped 2 , 2 %VAL(SEC_MASK), ! Section mask 2 GLOBAL_SEC,,) ! Section name IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) ! Call GETDVI to get the process ID of the ! process that allocated the device, then ! call GETJPI to get the process name and terminal ! name associated with that process ID. ! Set PROCESS equal to the process name and ! set TERMINAL equal to the terminal name. . . . ! After information is in GLOBAL_SEC STATUS = SYS$SETEF (%VAL(INFO_FLAG)) IF (.NOT. STATUS) CALL LIB$SIGNAL (%VAL(STATUS)) END
14
Using Run-Time Routines for Memory Allocation
This chapter describes the use of run-time routines (RTLs) to allocate and deallocate pages. It contains the following sections: Section 14.1 describes the allocating and freeing of pages. Section 14.2 describes the interactions with other RTL routines. Section 14.3 describes the interactions with system services. Section 14.4 describes how to use zones. Section 14.5 describes the mechanism for allocating and freeing blocks of memory. Section 14.6 describes the RTL algorithms used to allocate and free memory. Section 14.7 describes how to create and manage user-dened zones. Section 14.8 describes the methods of debugging programs that use virtual memory zones. Note In this chapter, all references to pages include both the 512-byte page size on VAX systems and the 512-byte pagelet size on Alpha and I64 systems. See Chapter 13 and Chapter 12 for a discussion of page sizes on VAX and Alpha and I64 systems.
Using Run-Time Routines for Memory Allocation 14.1 Allocating and Freeing Pages
LIB$GET_VM_PAGE and LIB$FREE_VM_PAGE are designed for request sizes ranging from one page to a few hundred pages. If you are using very large request sizes of contiguous space in a single request, the bitmap allocation method that is used may cause fragmentation of your virtual address space because allocated pages are contiguous. For very large request sizes, use direct calls to SYS$EXPREG and do not use LIB$GET_VM_PAGE. The format for LIB$GET_VM_PAGE is as follows: LIB$GET_VM_PAGE (number-of-pages ,base-address) With this routine, you need to specify only the number of pages you need in the number-of-pages argument. The routine returns the base address of the contiguous block of pages that have been allocated in the base-address argument. The rules for using LIB$GET_VM_PAGE and LIB$FREE_VM_PAGE are as follows: Any memory you free by calling LIB$FREE_VM_PAGE must have been allocated by a previous call to LIB$GET_VM_PAGE. You cannot allocate memory by calling either SYS$EXPREG or SYS$CRETVA and then free it using LIB$FREE_VM_PAGE. All memory allocated by LIB$GET_VM_PAGE is page aligned; that is, the low-order 9 bits of the address are all zero. All memory freed by LIB$FREE_ VM_PAGE must also be page aligned; an error status is returned if you attempt to free a block of memory that is not page aligned. You can free a smaller group of pages than you allocated. That is, if you allocated a group of 4 contiguous pages by a single call to LIB$GET_VM_ PAGE, you can free the memory by using several calls to LIB$FREE_VM_ PAGE; for example, free 1 page, 2 pages, and 1 page. You can combine contiguous groups of pages that were allocated by several calls to LIB$GET_VM_PAGE into one group of pages that are freed by a single call to LIB$FREE_VM_PAGE. Before doing this, however, you must compare the addresses to ensure that the pages you are combining are indeed contiguous. Of course, you must ensure that a routine frees only pages that it has previously allocated and still owns. Be especially careful that you do not attempt to free a set of pages twice. You might free a set of pages in one routine and reallocate those same pages from another routine. If the rst routine then deallocates those pages a second time, any information that the second routine stored in them is lost. Because the pages are still allocated to your program (even though to a different routine), this type of programming mistake does not generate an error. The contents of memory allocated by LIB$GET_VM_PAGE are unpredictable. Your program must assign values to all locations that it uses. You should try to minimize the number of request sizes your program uses to avoid fragmentation of the free page pool. This concept is shown in Figure 141.
Using Run-Time Routines for Memory Allocation 14.1 Allocating and Freeing Pages
Figure 141 Memory Fragmentation
5 3 25 15 40 2 2
ZK4150GE
The straight line running across Figure 141 represents the memory allocated to your program. The blocks represent memory that has already been allocated. At this point, if you request 16 pages, memory will have to be allocated at the far right end of the memory line shown in this gure, even though there are 20 free pages before that point. You cannot use 16 of these 20 pages because the 20 free pages are fragmented into groups of 15, 3, and 2 pages. Fragmentation is discussed further in Section 14.4.1.
A program containing routines written in several operating system languages may use a number of these facilities at the same time. This does not cause any problems or impose any restrictions on the user because all of these are layered on the run-time library heap management routines. Note To ensure correct operation, memory that is allocated by one of the higher-level allocators in the preceding list can be freed only by using
Using Run-Time Routines for Memory Allocation 14.2 Interactions with Other Run-Time Library Routines
the corresponding deallocation routine. That is, memory allocated by PASCAL NEW must be freed by calling PASCAL DISPOSE, and a dynamic string can be freed only by calling one of the string package deallocation routines.
Using Run-Time Routines for Memory Allocation 14.3 Interactions with System Services
The complete sequence of steps is as follows: 1. Call LIB$GET_VM_PAGE to allocate a contiguous group of (n+1) pages. The rst n pages are used to map the le; the last page serves as a guard page. 2. Call SYS$CRMPSC using the rst n pages to map the le into your process address space. 3. Process the le. 4. Call SYS$DELTVA to delete the rst n pages and unmap the le. 5. Call SYS$CRETVA to recreate the n pages of virtual address space as demand-zero pages. 6. Call LIB$FREE_VM_PAGE to free (n+1) pages of memory and return them to the processwide page pool. This sequence is satisfactory when mapping small les of a few hundred pages, but it has severe limitations when mapping very large les. As discussed in Section 14.1, you should not use LIB$GET_VM_PAGE to allocate very large groups of contiguous pages in a single request. In addition, when you allocate memory by calling LIB$GET_VM_PAGE (and thus SYS$EXPREG), the pages are charged against your process page le quota. Your page le quota is not charged if you call SYS$CRMPSC with the SEC$M_EXPREG option. You can process very large les using SYS$CRMPSC by rst providing a pool of pages that is sufcient for your program and then by using SYS$CRMPSC and SYS$DELTVA to map and unmap the le. Use LIB$SHOW_VM to obtain an estimate of how much dynamically allocated memory your program requires; round this number up and allow for increased memory usage in the future. You can then use the memory estimate as follows: 1. At the beginning of your program, include code to call LIB$GET_VM_PAGE and allocate the estimated number of pages. You should not request a large number of pages in one call to LIB$GET_VM_PAGE, because this would require contiguous allocation of the pages. 2. Call LIB$FREE_VM_PAGE to free all the pages allocated in step 1; this establishes a pool of free pages for your program. 3. Open les that your program needs; note that RMS may allocate buffers in P0 space. 4. Call SYS$CRMPSC specifying SEC$M_EXPREG to map the le into your process address space at the end of P0 space. 5. Process the le. 6. Call SYS$DELTVA, specifying the address range to release the le. If additional pages were not created after you mapped the le, SYS$DELTVA contracts your address space. Your program can repeat the process of mapping a le without continually expanding its address space.
14.4 Zones
The run-time library heap management routines LIB$GET_VM and LIB$FREE_ VM are based on the concept of zones. A zone is a logically independent memory pool or subheap that you can control as one unit. A program may use several zones to structure its heap memory management. You might use a zone to: Store short-lived data structures that you can subsequently delete all at once Store a program that does not reference a wide range of addresses Specify a memory allocation algorithm specic to your program Specify attributes, like block size and alignment, specic to your program
You create a zone with specied attributes by calling the routine LIB$CREATE_ VM_ZONE. LIB$CREATE_VM_ZONE returns a zone identier value that you can use in subsequent calls to the routines LIB$GET_VM and LIB$FREE_VM. When you no longer need the zone, you can delete the zone and free all the memory it controls by a single call to LIB$DELETE_VM_ZONE. The format for this routine is as follows: LIB$CREATE_VM_ZONE zone_id [,algorithm] [,algorithm_arg] [,ags] [,extend_size] [,initial_size] [,block_size] [,alignment] [,page_limit] [,smallest-block-size] [,zone-name] [,get-page] [,free-page] For more information about LIB$CREATE_VM_ZONE, refer to the HP OpenVMS RTL Library (LIB$) Manual. Allocating Address Space Use the algorithm argument to specify how much space should be allocatedas a linked list of free blocks, as a set of lookaside list indexes by request size, as a set of lookaside lists for some block sizes, or as a single queue of free blocks. Allocating Pages Within the Zone Use the initial_size argument to allocate a specied number of pages from the zone when it is created. After zone creation, you can use LIB$GET_VM to allocate space. Specifying the Block Size Use the block_size argument to specify the block size in bytes. Specifying Block Alignment Use the alignment argument to specify the alignment for each block allocated in bytes. Once a zone has been created and used, use LIB$DELETE_VM_ZONE to delete the zone and return the pages allocated to the processwide page pool. LIB$RESET_VM_ZONE frees pages for subsequent allocation but does not delete the zone or return the pages to the processwide page pool. Use LIB$SHOW_VM_ ZONE to get information about a specic zone. If you want a program to deal with each VM zone created during the invocation, including those created outside of the program, you can call LIB$FIND_VM_ ZONE. At each call, LIB$FIND_VM_ZONE scans the heap management database and returns the zone identier of the next valid zone.
Boundary Tag :A Address of first usable byte. This address is returned by LIB$GET_VM.
Boundary Tag ZK4149GE Boundary tags are not visible to the calling program. The request size you specify when calling LIB$GET_VM is the number of usable bytes your program needs. The address returned by LIB$GET_VM is the address of the rst usable byte of the block, and this same address is used when you call LIB$FREE_VM. Area extension size Pages of memory are allocated to a zone in contiguous groups called areas. By specifying area extension parameters for the zone, you can tailor the zone to achieve a satisfactory balance between locality, memory usage, and execution time for allocating pages. If you specify a large area size, you improve locality for blocks in the zone, but you may waste a large amount of virtual memory. Pages can be allocated to an area of a zone, but the memory might never be used to satisfy a LIB$GET_VM allocation request. If you specify a small area extension size, you reduce the number of pages used, but you may reduce locality and you increase the amount of overhead for area control blocks.
You can also control the way in which zones are extended by using the LIB$M_VM_EXTEND_AREA attribute. This attribute species that when new pages are allocated for a zone, they should be appended to an existing area if the pages are adjacent to an existing area. Block size The block size attribute species the number of bytes in the basic allocation quantum for the zone. All allocation requests are rounded up to a multiple of the block size. The block size must be a power of 2 in the range of 8 to 512. Table 142 lists the possible block sizes. Table 142 Possible Values for the Block Size Attribute
Block Size (Power of 2) 2 2
3 4
25
29
By adjusting the block size, you can control the effects of internal fragmentation and external fragmentation. Internal fragmentation occurs when the request size is rounded up and more bytes are allocated than are required to satisfy the request. External fragmentation occurs when there are many small blocks on the free list, but none of them is large enough to satisfy an allocation request. If you do not specify a value for block size, a default of 8 bytes is used. Alignment The alignment attribute species the required address boundary alignment for each block allocated. The alignment value must be a power of 2 in the range of 4 to 512. The block size and alignment values are closely related. If you are not using boundary-tagged blocks, the larger value of block size and alignment controls both the block size and alignment. If you are using boundary-tagged blocks, you can minimize the overhead for the boundary tags by specifying a block size of 8 and an alignment of 4 (longword alignment). On VAX systems, note that the VAX interlocked queue instructions require quadword alignment, so you should not specify longword alignment for blocks that will be inserted on an interlocked queue. If you do not specify an alignment value, a default of 8 is used (alignment on a quadword boundary). For I64, the default is 16 (alignment on an octaword boundary). Page limit You can specify the maximum number of pages that can be allocated to the zone. If you do not specify a limit, the only limit is the virtual address limit for the total process imposed by process quotas and system parameters. Fill on allocate If you do not specify the allocation ll attribute, LIB$GET_VM does not initialize the contents of the blocks of memory that it supplies. The contents of the memory are unpredictable, and you must assign a value to each location your program uses. In many applications, it is convenient to initialize every byte of dynamically allocated memory to the value 0. You can request that LIB$GET_VM do this initialization by specifying the allocation ll attribute LIB$M_VM_GET_ FILL0 when you create the zone. If your program does not use the allocation ll attribute, it may be very difcult to locate bugs where the program does not properly initialize dynamically allocated memory. As a debugging aid, you can request that
The zone identier for the default zone has the value 0 (see Section 14.4.2 for more information on the default zone). You can allocate and free blocks of memory in the default zone by either specifying a zone-id value of 0 or by omitting the zone-id argument when you call LIB$GET_VM and LIB$FREE_ VM. You cannot use LIB$DELETE_VM_ZONE or LIB$RESET_VM_ZONE on the default zone; these routines return an error status if the value for zone-id is 0.
The Quick Fit and Frequent Sizes algorithms use lookaside lists to speed allocation and freeing for certain request sizes. A lookaside list is the software analog of a hardware cache. It takes less time to allocate or free a block that is on a lookaside list. For each of the algorithms, LIB$GET_VM performs one or more of the following operations: Tries to allocate a block from an appropriate lookaside list. Scans the list of areas owned by the zone. For each area, it tries to allocate a block from the free list and then tries to allocate a block from the block of unallocated memory at the end of the area. Adds a new area to the zone and allocates the block from that area.
For each of the algorithms, LIB$FREE_VM performs one or more of the following operations: Places the block on a lookaside list associated with the zone if there is an appropriate list. Locates the area that contains the block. If the zone has boundary tags, the tags encode the area; otherwise, it scans the list of areas owned by the zone to nd the correct area. Inserts the block on the area free list and checks for merges with adjacent free blocks. If the zone has boundary tags, LIB$FREE_VM checks the tags of adjacent blocks; if a merge does not occur, it inserts the block at the tail of the free list. If the zone does not have boundary tags, LIB$FREE_VM scans the sorted free list to nd the correct insertion point. It also checks the preceding and following blocks for merges.
Using Run-Time Routines for Memory Allocation 14.6 Allocation Algorithms 14.6.2 Quick Fit Algorithm
The Quick Fit algorithm (LIB$K_VM_QUICK_FIT) maintains a set of lookaside lists indexed by request size for request sizes in a specied range. For request sizes that are not in the specied range, a First Fit list of free blocks is maintained. An allocation request is satised by removing a block from the appropriate lookaside list; if the lookaside list is empty, a First Fit allocation is done. When a block is freed, it is placed on either a lookaside list or the First Fit list according to its size. Free blocks that are placed on a lookaside list are neither merged with adjacent free blocks nor split to satisfy a request for a smaller block.
Each time that one of the run-time library heap management routines (LIB$GET_ VM, LIB$FREE_VM, LIB$RESET_VM_ZONE, LIB$DELETE_VM_ZONE) is called to perform an operation on a user-dened zone, the corresponding routine that you specied is called to perform the actual operation. You need not make any changes in the calling program to use user-dened zones; their use is transparent.
Example 141 Monitoring Heap Operations with a User-Dened Zone C+ C This is the main program that creates a zone and exercises it. C C Note that the main program simply calls LIB$GET_VM and LIB$FREE_VM. C It contains no special coding for user-defined zones. CPROGRAM MAIN IMPLICIT INTEGER(A-Z) CALL MAKE_ZONE(ZONE) CALL CALL CALL CALL CALL END LIB$GET_VM(10, I1, ZONE) LIB$GET_VM(20, I2, ZONE) LIB$FREE_VM(10, I1, ZONE) LIB$RESET_VM_ZONE(ZONE) LIB$DELETE_VM_ZONE(ZONE)
C+ C This is the subroutine that creates a user-defined zone for monitoring. C Each GET, FREE, or RESET prints a line of output on the terminal. C Errors are signaled. CSUBROUTINE MAKE_ZONE(ZONE) IMPLICIT INTEGER (A-Z) EXTERNAL GET_RTN, FREE_RTN, RESET_RTN, LIB$DELETE_VM_ZONE C+ C Create the primary zone. The primary zone supports C the actual allocation and freeing of memory. CSTATUS = LIB$CREATE_VM_ZONE(REAL_ZONE) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS)) C+ C Create a user-defined zone that monitors operations on REAL_ZONE. CSTATUS = LIB$CREATE_USER_VM_ZONE(USER_ZONE, REAL_ZONE, 1 GET_RTN, 1 FREE_RTN, 1 RESET_RTN, 1 LIB$DELETE_VM_ZONE) IF (.NOT. STATUS) CALL LIB$SIGNAL(%VAL(STATUS))
(continued on next page)
10
C+ C FREE routine for user-defined zone. CFUNCTION FREE_RTN(SIZE, ADDR, ZONE) IMPLICIT INTEGER(A-Z) STATUS = LIB$FREE_VM(SIZE, ADDR, ZONE) IF (.NOT. STATUS) THEN CALL LIB$SIGNAL(%VAL(STATUS)) ELSE TYPE 20, SIZE, ADDR FORMAT( Freed ,I4, bytes at ,Z8) ENDIF FREE_RTN = STATUS END
20
C+ C RESET routine for user-defined zone. CFUNCTION RESET_RTN(ZONE) IMPLICIT INTEGER(A-Z) STATUS = LIB$RESET_VM_ZONE(ZONE) IF (.NOT. STATUS) THEN CALL LIB$SIGNAL(%VAL(STATUS)) ELSE TYPE 30, ZONE FORMAT( Reset zone at , Z8) ENDIF RESET_RTN = STATUS END
30
Using Run-Time Routines for Memory Allocation 14.8 Debugging Programs That Use Virtual Memory Zones
15
Alignment on VAX, Alpha, and I64 Systems
This chapter describes the importance and techniques of alignment for OpenVMS VAX, OpenVMS Alpha1 , and OpenVMS I64 systems It contains the following subsections: Section 15.1 describes alignment on OpenVMS VAX, OpenVMS Alpha, and OpenVMS I64 systems. Section 15.2 describes using compilers for alignment. Section 15.3 describes using various tools to uncover unaligned data.
15.1 Alignment
Alignment is an aspect of a data item that refers to its placement in memory. The mixing of byte, word, longword, and quadword data types can lead to data that is not aligned on natural boundaries. A naturally aligned datum of size 2**N is stored in memory at a starting byte address that is a multiple of 2**N, that is, an address that has N low-order zero bits. Data is naturally aligned when its address is an integral multiple of the size of the data in bytes (for example, when the following occurs): A byte is aligned at any address. A word is aligned at any address that is a multiple of 2. A longword is aligned at any address that is a multiple of 4. A quadword is aligned at any address that is a multiple of 8.
Data that is not aligned is referred to as unaligned. Throughout this chapter, the term aligned is used instead of naturally aligned. Table 151 shows examples of common data sizes, their alignment, the number of zero bits in an aligned address for that data, and a sample aligned address in hexadecimal.
Reprinted from an article in the March/April 1993 issue of Digital Systems Journal, Volume 15, Number 2, titled "Alpha AXP(TM) Migration: Understanding Data Alignment on OpenVMS AXP Systems" by Eric M. LaFranchi and Kathleen D. Morse. Copyright 1993 by Cardinal Business Media, Inc., 101 Witmer Road, Horsham, PA 19044.
An aligned structure has all its members aligned. An unaligned structure has one or more unaligned members. Figure 151 shows examples of aligned and unaligned structures. Figure 151 Aligned and Unaligned Structures
Aligned Structure: 7 63 55 aligned longword 6 5 4 31 3 23 byte 2 1 7 byte 0 Bytes 0 Bits
:aaa0 :aaa8
:aaa0
:aaa8
byte
= unaligned quadword
ZK6999AGE
Though Alpha systems do not use microcode to automatically handle unaligned references, PALcode traps the faults and corrects unaligned references as the data is processed. If you use the shorter load/store instruction sequences and your data in unaligned, then you incur an alignment fault PALcode xup. The use of PALcode to correct alignment faults results in the slowest of the three ways to process your data. By using directives to the compiler, you can tell your compiler to create a safe set of instructions. If it is unaligned, the compiler uses a set of unaligned load/store instructions. These unaligned load/store instructions are called safe sequences because they never generate unaligned data exceptions. Code sequences that use the unaligned load/store instructions are longer than the aligned load/store instruction sequences. By using unaligned load/store instructions and longer instruction sequences, you can obtain the desired results without incurring an alignment trap. This technique allows you to avoid the signicant performance impact of a trap and subsequent data xes. By xing the data yourself so that it is aligned, you can use a short instruction stream. This results in the fastest way to process your data. When aligning data, the following recommendations are suggested: If references to the data must be made atomic, then the data must be aligned. Otherwise, an unaligned fault causes a fatal reserved operand fault in this case. If you x alignment problems in public interfaces, then you could break existing programs.
To detect unaligned reference information, you can use utilities such as the OpenVMS Debugger and Performance and Coverage Analyzer (PCA). You can also use the OpenVMS Alpha handler to generate optional informational exceptions for process space references. This allows condition handlers to track unaligned references. Alignment fault system services allow you to enable and disable the delivery of these informational exceptions. Section 15.3.3 discusses
struct { char byte; short word; long longword; } mystruct; #pragma member_alignment restore #
! Saves the current alignment setting. " Sets nomember_alignment, which means that the data is to be packed in
The base alignment of a data structure is set to be the alignment of the largest member in the structure. If the largest element of a data structure is a longword, for example, then the base alignment of the data structure is longword alignment. The malloc( ) function of the HP C Run-Time Library retrieves pointers that are at least quadword aligned. Because it is the exception rather than the rule to encounter unaligned data in C programs, the compiler assumes most data references are aligned. Pointers, for example, are always assumed to be aligned; only data structures declared with the pragma nomember_ alignment are assumed to contain unaligned data. If the HP C compiler believes the data might be unaligned, it generates the safe instruction sequences; that is, it uses the unaligned load/store instructions. Also, you can use the /WARNING=ALIGNMENT compiler qualier to turn on alignment checking by the compiler. This results in a compiler warning for unaligned data references. On OpenVMS Alpha and OpenVMS I64 systems, dereferencing a pointer to a longword- or quadword-aligned object is more efcient than dereferencing a pointer to a byte- or word-aligned object. Therefore, the compiler can generate more optimized code if it makes the assumption that a pointer object of an aligned pointer type does point to an aligned object.
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only)
Because the compiler determines the alignment of the dereferenced object from the type of the pointer, and the program is allowed to compute a pointer that references an unaligned object (even though the pointer type indicates that it references an aligned object), the compiler must assume that the dereferenced objects alignment matches or exceeds the alignment indicated by the pointer type. Specifying /ASSUME=ALIGNED_OBJECTS (the default) allows the compiler to make such an assumption. With this assumption made, the compiler can generate more efcient code for pointer dereferences of aligned pointer types. To prevent the compiler from assuming the pointer types alignment for objects that it points to, use the /ASSUME=NOALIGNED_OBJECTS qualier. See the HP C Users Guide for OpenVMS Systems for additional information. 15.2.1.1 Compiler Example of Memory Structure of VAX C and HP C The following code examples, and Figure 152, and Figure 153 illustrate a C data structure containing byte, word, and longword data and how it would be laid out in memory by VAX C and HP C. struct { char byte; short word; long longword; }mystruct; On VAX systems, when compiled using the VAX C compiler, the previous structure has a memory layout as shown in Figure 152, where each piece of data begins on the next byte boundary. Figure 152 Alignment Using VAX C Compiler
63 55 longword 31 23 word 7 byte
ZK7000AGE
On Alpha and I64 systems, when compiled using the HP C compiler, the structure is padded to achieve natural alignment, if needed, as shown in Figure 153. Figure 153 Alignment Using HP C Compiler
63 55 longword 31 23 word 7 byte
ZK7001AGE
On Alpha and I64 systems, note where HP C places some padding to align naturally all the data structure elements. HP C would also align the structure itself on a longword boundary. The HP C compiler aligns the structure on a longword boundary because the largest element in the structure is a longword.
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only) 15.2.2 The BLISS Compiler
On Alpha and I64 systems, the BLISS compiler provides greater control over alignment than the HP C compiler. The BLISS compiler also makes different assumptions about alignment. The Alpha and I64 BLISS compilers, like the VAX BLISS compiler, allows explicit specication of program section (PSECT) alignment. On Alpha and I64 systems, BLISS compilers align all explicitly declared data on naturally aligned boundaries. On Alpha and I64 systems, you can align declared data in BLISS source code with the align attribute, although the alignment specied cannot be greater than that for the PSECT in which the data is contained. The alignment attribute indicates a specic address boundary by means of a boundary value, N, which species that the binary address of the data segment must end in at least N zeros. To specify the static byte datum A to be aligned on a longword boundary, for example, use the following declaration: OWN A:BYTE ALIGN(2) On Alpha and I64 systems, when the BLISS compiler cannot determine the base alignment of a BLOCK, it assumes full word alignment, unless told otherwise by a command qualier or switch declaration. Like the HP C compiler, if the BLISS compilers believe that the data is unaligned, they generate safe instruction sequences. If you specify the qualier /CHECK=ALIGNMENT in the BLISS command line, then warning information is provided when they detect unaligned memory references.
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only)
Besides command line qualiers, HP Fortran provides two directives to control the alignment of RECORD statement data and COMMON block data. The CDEC$OPTIONS directive controls whether the HP Fortran compiler naturally aligns elds in RECORD statements or data items in COMMON blocks for performance reasons, or whether the compiler packs those elds and data items together on arbitrary byte boundaries. The CDEC$OPTIONS directive, like the /ALIGN command qualier, takes class and rule parameters. Also, the CDE$OPTIONS directive overrides the compiler option /ALIGN. By default, the HP Fortran compiler emits alignment warnings, but these can be turned off by using the qualier /WARNINGS=NOALIGNMENT.
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only)
The .PSECT and .ALIGN directives are supported. The compiler knows the alignment of locally declared data. The compiler makes certain assumptions about the alignment, but does allow programmer control over those assumptions. The Macro-32 compiler provides two directives for changing the compilers assumptions about alignment, which results in letting the compiler produce more efcient code. These two directives are as follows: .SET_REGISTERS allows you to specify whether a register points to aligned or unaligned data. You use this directive when the result of an operation is the opposite of what the compiler expects. Also, use the same directive to declare registers that the compiler would not otherwise detect as input or output registers. For example, consider the DIVL instruction. After executing this instruction in the following example, the Macro-32 compiler assumes that R1 is unaligned. A future attempt at using R1 as a base register will cause the compiler to generate an unaligned fetch sequence. However, suppose you know that R1 is always aligned after the DIVL instruction. You can then use the .SET_REGISTERS directive to inform the compiler of this. When the compiler sees the MOVL from 8(r1), it knows that it can use the shorter aligned fetch (LDL) to retrieve the data. At run time, however, if R1 is not really aligned, then this results in an alignment trap. The following example shows the setting of a register to be aligned: divl movl r0,r1 8(r1),r2 ;Compiler now thinks R1 unaligned ;Compiler now treats R1 as aligned
.set_registers aligned=r1 .SYMBOL_ALIGNMENT allows you to specify the alignment of any memory reference that uses a symbolic offset. The .SYMBOL_ALIGNMENT directive associates an alignment attribute with a symbol denition used as a register offset; you can use it when you know the base register will be aligned for every use of the symbolic offset. This attribute guarantees to the compiler that the base register has that alignment, and this enables the compiler to generate optimal code. In the example that follows, QUAD_OFF has a symbol alignment of QUAD, LONG_OFF, a symbol alignment of LONG, and NONE_OFF has no symbol alignment. In the rst MOVL instruction, the compiler assumes that R0, since it is used as a base register with QUAD_OFF, is quadword aligned. Since QUAD_OFF has a value of 4, the compiler knows it can generate an aligned longword fetch. For the second MOVL, R0 is assumed to be longword aligned, but since LONG_OFF has a value of 5, the compiler realizes that offset+ base is not longword aligned and would generate a safe unaligned fetch sequence. In the third MOVL, R0 is assumed to be unaligned, unless the compiler knows otherwise from other register tracking, and would generate a safe unaligned sequence. The .SYMBOL_ALIGNMENT alignment remains in effect until the next occurrence of the directive. .symbol_alignment QUAD quad_off=4 .symbol_alignment LONG long_off=5 .symbol_alignment NONE none_off=6
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only)
movl quad_off(r0),r1 movl long_off(r0),r2 movl none_off(r0),r3 ;Assumes R0 quadword aligned ;Assumes R0 longword aligned ;No presumed alignment for R0
15.2.4.1 Precedence of Alignment Controls The order of precedence of the compilers alignment controls, from strongest (.SYMBOL_ALIGNMENT) to weakest (built-in assumptions and tracking mechanisms), is as follows: 1. .SYMBOL_ALIGNMENT directive 2. .SET_REGISTER directive 3. /UNALIGN qualier 4. Built-in assumptions and tracking mechanisms 15.2.4.2 Recommendations for Aligning Data The following recommendations apply to aligning data: If references to the data must be made atomic with /PRESERVE=ATOMICITY or .PRESERVE ATOMICITY, the data must be aligned. For data in internal or privileged interfaces, do not automatically make changes to improve data alignment. You should consider the frequency with which the data structure is accessed, the amount of work involved in realigning the structure, and the risk that things might go wrong. In judging the amount of work involved, make sure you know all accesses to the data; do not merely guess. If you own all accesses in the code for which you are responsible and if you are making changes in the module (or modules) anyway, then it is safe to x the alignment problem. Do not routinely unpack byte and word data into longwords or quadwords. The time to do this is when you are xing an alignment problem (word not on word boundary), subject to the aforementioned cautions and constraints, or if you know the data granularity is a problem. If you do not own all the accesses to the data, there still may be circumstances under which xing alignment is appropriate. If the data is frequently accessed, if performance is a real issue, and if you must unavoidably scramble the data structure anyway, it makes sense to align the structure at the same time. It is important that you notify other programmers whose code may be affected. Do not assume in such cases that all related modules will recompile or that program documentation will help others detect errant data cell separation assumptions. Always assume that changes like this will reveal irregular programming practices and will not go smoothly.
Alignment on VAX, Alpha, and I64 Systems 15.2 Using Compilers for Alignment (Alpha and I64 Only)
In pessimistic mode, all non PC-relative references are treated as unaligned using the safe access sequences. In optimistic mode, the emulated VAX registers (R0R14) are assumed to be quadword aligned upon entry to each basic block. Autoincrement and autodecrement changes to the base registers are tracked. The offset plus the base register alignment are used to determine the alignment and the appropriate access sequence is generated. The /OPTIMIZE=NOALIGN qualier on the VEST command tells VEST to be pessimistic; it assumes that base registers are not aligned, and should generate the safe instruction sequence. Doing this can slow execution speed by a factor of two or more, if there are no unaligned data references. On the other hand, it can result in a performance gain if there are a signicant number of unaligned references, since safe sequences avoid any unaligned data traps. Additional controls preserve atomicity in longword data that is not naturally aligned. Wherever possible, data should be aligned in the VAX source code and the image rebuilt before translating the image with DECmigrate. This results in better performance on both VAX and Alpha systems.
Alignment on VAX, Alpha, and I64 Systems 15.3 Using Tools for Finding Unaligned Data
Example 151 (Cont.) OpenVMS Debugger Output from SET OUTPUT LOG Command ------- Compile and Link commands ------$ cc/debug debug_example $ link/debug debug_example $ run debug_example ------- DEBUG session using set output log ------Go ! break at routine DEBUG_EXAMPLE\main ! 598: p - (char *)malloc( 32 ); set break/unaligned_data set break/exception set radix hexadecimal Go !Unaligned data access: virtual address - 003CEEA1, PC - 00020048 !break on unaligned data trap preceding DEBUG_EXAMPLE\main\%LINE 602 ! 602: printf( "data - %d\n", lp[0] ); ex/inst 00020048-4 !DEBUG_EXAMPLE\main\%LINE 600+4: STL R1,(R0) ex r0 !DEBUG_EXAMPLE\main\%R0: 00000000 003CEEA1
Also, PCA can display data according to the PC of the fault, or by the virtual address of the unaligned data.
Alignment on VAX, Alpha, and I64 Systems 15.3 Using Tools for Finding Unaligned Data
Exception method. This method requires no buffer. Unaligned data exceptions are signaled to the image, at which point a user-written condition handler takes whatever action is desired. If no user-written handler is set up, then an informational exception message is broadcast for each unaligned data trap, and the program continues to execute. SYS$STOP_ALIGN_FAULT_REPORT. This service cancels unaligned data exception reporting for the current image if it were previously enabled. If you do not explicitly call this routine, then reporting is disabled by the operating systems image rundown logic. SYS$GET_ALIGN_FAULT_DATA. This service retrieves the accumulated, buffered alignment data when using the buffered collection method.
You can use two of the eight system services to report unaligned data exceptions for the current process. The two services are as follows: SYS$PERM_REPORT_ALIGN_FAULT. This service enables unaligned data exception reporting for the process. Once you enable this service, the reporting remains in effect for the process until you explicitly disable it. Once enabled, the SS$_ALIGN condition is signaled for all unaligned data exceptions while the process is active. By default, if no user-written exception handler handles the condition, this results in an information display message for each unaligned data exception. This service provides a convenient way of running a number of images without modifying the code in each image, and also of recording the unaligned data exception behavior of each image. SYS$PERM_DIS_ALIGN_FAULT_REPORT. This service disables unaligned data exception reporting for the process.
The three system services that allow you to track systemwide alignment faults are as follows: SYS$INIT_SYS_ALIGN_FAULT_REPORT. This service initializes system process alignment fault reporting. SYS$STOP_SYS_ALIGN_FAULT_REPORT. This service disables systemwide alignment fault reporting. SYS$GET_SYS_ALIGN_FAULT_DATA. This service obtains data from the system alignment fault buffer.
These services require CMKRNL privilege. Alignment faults for all modes and all addresses can be reported using these services. The user can also set up masks to report only certain types of alignment faults. For example, you can get reports on only kernel modes, only user PC, or only data in system space.
Alignment on VAX, Alpha, and I64 Systems 15.3 Using Tools for Finding Unaligned Data
$ ANALYZE/SYSTEM SDA> FLT LOAD SDA> FLT START TRACE SDA> FLT SHOW TRACE /SUMMARY Fault Trace Information: (at 18-AUG-2004 04:49:58.61, trace time 00:00:45.229810) --------------------------------------------------------------------------------Exception PC ----------------FFFFFFFF.80B25621 FFFFFFFF.80B25641 FFFFFFFF.80B25660 FFFFFFFF.80B25671 FFFFFFFF.80B25691 FFFFFFFF.80B39330 FFFFFFFF.807273A1 FFFFFFFF.807273D1 FFFFFFFF.80B25631 FFFFFFFF.80B25661 FFFFFFFF.80B25600 FFFFFFFF.80B25650 FFFFFFFF.80B25680 FFFFFFFF.84188930 FFFFFFFF.80A678E0 FFFFFFFF.841888A0 FFFFFFFF.80B25AE0 FFFFFFFF.80B26870 FFFFFFFF.80B256F0 FFFFFFFF.80B25AC0 FFFFFFFF.80B25EF0 FFFFFFFF.80B256E0 [...............] SDA> FLT STOP TRACE SDA> FLT UNLOAD Count -----------1260 1260 1260 1260 1260 1243 1144 1144 1131 1131 1131 1131 1131 999 991 976 392 392 360 336 336 326 Exception PC Module Offset ------------ ---------------------------------SECURITY+1B021 SECURITY 0001B021 SECURITY+1B041 SECURITY 0001B041 SECURITY+1B060 SECURITY 0001B060 SECURITY+1B071 SECURITY 0001B071 SECURITY+1B091 SECURITY 0001B091 NSA$SIZE_NSAB_C+00920SECURITY 0002ED30 LOCKING+271A1 LOCKING 000271A1 LOCKING+271D1 LOCKING 000271D1 SECURITY+1B031 SECURITY 0001B031 SECURITY+1B061 SECURITY 0001B061 SECURITY+1B000 SECURITY 0001B000 SECURITY+1B050 SECURITY 0001B050 SECURITY+1B080 SECURITY 0001B080 LIBRTL+00158930 LIBRTL 00158930 RMS+001D4EE0 RMS 001D4EE0 LIBRTL+001588A0 LIBRTL 001588A0 EXE$TLV_TO_PSB_C+003B0SECURITY 0001B4E0 SECURITY+1C270 SECURITY 0001C270 SECURITY+1B0F0 SECURITY 0001B0F0 EXE$TLV_TO_PSB_C+00390SECURITY 0001B4C0 EXE$TLV_TO_PSB_C+007C0SECURITY 0001B8F0 SECURITY+1B0E0 SECURITY 0001B0E0
16
Memory Management with VLM Features
OpenVMS Alpha and OpenVMS I64 very large memory (VLM) features for memory management provide extended support for database, data warehouse, and other very large database (VLDB) products. The VLM features enable database products and data warehousing applications to realize increased capacity and performance gains. By using the extended VLM features, application programs can create large, in-memory global data caches that do not require an increase in process quotas. These large memory-resident global sections can be mapped with shared global pages to dramatically reduce the system overhead required to map large amounts of memory. This chapter describes the following OpenVMS Alpha and OpenVMS I64 memory management VLM features: Memory-resident global sections Fast I/O and buffer objects for global sections Shared page tables Expandable global page table Reserved memory registry
To see an example program that demonstrates many of these VLM features, refer to Appendix C.
Fault option To use the fault option, it is recommended, but not required that the pages within the memory-resident global section be deducted from the systems uid page count through the Reserved Memory Registry. Using the Reserved Memory Registry ensures that AUTOGEN tunes the system properly to exclude memory-resident global section pages in its calculation of the systems uid page count. AUTOGEN sizes the system pagele, number of processes, and working set maximum size based on the systems uid page count.
Memory Management with VLM Features 16.3 Fast I/O and Buffer Objects for Global Sections
Buffer objects enable Fast I/O system services, which can be used to read and write very large amounts of shared data to and from I/O devices at an increased rate. By reducing the CPU cost per I/O request, Fast I/O increases performance for I/O operations. Fast I/O improves the ability of VLM applications, such as database servers, to handle larger capacities and higher data throughput rates.
Memory Management with VLM Features 16.3 Fast I/O and Buffer Objects for Global Sections
This method allows for maximum exibility because the process can continue to page and can even be swapped out of the balance set while the I/O is still outstanding or active. No pages need to be locked for buffered I/O, and for direct I/O, most of the process pages can still be paged or swapped. However, this exibility comes at a price: all pages involved in an I/O must be probed or locked and unlocked for every single I/O. For applications with high I/O rates, the operating system can spend a signicant amount of time on these time-consuming operations. Buffer objects can help avoid much of this overhead.
Memory Management with VLM Features 16.3 Fast I/O and Buffer Objects for Global Sections
For more information about using Fast I/O features, see the HP OpenVMS I/O Users Reference Manual.
Memory Management with VLM Features 16.4 Shared Page Tables 16.4.1 Memory Requirements for Private Page Tables
Table 161 highlights the physical memory requirements for private page tables and shared page tables that map to various sizes of global sections by various numbers of processes. This table illustrates the amount of physical memory saved systemwide through the use of shared page tables. For example, when 100 processes map to a 1 GB global section, 99 MB of physical memory are saved by mapping to the global section with shared page tables. Overall system performance benets from this physical memory savings because of the reduced contention for the physical memory system resource. Individual processes benet from the reduction of working set usage by page table pages, thus allowing a process to keep more private code and data in physical memory. Table 161 Page Table Size Requirements
Number of Mapping Processes 1 10 100 1000
Key PPT = Private Page Tables SHPT = Shared Page Tables
Size of Global Section 8MB PPT 8KB 80KB 800KB 8MB 8MB SHPT 8KB 8KB 8KB 8KB 1GB PPT 1MB 10MB 100MB 1GB 1GB SHPT 1MB 1MB 1MB 1MB 8GB PPT 8MB 80MB 800MB 8GB 8GB SHPT 8MB 8MB 8MB 8MB 1TB PPT 1GB 10GB 100GB 1TB 1TB SHPT 1GB 1GB 1GB 1GB
A shared page table region can only map memory-resident global sections. An application can map more than one memory-resident global section into a shared page table region. The starting virtual address for global sections mapped into a shared page table region are always rounded to a page table page boundary. This prevents two distinct global sections from sharing the same page table page. Attempts to create virtual address space in a shared page table region with any other system service except those listed in Step 2 will fail. Note Processes can specify a non-shared page table region for mapping to a memory- resident global section with shared page tables. In this case, process private page tables are used to map to the global section.
Because the global page table is mapped in 64-bit S2 space, which is a minimum of 6 GB on Alpha (S2 space on I64 is always 8 TB minus 2 GB), these conditions can be met by almost all systems. Only extremely memory-starved systems or systems with applications making extensive use of S2 virtual address space may make it impossible to grow the global page table on demand.
Memory Management with VLM Features 16.5 Expandable Global Page Table
Because global pages are a system resource that also affects other tuning parameters, HP recommends using AUTOGEN and rebooting systems to increase GBLPAGES. If a reboot is not possible for operational reasons, you can change the parameter on the running system using the following commands: $ RUN SYS$SYSTEM:SYSGEN SYSGEN> USE ACTIVE SYSGEN> SET GBLPAGES new_value SYSGEN> WRITE ACTIVE The WRITE ACTIVE command requires the CMKRNL privilege. The same commands also allow you to reduce the effective size of the global page table. The global page table is actually reduced and full pages are released to the system as uid pages under the following conditions: A global section is deleted, thus freeing up global page table entries. The value of GBLPAGES indicates a smaller size of the global page table than the current size. Unused entries exist at the high address end of the global page table that allow you to contract the stucture.
Reducing the active value of GBLPAGES below the number of currently used global pages does not affect currently used global pages. It only prevents the creation of additional global pages. Increasing the active value of the GBLPAGFIL parameter always succeeds, up to the maximum positive integer value. As with GBLPAGES, reducing the value of GBLPAGFIL below the number of global pages that may be paged against the systems pagele has no effect on these pages. Doing so simply prevents the creation of additional global pagele sections. Note that an increase of GBLPAGFIL may also require that additional pagele space be satised by installing an additional pagele.
Part IV
Appendixes: Macros and Examples of 64-Bit Programming
This part describes macros used in 64-bit programming and presents two examples of 64-bit programming.
A
C Macros for 64-Bit Addressing
This appendix describes the following C macros for manipulating 64-bit addresses, for checking the sign extension of the low 32 bits of 64-bit values, and for checking descriptors for the 64-bit format: $DESCRIPTOR64 $is_desc64 $is_32bits
DESCRIPTOR64
Constructs a 64-bit string descriptor.
Format
$DESCRIPTOR64 name, string
Description
name is name of variable string is address of string
Example: int status; $DESCRIPTOR64 (gblsec, "GBLSEC_NAME"); ... /* Create global page file section */ status = sys$create_gpfile (&gblsec, 0, 0, section_size, 0, 0); ... This macro resides in descrip.h in SYS$LIBRARY:DECC$RTLDEF.TLB.
$is_desc64
Distinguishes a 64-bit descriptor.
Format
$is_desc64 desc
Description
desc is address of 32-bit or 64-bit descriptor Returns: 0 if descriptor is 32-bit descriptor 1 if descriptor is 64-bit descriptor
Example: #include <descrip.h> #include <far_pointers.h> ... if ($is_desc64 (user_desc)) { /* Get 64-bit address and 64-bit length from descriptor */ ... } else { /* Get 32-bit address and 16-bit length from descriptor */ ... } This macro resides in descrip.h in SYS$LIBRARY:DECC$RTLDEF.TLB.
$is_32bits
Tests if a quadword is 32-bit sign-extended.
Format
$is_32bits arg
Description
Input: arg is 64-bit value Output: 1 if arg is 32-bit sign-extended 0 if arg is not 32-bit sign-extended
B
64-Bit Example Program
This example program demonstrates the 64-bit region creation and deletion system services. It uses SYS$CREATE_REGION_64 to create a region and then uses SYS$EXPREG_64 to allocate virtual addresses within that region. The virtual address space and the region are deleted by calling SYS$DELETE_ REGION_64. /* This program creates a region in P2 space using the region creation service and then creates VAs within that region. The intent is to demonstrate the use of the region services and how to allocate virtual addresses within a region. The program also makes use of 64-bit descriptors and uses them to format return values into messages with the aid of SYS$GETMSG. To build and run this program type: $ CC/POINTER_SIZE=32/STANDARD=RELAXED/DEFINE=(__NEW_STARLET=1) REGIONS.C $ LINK REGIONS.OBJ $ RUN REGIONS.EXE */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include <descrip.h> <far_pointers.h> <gen64def.h> <iledef.h> <ints.h> <iosbdef.h> <psldef.h> <ssdef.h> <starlet.h> <stdio.h> <stdlib.h> <string.h> <syidef.h> <vadef.h> /* /* /* /* /* /* /* /* /* /* /* /* /* /* Descriptor Definitions Long Pointer Definitions Generic 64-bit Data Type Definition Item List Entry Definitions Various Integer Typedefs I/O Status Block Definition PSL$ Constants SS$_ Message Codes System Service Prototypes printf malloc, free memset $GETSYI Item Code Definitions VA Creation Flags and Constants */ */ */ */ */ */ */ */ */ */ */ */ */ */ */
/* Module-wide constants and macros. #define #define #define #define #define BUFFER_SIZE HW_NAME_LENGTH PAGELET_SIZE REGION_SIZE good_status(code) 132 32 512 128 ((code) & 1)
*/
*/
int get_page_size (void); static void print_message (int code, char *string); main (int argc, char **argv) { int i, status; uint64 length_64, master_length_64, return_length_64; GENERIC_64 region_id_64; VOID_PQ master_va_64, return_va_64; /* Get system page size, using SYS$GETSYI. status = get_page_size (); if (!good_status (status)) return (status); /* Get a buffer for the message descriptor. */ */
msgdsc.dsc64$pq_pointer = malloc (BUFFER_SIZE); printf ("Message Buffer Address = %016LX\n\n", msgdsc.dsc64$pq_pointer); /* Create a region in P2 space. length_64 = REGION_SIZE*page_size; status = sys$create_region_64 ( length_64, /* Size of Region to Create VA$C_REGION_UCREATE_UOWN, /* Protection on Region 0, /* Allocate in Region to Higher VAs ®ion_id_64, /* Region ID &master_va_64, /* Starting VA in Region Created &master_length_64); /* Size of Region Created if (!good_status (status)) { print_message (status, "SYS$CREATE_REGION_64"); return (status); } */
*/ */ */ */ */ */
printf ("\nSYS$CREATE_REGION_64 Created this Region: %016LX - %016LX\n", master_va_64, (uint64) master_va_64 + master_length_64 - 1); /* Create virtual address space within the region. */
for (i = 0; i < 3; ++i) { status = sys$expreg_64 ( ®ion_id_64, /* Region to Create VAs In page_size, /* Number of Bytes to Create PSL$C_USER, /* Access Mode 0, /* Creation Flags &return_va_64, /* Starting VA in Range Created &return_length_64); /* Number of Bytes Created if (!good_status (status)) { print_message (status, "SYS$EXPREG_64"); return status; } printf ("Filling %016LX - %16LX with %0ds.\n", return_va_64, (uint64) return_va_64 + return_length_64 - 1, i); memset (return_va_64, i, page_size); }
*/ */ */ */ */ */
/* Return the virtual addresses created within the region, as well as the region itself. */ printf ("\nReturning Master Region: %016LX - %016LX\n", master_va_64, (uint64) master_va_64 + master_length_64 - 1); status = sys$delete_region_64 ( ®ion_id_64, /* Region to Delete PSL$C_USER, /* Access Mode &return_va_64, /* VA Deleted &return_length_64); /* Length Deleted */ */ */ */
if (good_status (status)) printf ("SYS$DELETE_REGION_64 Deleted VAs Between: %016LX - %016LX\n", return_va_64, (uint64) return_va_64 + return_length_64 - 1); else { print_message (status, "SYS$DELTE_REGION_64"); return (status); } /* Return message buffer. free (msgdsc.dsc64$pq_pointer); } /* This routine obtains the system page size using SYS$GETSYI. The return value is recorded in the module-wide location, page_size. */ int get_page_size () { int status; IOSB iosb; ILE3 item_list [2]; /* Fill in SYI item list to retrieve the system page size. */ */
item_list[0].ile3$w_length item_list[0].ile3$w_code item_list[0].ile3$ps_bufaddr item_list[0].ile3$ps_retlen_addr item_list[1].ile3$w_length item_list[1].ile3$w_code /* Get the system page size. status = sys$getsyiw ( 0, 0, 0, &item_list, &iosb, 0, 0);
= = = = = =
sizeof (int); SYI$_PAGE_SIZE; &page_size; 0; 0; 0; */ /* /* /* /* /* /* /* EFN CSI address Node name Item list I/O status block AST address AST parameter */ */ */ */ */ */ */
if (!good_status (status)) { print_message (status, "SYS$GETJPIW"); return (status); } if (!good_status (iosb.iosb$w_status)) { print_message (iosb.iosb$w_status, "SYS$GETJPIW IOSB"); return (iosb.iosb$w_status); } return SS$_NORMAL; } /* This routine takes the message code passed to the routine and then uses SYS$GETMSG to obtain the associated message text. That message is then printed to stdio along with a user-supplied text string. */ #pragma inline (print_message) static void print_message (int code, char *string) { msgdsc.dsc64$q_length = BUFFER_SIZE; sys$getmsg ( code, /* (unsigned short *) &msgdsc.dsc64$q_length, /* &msgdsc, /* 15, /* 0); /* *(msgdsc.dsc64$pq_pointer+msgdsc.dsc64$q_length) = printf ("Call to %s returned: %s\n", string, msgdsc.dsc64$pq_pointer); }
Message Code Returned Length Message Descriptor Message Flags Optional Parameter \0;
*/ */ */ */ */
C
VLM Example Program
This example program demonstrates the memory management VLM features described in Chapter 16. /* This program creates and maps to a memory-resident global section using shared page tables. The program requires a reserved memory entry (named In_Memory_Database) in the Reserved Memory Registry. The entry in the registry is created using SYSMAN as follows: $ MCR SYSMAN SYSMAN> RESERVED_MEMORY ADD "In_Memory_Database"/ALLOCATE/PAGE_TABLES /ZERO/SIZE=64/GROUP=100 The above command creates an entry named In_Memory_Database that is 64M bytes in size and requests that the physical memory be allocated during system initialization. This enables the physical memory to be mapped with granularity hints by the SYS$CRMPSC_GDZRO_64 system service. It also requests that physical memory be allocated for page tables for the named entry, requests the allocated memory be zeroed, and requests that UIC group number 100 be associated with the entry. Once the entry has been created with SYSMAN, the system must be re-tuned with AUTOGEN. Doing so allows AUTOGEN to re-calculate values for SYSGEN parameters that are sensitive to changes in physical memory sizes. (Recall that the Reserved Memory Registry takes physical pages away from the system.) Once AUTOGEN has been run, the system must be rebooted. Use the following commands to compile and link this program: $ CC/POINTER_SIZE=32 shared_page_tables_example $ LINK shared_page_tables_example Since 64-bit virtual addresses are used by this program, a Version 5.2 HP C compiler or later is required to compile it. */ #define #include #include #include #include #include #include #include #include #include #include #include #include #define #define __NEW_STARLET <DESCRIP> <FAR_POINTERS> <GEN64DEF> <INTS> <PSLDEF> <SECDEF> <SSDEF> <STARLET> <STDIO> <STDLIB> <STRING> <VADEF> bad_status(status) (((status) & 1) != 1) ONE_MEGABYTE 0x100000
VLM Example Program C1
main () { int status; $DESCRIPTOR (section_name, "In_Memory_Database"); uint32 region_flags = VA$M_SHARED_PTS, section_flags = SEC$M_EXPREG; uint64 mapped_length, requested_size = 64*ONE_MEGABYTE, section_length = 64*ONE_MEGABYTE, region_length; GENERIC_64 region_id; VOID_PQ mapped_va, region_start_va; printf ("Shared Page Table Region Creation Attempt: Size = %0Ld\n", requested_size); /* Create a shared page table region. */ status = sys$create_region_64 ( requested_size, VA$C_REGION_UCREATE_UOWN, region_flags, ®ion_id, ®ion_start_va, ®ion_length); /* /* /* /* /* /* Size in bytes of region */ Region VA creation and owner mode */ Region Flags: shared page tables */ Region ID */ Starting VA for region */ Size of created region */ /* Shared PT region. */
if (bad_status (status)) { printf ("ERROR: Unable to create region of size %16Ld\n\n", requested_size); return; } printf ("Shared Page Table Region Created: VA = %016LX, Size = %0Ld\n\n", region_start_va, region_length); /* Create and map a memory-resident section with shared page tables into the shared page table region. */ printf ("Create and map to section status = sys$crmpsc_gdzro_64 ( §ion_name, 0, 0, section_length, ®ion_id, 0, PSL$C_USER, section_flags, &mapped_va, &mapped_length); %s\n", section_name.dsc$a_pointer); /* /* /* /* /* /* /* /* /* /* Section name */ Section Ident */ Section protection */ Length of Section */ RDE */ Section Offset; map entire section */ Access Mode */ Section Creation Flags */ Return VA */ Return Mapped Length */
if (bad_status (status)) printf ("ERROR: Unable to Create and Map Section %s, status = %08x\n\n", section_name.dsc$a_pointer, status); else { printf ("Section %s created, Section Length = %0Ld\n", section_name.dsc$a_pointer, section_length); printf (" Mapped VA = %016LX, Mapped Length = %0Ld\n\n", mapped_va, mapped_length); } /* Delete the shared page table. This will cause the mapping to the section and the section itself to be deleted. */ printf ("Delete the mapping to the memory-resident global section"); printf (" and the shared\n page table region.\n"); status = sys$delete_region_64 ( ®ion_id, PSL$C_USER, ®ion_start_va, ®ion_length); if (bad_status (status)) printf ("ERROR: Unable to delete shared page table region, status = %08x\n\n", status); else printf ("Region Deleted, Start VA = %016LX, Length = %016LX\n\n", region_start_va, region_length); printf ("\n"); } This example program displays the following output: Shared Page Table Region Creation Attempt: Size = 67108864 Shared Page Table Region Created: VA = FFFFFFFBFC000000, Size = 67108864 Create and map to section In_Memory_Database Section In_Memory_Database created, Section Length = 67108864 Mapped VA = FFFFFFFBFC000000, Mapped Length = 67108864 Delete the mapping to the memory-resident global section and the shared page table region. Region Deleted, Start VA = FFFFFFFBFC000000, Length = 0000000004000000
Index
A
Access modes effect on AST delivery, 811 with AST, 87 Ada, 110 Address space allocating by page, 125, 138 allocating in zones, 146 deallocating by page, 126, 138, 142 zones, 146 Afnity, types of, 435 Afnity mechanism, 432 Algorithms, for memory allocation, 147 Alignment, 151 natural, 152 on OpenVMS Alpha systems, 63 on OpenVMS I64 systems, 65, 66 on OpenVMS VAX systems, 63 OpenVMS Alpha systems, 153 OpenVMS VAX, 153 system services, 1511 with BLISS compiler, 156 with compilers, 154 with HP C compiler, 154 with HP Fortran compiler, 156 with Macro-32 compiler, 157 with OpenVMS Debugger, 1510 with PCA, 1511 with tools, 1510 with VEST translator, 159 Alignment attribute, 1411 Alignment fault utility for tracing, 1512 Alignment precedence with Macro-32 compiler, 159 Alpha architecture, 14 Alpha platforms, 13 APL (Application Programming Language), 110 Applications distributed, 15 graphical user interface, 119 OpenVMS, 13 portable, 15 Architecture Alpha, 14 CISC, 14 Architecture (contd) RISC, 14 VAX, 14 Area extension size, 149 Argument lists for AST service routine, 89 for condition handler, 930 Arguments, mechanism vector, 938 Arithmetic exceptions, on Alpha systems, 916 Arrays mechanism, 938 virtual address, 129, 1310 Assemblers, 110 AST routines, 81 ASTs (asynchronous system traps), 116, 221, 81 See also Synchronization access mode, 87 blocking, 713, 720 call frame, 83 declaring, 82 delivery, 86, 88 example, 810 execution, 81 in target process, 426 kernel thread delivery, 811 parameter, 89 process wait state, 813 queuing, 82 reentrant code, 83 service routine, 89 shared data access, 83 system service, 82 writing, 82 AST synchronization, shared data, 84 Asynchronous system traps See ASTs Atomicity, denition, 63 Atomic memory reference, 63
B
Balance set, swapping, 1213, 1312 BASIC HP BASIC for OpenVMS, 110 VAX BASIC, 110
Index1
32-bit descriptors, 112 64-bit descriptors, 112 32-bit item list formats, 115 64-bit item list formats, 116 32-bit item lists, 115 64-bit item lists, 116 BLISS-32, 110 BLISS-64, 110 BLISS compiler alignment, 156 consequences of noncompliant code, 611 Blocking ASTs description, 713 using, 720 Block size options, 1410 Boot CPU, 51 Booting, an SMP system, 51 Boundary tags, 148
C
C HP C for OpenVMS, 110 VAX C, 110 C++, 110 Caching, 720 Callable system routines, 114 Call-frame condition handlers, 927 Call frames ASTs, 83 exit handlers, 981 Calling ASTs, 87 Calling standard, 18, 1127 Call stacks, unwinding, 953 Capabilities mechanism, 432 Capability masks CPU, 434 process, 434 Capability types, 433 Catchall handlers, 928, 950 Chaining item lists, 114 Change-mode handlers, 914 Channels, 310 $CHFDEF2 macro, 930 $CHFDEF macro, 930 CISC, architecture, 14 Class scheduler, 436 Class scheduler database, 440 Class_schedule, SYSMAN command, 437 CLI (command language interpreter), 25 Client/server computing, 15 Clients, 15 Cluster-aware services SYS$CREPRC, 212 SYS$DELPRC, 474 SYS$FORCEX, 470 SYS$GETJPI, 45, 49
Cluster-aware services (contd) SYS$GETJPIW, 49 SYS$GETUPIW, 45 SYS$ICC_ACCEPT, 322 SYS$ICC_CLOSE_ASSOC, 322 SYS$ICC_CONNECT, 322 SYS$ICC_CONNECTW, 322 SYS$ICC_DISCONNECT, 322 SYS$ICC_DISCONNECTW, 322 SYS$ICC_OPEN_ASSOC, 322 SYS$ICC_RECEIVE, 322 SYS$ICC_RECEIVEW, 322 SYS$ICC_REJECT, 322 SYS$ICC_REPLY, 322 SYS$ICC_REPLYW, 322 SYS$ICC_TRANSCEIVE, 322 SYS$ICC_TRANSCEIVEW, 322 SYS$ICC_TRANSMITW, 322 SYS$ICC_TRNSMIT, 322 SYS$WAKE, 465 CMS, 114 Command Denition Utility (CDU), 113, 118 Command language interpreter, 25 See CLI Common areas, per-process, 36 Common blocks modifying, 36 Common event ag clusters, 628 permanent, 630 temporary, 630 Comparing 32-bit and 64-bit item lists, 114 Compatibility mode handlers, 914 Compilers, 110 alignment, 154 Condition codes chaining, 960 signaling, 936 SS$_EXQUOTA, 925 SS$_NOPRIV, 925 Condition handlers See also Signal argument vectors argument list, 930 arithmetic, 919 call frame, 927 catchall, 928, 950 condition code, 972 continuing execution of, 971 debugging, 977 default, 948 establishing, 95 example, 976 exiting, 973 last-chance, 950 last-chance exception vector, 928 mechanism argument vectors, 938 primary exception vector, 927 resignaling, 971 searching for, 927
Index2
Condition handlers (contd) secondary exception vectors, 927 signal argument array, 935 software supplied, 948 specifying, 94 traceback, 928, 949 types, 948 types of action, 952 unwinding, 971 use of, 930 user-supplied, 948 writing, 970 Condition handling, 93 See also Condition handlers See also Condition Handling Facility See also Condition values See also Exception conditions See also Exceptions See also Message utility (MESSAGE) alignment fault reporting, 918 arithmetic exceptions, 916 continuing, 952 displaying messages, 956 GOTO unwind, 952 hardware exception conditions, 914 logging error messages, 96 logging error messages to a le, 962 mechanism argument vectors, 938, 940 mechanism array format, 940 resignaling, 952, 974 return status, 924 run-time library support routines, 920 signal argument vectors, 936 signaling a condition, 952 stack traceback, 96 stack unwind, 96, 952 unwinding, 974 user-dened messages, 96 VAX hardware exceptions, 915 Condition Handling Facility (CHF), 948 denition, 91 function, 94 Conditions for exception, 97 Condition values, 921 to 923, 934 denition, 970 severity, 922 testing with $VMS_STATUS_SUCCES, 924 CPU characteristics SMP system, 51 CPUs (central processing units) afnity scheduling, 432 capabilities scheduling, 432 class scheduling, 436 CPU-specic pages, 121
Create Mailbox and Assign Channel system service See also SYS$CREMBX system service C system( ) call, 27 Current procedure, 955
D
Data alignment, 151 exception reporting, 918 Data Cells, 224 Data management, 119 Deadlock detection, 78 Debugger, quadwords, 1125 Debuggers, 111 Debugging BUGCHECKFATAL, 113 condition handler, 977 CPUSPINWAIT, 113 detached process, 215 exit handler, 977 kept debugger, 215 MULTIPROCESSING, 113 POOLCHECK, 113 subprocess, 215 SYSTEM_CHECK, 113 DECdtm services support for transaction processing, 117 Declaring ASTs, 82 DECset, 119 DECTPU, 19 DECW$TERM_PORT example program, 216 Default zone, 1412 Delta/XDelta Debugger (DELTA/XDELTA), 111 Detached processes, 21 creating, 213 debugging, 215 Developing application programs, 16 Directives See also Message utility (MESSAGE) .END, 966 .FACILITY, 965 .SEVERITY, 966 .TITLE, 967 Disk les, opening, 1216, 1314 Dispatcher, exception, 927 Distributed computing, 15 Distributed environments, 15 Distributed processing, 14 Dynamic memory allocation, 124
E
Editors, 19 EDT, 19 EVE, 19 vi (POSIX), 19
Index3
EFN 128 event ag EFN$C_ENF, 625, 626 .END directive, 966 ENQLM process limit, 79 Enqueue process limit quota, 79 Environments client/server, 15 common code, 18 common language, 18 computing, 14 distributed, 15 open system, 14 production systems, 14 Error handling See Condition handling Errors, signaling, 96 EV6 Alpha processor, 611 EVE (Extensible Versatile Editor), 19 Event ag clusters deleting, 630 disassociating, 630 specifying name for, 629 Event ags, 116, 221, 623 See also Synchronization clearing, 634 cluster, 624 common, 624 for interprocess communication, 38 local, 32, 624 numbers, 624 setting, 634 specifying, 625 wait, 632 Event ag service, example using, 636 Event ag zero (0), 626 Exception conditions, 92, 97 returning condition value, 97 signaling, 96, 97, 919, 931, 957 Exceptions denition, 92 dispatcher, 927 oating-point underow, 919 handling by run-time library, 918 type, 97 EXE$READ_PROCESS routine, 443 to 445 EXE$WRITE_PROCESS routine, 446 to 448 Execution context, 22 Executive images linking, 452 loading, 452 to 456 unloading, 457 to 458 writing, 449 to 451 Executive mode ASTs, 813 Executive stack, 223
Exit handlers, 470, 981 debugging, 985 establishing, 982 writing, 984 Exits See also Exit handlers forced, 470 image, 468, 981 Explicit afnity, 436 Extended address space, 133, 134 physical address space, 133 virtual address space, 134 Extended Math Library for OpenVMS, 116 Extents, dening section, 1217, 1315
F
.FACILITY directive, 965 FAO argument, signaling, 969 FAO parameter, specifying, 969 Flags See Event ags Floating-point overow, 919 Floating-Point Registers and Execution Data Blocks See FREDs Floating-point underow, 919 Forced exit, 470 Fortran HP Fortran 77 for OpenVMS VAX Systems, 110 HP Fortran for OpenVMS Alpha Systems, 111 FREDs (Floating-Point Registers and Execution Data Blocks), 223
G
Global sections, 1218, 1316 characteristics, 1218, 1316 denition, 1214, 1313 for interprocess communication, 38 mapping, 1222, 1319 multiprocessing, 622 name, 1218, 1317 paging le, 1223, 1320 writable, 622 Global symbols signaling with, 968 GOTO unwind operations, 956 Granularity of resources, 73 on OpenVMS Alpha systems, 64 on OpenVMS I64 systems, 65 on OpenVMS VAX systems, 64 Graphical interfaces, creating, 119
Index4
H
Handlers, change and compatibility modes, 914 Hardware process control blocks See HWPCBs Hibernation, 463 alternate method, 466 and AST, 813 compared with suspension, 464 High-performance sort, 118 HP C++ compiler, consequences of noncompliant code, 611 HP C compiler alignment, 154 consequences of noncompliant code, 611 HP COBOL for OpenVMS, 110 HP DECwindows Motif for OpenVMS software, programming libraries and tools, 118 HP Fortran compiler alignment, 156 HP POSIX Threads Library, 219 HWPCBs (hardware process control blocks), 221, 223
Interprocess control, 31 Interrupt priority level, 610 See IPL Interrupt requests, SMP systems, 52 Intracluster communications, 321 clients, 327 concepts, 322 design considerations, 323 programming considerations, 325 servers, 325 Intra-Cluster communications, 31 Intraprocess communication, 31 common area, 36 global symbols, 35 IOSBs (I/O status blocks), 85 IPL (interrupt priority level), 610 Item lists chaining, 114 segments, 115
K
Kept debugger, 215 Kernel mode ASTs, 813 Kernel stacks, 223 Kernel thread blocks, 222 See KTBs Kernel threads advantages, 218 AST delivery, 811 denition, 218 execution, 463 hibernating, 463 model, 220 priority, 432 region, 223 scheduling, 432 suspending, 463 KTBs (kernel thread blocks), 222
I
I/O status blocks See IOSBs I/O system services, 117 ICC system services, 321 Image rundown, 981 Images exit, 468 exiting, 981 for subprocess, 212 rundown activity, 469 Image sections, 1228, 1323 Implicit afnity, 435 IM semaphore, 620 INITIALIZATION_ROUTINE macro, 451 Inner mode (IM) semaphore, 620 Inner mode access, 220 Inner mode ASTs, 813 Inner mode synchronization, 620 Input address arrays, 127, 128, 139 Instruction memory barriers, 618 Instructions, queue, 623 Interlocked instructions, 67, 617, 622 Interlocked memory instructions, using, 611 Interpreters, 110 Interprocess communication, 31, 37 event ags, 38 global sections, 38 lock management services, 38 logical names, 38 mailboxes, 38 using, 39
L
Languages ANSI/ISO, 15 compilers, 110 Large page-le sections, 1234 Last-chance exception vectors, 928 LDR$LOAD_IMAGE routine, 453 to 456 LDR$UNLOAD_IMAGE routine, 457 to 458 LIB$ASN_WTH_MBX routine, 310 LIB$CREATE_USER_VM_ZONE routine, 1412, 1416 LIB$CREATE_VM_ZONE routine, 147, 1416 LIB$DECODE_FAULT routine, 980 LIB$DEC_OVER routine, 919
Index5
LIB$DELETE_VM_ZONE routine, 147, 1413 LIB$ESTABLISH routine, 94, 948 LIB$FIND_VM_ZONE routine, 147 LIB$FIXUP_FLT routine, 980 LIB$FLT_UNDER routine, 919 LIB$FREE_VM routine, 124, 136 LIB$FREE_VM_64 routine, 124 LIB$FREE_VM_PAGE routine, 123, 136 LIB$FREE_VM_PAGE_64 routine, 123 LIB$GETJPI system routine, 49 LIB$GET_COMMON routine, 36 LIB$GET_VM routine, 124, 136 LIB$GET_VM_64 routine, 124 LIB$GET_VM_PAGE routine, 123, 136 LIB$GET_VM_PAGE_64 routine, 123 LIB$INT_OVER routine, 919 LIB$MATCH_COND routine, 937, 972, 980 LIB$PUT_COMMON routine, 36 LIB$RESET_VM_ZONE routine, 146, 1413 LIB$REVERT routine, 94, 95 LIB$SHOW_VM_ZONE routine, 147 LIB$SIGNAL routine, 93, 95, 919, 931, 937, 938, 939, 957, 964, 972 generating signals, 933 invoking, 933 LIB$SIG_TO_RET routine, 978 establishing, 979 LIB$SIG_TO_STOP routine, 979 LIB$SIM_TRAP routine, 971, 978 LIB$STOP routine, 93, 95, 97, 931, 937, 939, 952, 957, 964, 971, 972 generating signals, 933 LIB$VERIFY_VM_ZONE routine, 147 Librarian utility (LIBRARIAN), 111 Libraries message object module, 967 Linkage sections, 1213 Linker utility, 111 Load-locked instructions, 610, 622 Local buffer caching, with lock management service, 720 Local symbols signaling with, 968 Lock limits, 78 Lock management system services for interprocess communication, 38 Lock manager, 71 See also Synchronization and Distributed lock manager ENQLM quota, 79 LOCKIDTBL size, 79 resource hash table quota, 79 sub-resource and sub-lock quota, 79 Lock quotas, 78 Lock requests queuing, 76 queuing a lock request, 79 synchronizing, 711
Locks choice of mode, 75 concept of, 72 conversion, 77, 713, 714 deadlock detection, 78 dequeuing, 718 level, 75 mode, 75 Lock status blocks, 712 Lock value blocks description, 716 using, 720 Logical names, for interprocess communication, 38 LOGINOUT creating SYS$LOGIN logical name, 29 creating SYS$LOGIN_DEVICE logical name, 29 creating SYS$SCRATCH logical name, 29 LOGINOUT sample program, 29 LSE/SCA, 19
M
MACRO Macro-32 compiler, 111 MACRO-64 assembler, 111 Macro32 compiler alignment, 157 MACRO32 compiler alignment precedence, 159 consequences of noncompliant code, 611 MACRO64 assembler, consequences of noncompliant code, 611 MACRO language VAX MACRO, 111 Mailboxes, 39, 310 creating, 39 for interprocess communication, 38 input/output asynchronous, 311 immediate, 311 synchronous, 311 using SYS$QIO, 311 using SYS$QIOW, 311 permanent, 39 reading data from, 311 temporary, 39 termination, 476 writing data to, 311 Management data, 119 system, 14 Mathematical functions, 115 Mechanism argument vectors, 931, 938, 970 on Alpha systems, 940 on VAX systems, 938
Index6
Mechanism arrays, format, 940 Memory allocating algorithms, 147 allocating and freeing blocks, 141 allocating and freeing pages, 141 barriers, 618 instructions, 618 fences, 619 locking page into, 1214, 1313 reads and writes on VAX systems, 65 reads and writes on Alpha systems, 65 Memory fragmentation, 142 Memory management system services, 122, 135 Memory-resident global sections, 1228 Messages chaining, 960 displaying, 957 logging, 963 Message text, specifying variables in, 967 Message utility (MESSAGE), 113, 118, 963 to 970 accessing message object module, 967 associating messages with exception conditions, 964 compiling message le, 967 creating a message object library, 967 .END directive, 966 .FACILITY directive, 965 facility name, 965 facility number, 966 FAO parameters, 969 /FAO_COUNT qualier, 967 logging messages, 963 message object module, 967 message text, 966 message text variables, 967 modifying a message source le, 968 .SEVERITY directive, 966 source module, 965 .TITLE directive, 967 Middleware services, 17 client/server software, 16 MMS, 114 Multiple execution contexts, 218 Multiprocess applications synchronizing, 621 Multiprocessor environment, 622 See also Synchronization scheduling, 621 Multistreamed work load, 622
N
Naming spawned subprocess, 23 National Character Set (NCS) utility, 114 Natural alignment, 152 performance, 152 Network management, 14
O
Object les, 110 Object libraries including message object module, 967 Object-oriented programming, 110 Open standards, 12 Open systems, 14 environment, 14 OpenVMS Alpha operating systems migrating to, 13 OpenVMS Alpha System-Code Debugger, 112 OpenVMS Cluster systems, ICC programming, 321 OpenVMS Debugger (debugger), 111 OpenVMS Debugger utility, 153 alignment, 1510 OpenVMS I64 operating systems migrating to, 13 OpenVMS RMS See RMS OpenVMS systems compatibility, 13 compliance with open standards, 12 congurations, 13 debugger, 111 description, 12 open systems capability, 14 software, 13 system services, 116 OpenVMS utility routines, 117 Outer mode ASTs, 812 Overview of the OpenVMS Operating System, 12
P
P0 space, 223 denition, 102 P1 space, 223, 224 denition, 102 Page-le sections larger limits (Alpha and I64), 1234 Page frame sections, 1228, 1324 Pagelets, 121 Pages, 133 copy-on-reference, 1218, 1316 demand-zero, 1218, 1316 locking into memory, 1214, 1313 owner, 1210, 1310
Index7
Pages (contd) ownership and protection, 1210, 1310 Page table entries See PTEs Paging le sections, 1224, 1320 global, 1223, 1320 PALcode (privileged architecture library) code, 619, 153 Parent lock, 715 Partial sections, 1229 Pascal, 111 Patch utility (PATCH), 113 PCA (performance and coverage analyzer), 1511 PCA (Performance and Coverage Analyzer) alignment, 153 PCBs (process control blocks), 221 Per Kernel Thread Stacks, 223 Per-process common areas, 36 PFNs (page frame numbers), 135 PHDs (process headers), 221 PID numbers, 43, 46 denition, 46, 49 referencing remote processes, 49 Platforms Alpha, 13 VAX, 13 Pointers, 64-bit support, 1127, 1128 Portability, applications, 15 POSIX Threads Library, 114 Primary exception vector, 927 Private sections, denition, 1214, 1313 Privileged architecture library code See PALcode Privileges SS$_NOPRIV, 925 Process contexts accessing, 442 to 458 reading, 443 to 445 using with $GETJPI system service, 49 writing, 446 to 448 Process controls, 41 Processes See also SYS$GETJPI system service See also SYS$PROCESS_SCAN system service communicating between, 37 communicating within, 31 using logical names, 32 using symbols, 35 creating restrictions, 43 deleting, 471, 474 detached, 21, 213 disabling swap mode, 1214, 1312 disallowing swapping, 1214, 1312 execution, 463 hibernating, 463 identication, 43
Processes (contd) lock information, 430 modes of execution, 22 modifying name, 441 obtaining information about, 49 example, 49 processes on specic nodes, 421, 422 synchronously, 423 using LIB$GETJPI routine, 45 using PIDs, 45, 49 using process name, 46, 49 using SYS$GETJPI system service, 45 using SYS$GETJPIW system service, 45 one process, 49 priority modifying, 432 privileges setting, 431 scheduling, 432 spawned, 21 subprocess, 21 suspending, 463, 467 swapping, 1213, 1312 SYS$PROCESS_SCAN system service item lists using to specify selection criteria about processes, 416, 420, 421 using with remote procedures, 424 item-specic ags to control selection information, 416 search, 414 termination mailboxes, 476 wildcard search, 412 Process Header (PHD), 221 Process identication numbers See PID numbers Processing, distributed, 14 Process names length of for remote processes, 46 obtain information about remote processes example, 412 specifying for local processes, 46 specifying for remote processes, 46 using to obtain information about remote processes, 46, 49, 421 Process-private space denition, 102 Process searches obtaining information about, 49 searching on all nodes, 422 searching on specic nodes, 421 using item lists with remote procedures, 424 using item-specic ags to control selection information, 416 using SYS$PROCESS_SCAN system service item list, 417
Index8
Process searches (contd) using SYS$PROCESS_SCAN system service item list to specify processes example, 420 using SYS$PROCESS_SCAN system service item list to specify selection criteria about processes, 421 using wildcard on local system, 412 Process structure, 220 Production systems, OpenVMS capabilities, 14 Program decomposition, 622 Program execution See also Synchronization specifying a time, 459, 460 timed intervals, 461 Programming modular techniques, 18 software development tools, 18 to standards, 18 Programming environment, 16 Program regions, 124, 125, 138 Protection, page, 1210, 1310 PTEs (page table entries) extended addresses, 135
RMS, 17, 119 See also RAB64 les and records, 119 interface enhancements, 1112 opening le for mapping, 1216, 1314 routines, 120 utilities, 120 RMS les, 119 Routines callable system, 114 high-performance sort, 118 RTL, 115 RTL jacket handler, 978 RTLs (run-time libraries) condition handling, 91 routines, 115 Run-time libraries See RTLs Run-time library routines on Alpha systems, 920 return status, 924
S
S0 space, denition, 102 Schedulers callback, 219 OpenVMS, 219 POSIX Threads Library, 219 Scheduling, 221 Secondary exception vectors, 927 Sections, 1214, 1313 characteristic, 1217, 1315 creating, 1216, 1314 dening extent, 1217, 1315 deleting, 1227, 1323 global paging le, 1223, 1320 image, 1228, 1323 mapping, 1219, 1318 page frame, 1228, 1324 paging, 1224, 1320, 1321 releasing, 1227, 1323 sharing data, 1226, 1322 unmapping, 1227, 1323 writing back, 1227, 1323 Segments, item lists, 115 Servers, 15 Service routines AST, 89 SET BREAK debugger command, /HANDLER qualier, 977 .SEVERITY directive, 966 Shared data access, 83 AST synchronization, 84
Q
Queues lock management, 76 Queuing ASTs, 82 Quotas SS$_EXQUOTA condition value, 925
R
RAB64 (64-bit record access blocks) data structure, 1113 macros, 1115 RAB64$PQ_x elds, 1113, 1114 RAB64$Q_x elds, 1113, 1114 Read and write operations, ordering, 65 on I64 systems, 66 Read-modify-write operations, atomic for I64 systems, 68 for VAX and Alpha systems, 66 Records, RMS, 119 Reentrant code, ASTs, 83 Reserved Memory Registry, 162 Resource granularity, in lock, 73 Resources lock management concept, 72 name, 74 Return address arrays, 127, 128, 139 Return status, 924 from signal, 979 RISC architecture, 14
Index9
Signal argument vectors, 931, 935, 970 Signaling, 936 changing to return status, 979 SMP (symmetric multiprocessing), 51 goals, 52 interrupt requests, 52 tightly coupled, 51 Software development life cycle, 18 Software development tools, 17 Software programs, developing, 16 Sort/Merge utility, high-performance routines, 118 Spawned subprocess naming, 23 Special modes for debugging, 113 SRM_CHECK tool location on kit, 612 using to analyze code, 612 SS$_ALIGN exception, 915 signal array format, 918 SS$_HPARITH exception, 915 signal array format, 916 Standards, open, 12 Store-conditional instructions, 610 Sublock, 715 Subprocesses, 21 creating with LIB$SPAWN, 24 with SYS$CREPRC, 27 debugging, 215 disk and directory default, 213 image, 212 input, output, and error device, 28 priority setting, 432 Supervisor mode ASTs, 812 Supervisor stack, 223 Suspension, 463, 467 compared with hibernation, 464 Swapping by suspension, 467 Symmetric Multiprocessing See also SMP Synchronization asynchronous system traps, 81 denition of, 61 hardware-level, 69 inner mode, 620 passing control to another image, 467 software-level, 619 using detached processes, 459 using events ags, 623 using process priority, 621 using spin locks, 622 using subprocesses, 459 SYS$ADJWSL system service, 1211, 1311
SYS$ASCEFC system service, 628 SYS$CLREF system service, 634 SYS$CPU_CAPABILITIES system service, 434 SYS$CREMBX system service, 28, 39, 478 SYS$CREPRC system service, example, 212 SYS$CRETVA system service, 127, 139 SYS$DACEFC system service, 630 SYS$DCLAST system service, example, 810 SYS$DCLCMH system service, 93 SYS$DCLEXH system service, 982 SYS$DELPRC system service, 474 SYS$DEQ system service, example, 719 SYS$DGBLSC system service, 1316 SYS$DLCEFC system service, 630 SYS$ENQ system service, example, 710 SYS$ERROR logical name, 27, 28, 29, 210, 469, 949, 957, 962 SYS$EXIT system service, 469 SYS$EXPREG system service, 125, 138 example, 126, 138 SYS$FAO system service, 949, 957, 962 SYS$FORCEX system service example, 470 SYS$GETJPI system service, 45, 49 See also SYS$PROCESS_SCAN system service AST in target process, 426 buffer, 424, 425 control ags, 426 item list specifying criteria to select processes example, 420 item-specic ags, 416 obtaining information about all processes on the local system, 49 to 414 obtaining information about one process, 49 obtaining information with wildcard search example, 413 packing information in buffers, 424, 425 searching for processes on all nodes, 422 searching for processes on specic nodes, 421, 422 searching for selected processes, 414 specifying buffer size, 424, 425 specifying criteria to select processes example, 421 swapping processes, 426 synchronizing calls, 421, 422, 423 using item lists, 416, 424 with remote procedures, 424 using multiple $PROCESS_SCAN service contexts, 423 using SYS$PROCESS_SCAN system service item list to specify selection criteria about processes, 416, 420, 421 item-specic ags to control selection information, 416 search, 414
Index10
SYS$GETJPI system service (contd) using SYS$PROCESS_SCAN system service item list to specify selection criteria about processes, 417 using wildcards, 49 to 414 example, 413 using wildcards as pidadr, 49 SYS$GETJPIW system service, 45, 49 SYS$GETLKI system service, 430 SYS$GETMSG system service, 957 SYS$GET_ALIGN_FAULT_DATA system service, 1511 SYS$GET_SYS_ALIGN_FAULT_DATA system service, 1512 SYS$GOTO_UNWIND system service, 952, 956 SYS$HIBER system service, 465 example, 466 SYS$ICC_ACCEPT system service, 322, 119 SYS$ICC_CLOSE_ASSOC system service, 322 SYS$ICC_CONNECT system service, 322, 119 SYS$ICC_CONNECTW system service, 322, 119 SYS$ICC_DISCONNECT system service, 322, 119 SYS$ICC_DISCONNECTW system service, 322, 119 SYS$ICC_OPEN_ASSOC system service, 322, 119 SYS$ICC_OPEN_ASSOCW system service, 119 SYS$ICC_RECEIVE system service, 322, 119 SYS$ICC_RECEIVEW system service, 322, 119 SYS$ICC_REJECT system service, 322, 119 SYS$iCC_REPLY system service, 322 SYS$ICC_REPLY system service, 119 SYS$ICC_REPLYW system service, 322, 119 SYS$ICC_TRANSCEIVE system service, 322, 119 SYS$ICC_TRANSCEIVEW system service, 322, 119 SYS$ICC_TRANSMIT system service, 322, 119 SYS$ICC_TRANSMITW system service, 322, 119 SYS$INIT_SYS_ALIGN_FAULT_REPORT system service, 1512 SYS$INPUT logical name, 24, 27, 28, 29, 469, 85 example, 25, 28, 210 SYS$LCKPAG system service, 1214, 1312 SYS$LCKPAG_64 system service, 1214 SYS$LKWSET system service, 1212, 1312 SYS$LKWSET_64 system service, 1212 SYS$LOGIN logical name, 29 SYS$LOGIN_DEVICE logical name, 29 SYS$OUTPUT logical name, 24, 27, 28, 29, 469, 85, 949, 957, 962 example, 25, 210
SYS$PERM_DIS_ALIGN_FAULT_REPORT system service, 1512 SYS$PERM_REPORT_ALIGN_FAULT system service, 1512 SYS$PROCESS_AFFINITY system service, 436 SYS$PROCESS_CAPABILITIES system service, 434 SYS$PROCESS_SCAN system service, 45, 49 See also SYS$GETJPI system service obtaining information about processes on nodes, 422 to 423 obtaining information about processes on specic nodes, 421, 422 searching nodes, 422 searching on specic nodes, 421 setting up multiple contexts, 423 using item lists, 416 to 424 with remote procedures, 424 using item lists to specify selection criteria about processes, 416, 417, 421 example, 420 using item-specic ags to control selection information, 416 SYS$PURGWS system service, 1211, 1312 SYS$PURG_WS system service, 1211 SYS$PUTMSG system service, 96, 949, 957, 962 SYS$SCRATCH logical name, 29 SYS$SETEF system service, 634 SYS$SETEXV system service, 927 example, 94 SYS$SETIMR system service example with ASTs, 87 SYS$SETPRN system service, 441 SYS$SETPRT system service, 1210 SYS$SETPRV system service, 431 SYS$SETSWM system service, 1214, 1312 example, 1214, 1312 SYS$SET_IMPLICIT_AFFINITY system service, 435 SYS$SET_RESOURCE_DOMAIN system service, 74 SYS$START_ALIGN_FAULT_REPORT system service, 1511 SYS$STOP_ALIGN_FAULT_REPORT system service, 1511 SYS$STOP_SYS_ALIGN_FAULT_REPORT system service, 1512 SYS$SYNCH system service, 632 SYS$ULKPAG system service, 1214, 1312 SYS$ULKPAG_64 system service, 1214 SYS$ULWSET system service, 1212, 1312 SYS$UNWIND system service, 952, 954, 956, 971, 972, 974, 979 example, 955
Index11
SYS$WAITFR system service, 632 SYS$WAKE system service, 465 example, 466 SYS$WFLAND system service, 632 SYS$WFLOR system service, 632 SYSMAN command, class_schedule, 437 System Dump Analyzer (SDA) utility, 114 System management, 14 System routines callable, 17 system services asynchronous, 638 synchronous, 638 Systems exception dispatcher, 927 System services C function prototypes, 1112 MACRO-32, 1112 obtaining information about processes, 45, 49 OpenVMS, 116 return status, 924 System space, denition, 102 System timer canceling, 463 setting, 462
V
VAX, architecture, 14 VAX DIBOL, 110 VAX Environment Software Translator See VEST VAX platforms, 13 VEST (VAX Environment Software Translator) alignment, 159 vi editor, 19 VIOC not supported in I64, 166 Virtual address space, 126, 131, 138 increasing and decreasing, 125, 138 increasing and decreasing with 64-bit, 124 mapping section of, 1221, 1318 specifying array, 129, 1310 Virtual page size, 131 $VMS_STATUS_SUCCES testing condition values with, 924
W
WAIT form services, 632 Web-enabling tools, 17 Wildcard searches obtaining information about processes example, 413 using SYS$GETJPI system service, 412 Working sets adjusting size, 1211, 1311 paging, 1211, 1311 Write-back sections, 1227, 1323 Writing a condition handler example, 972
T
Termination mailboxes, 476 Text processors, 19 THREADCP not supported on I64, 225 Thread manager, 219 Threads, 955 POSIX Threads Library services, 114 .TITLE directive, 967 Tools, alignment, 1510 Traceback handlers, 928 Transaction processing, distributed environments, 117
Z
Zones, 146 to 1414 allocation algorithm, 1414 attributes, 148 creating, 147 default, 1412 deleting, 147 identier, 1412 resetting, 1413 user-created, 146
U
Unalignment, 151 Uniprocessor operations, 66 Unwind condition handlers, 974 Upcalls, 219 User capabilities, 434 User-dened condition values signaling, 968 User interfaces programming tools, 118 User mode ASTs, 812
Index12