HP 3000 Manuals

THE SEGMENTER [ MPE Segmenter Reference Manual ] MPE/iX 5.0 Documentation


MPE Segmenter Reference Manual

THE SEGMENTER 

The Segmenter is a subsystem of the MPE operating system.  It performs
all intermediate functions between source code compilation and program
execution.  One of its primary responsibilities is to gather and link
into pieces, or segments, most of the resources needed to form an
executable program file.  The Segmenter gives programmers considerable
control over the arrangement of code within segments, which in turn
affects the efficiency of individual programs and the economical use of
system resources in general.

The Segmenter In Context:  The Program Development Process 

To get a clear idea of what the Segmenter is and how it works, it helps
to have in mind the process of program creation.  Figure 1-1 provides an
overview of the entire process.

An analogy will help to summarize the process and to highlight some
particularly important points.

Think of the various elements and events of the program development
process, taken together, as forming a multi-floor condominium, with the
elements corresponding as follows:

 *  Relocatable Binary Modules (RBMs):  rooms.

 *  Entry points:  doors.

 *  Segments:  floors (groups of rooms).

 *  Procedure libraries:  files of pre-designed common areas, such as
    hallways, bathrooms, kitchens.

[]
Figure 1-1. Program Development Overview * User Subprogram Library (USL): preliminary plans. * Program file: final plans. The program development process is analogous to the architectural process of designing the condominium. The architect takes her ideas and translates them into a preliminary plan. This floorplan may contain one or more rooms per floor, and each room may have one or more doors. Since these are preliminary plans, the architect can rearrange rooms and even move rooms to different floors. She can also go to her portfolios for copies of already-created rooms or groups of rooms to incorporate into one of her floors. When the architect is finally satisfied with the design, she prepares the final plan, inking in the lines and in effect locking the doors, rooms, and floors into a permanent arrangement. Since a copy of the preliminary plans still exists, the architect can get them out and go through the process as often as she wishes to create other, slightly different final plans to be followed during actual construction (program loading and execution). In the following explanation, the boxed portions of the accompanying diagrams indicate which parts of the process are active for that step. COMPILATION. The first step, illustrated in Figure 1-2, is to translate the source program units (sometimes called procedures, functions, or subroutines) into blocks of machine instructions called "relocatable binary modules", or RBMs. This is done by the various MPE language compilers, which automatically store the RBMs in a specially-formatted file called the user subprogram library, or USL.
[]
Figure 1-2. Compilation Relocatable Binary Modules. An RBM is the smallest unit of object code generated by a compiler. RBMs for the various subprograms contain program instructions and external references (references to procedures in other RBMs or in library files). In addition to these subprogram RBMs, the compiler constructs a main, or outer block, RBM, which contains instructions for the main program as well as program constants. The main RBM may also contain fixed addresses for locating items in the data stack; this information will be used later in the program development process. The different compilers have their own specific conventions for constructing program units into RBMs. See Appendices A through F for a discussion of these. Some programming languages (FORTRAN and SPL) allow you to specify parameters within RBMs as "entry points". These are points within the code unit which you can selectively instruct the system to use as starting locations for a particular action. When the compiler places the RBMs in the USL file, it "associates" them with particular code segments. Actual code segments do not yet exist, but you can think of the RBMs as "belonging" to their associated segments. The RBMs are relocatable, which means that using the Segmenter you can move RBMs around and associate them with different code segments. You can also copy RBMs from other USLs, add new RBMs to a USL, or purge RBMs. An analogy will help clarify some of the important characteristics of RBMs. Suppose you are designing posters for a presentation. Each poster will contain one or more pictures or diagrams. You lay the pictures out on the poster board but leave them unglued, so you can rearrange them on the boards or move them from board to board as often as you wish. Once they are glued down, however, their positions are fixed, and they can no longer be moved around. Think of RBMs as the diagrams and the code segment names as the poster board. While in the USL, the RBMs can be rearranged and associated with one code segment name (board) or another. At preparation time, the Segmenter looks at the current arrangement and applies the "glue" to form the final poster, or code segment, which is output to the program file. However, unlike the pictures which were glued to the poster board, the pieces of code used to form the code segments still exist in the USL, waiting to be further manipulated or changed in another cycle of segment design. The picture, or code, glued into the code segment was just a copy of the code modules found in the USL. User Subprogram Libraries (USLs). Users often think of code as residing only in program files, but in Hewlett-Packard's design for code-handling, code can also be stored, maintained, and managed in three different kinds of specially formatted files called "libraries." The user subprogram library, or USL, is the first of the procedure libraries used in the program development process. It is the file used for compiler output and forms the basis for the other two libraries ("Relocatable Libraries," or RLs; and "Segmented Libraries," or SLs). The USL is the file you can manipulate to achieve effective segmentation. In addition to an RBM for the main program and each subprogram successfully compiled, the compiler generates and places the following into the USL: * A directory to keep track of the RBMs stored in the USL. * Data stack information that will be required at a later stage. A major advantage of this library is that once code is compiled into the USL, the programmer can manipulate it and even copy it into another USL without having to perform time-consuming recompilation. Users can also compile several versions of a procedure into a USL, using the Segmenter's indexing capability to select at execution time the version they wish to use. Although USLs are usually created by the compiler, the programmer can create them, using commands within the Segmenter subsystem. Segmenter commands also allow users to list the contents of the USL they are currently working with. PREPARATION. The second step in the program development process is to "prepare" the USL. This step, which is illustrated in Figure 1-3, is performed by the MPE Segmenter subsystem, and results in a "program file" containing: * Loadable code segments. * A skeleton data segment, or "stack". The Segmenter may bring in procedures from a "relocatable library" (RL) to resolve external references made within the RBMs, such as a call to a procedure which finds the cosine of a number generated within the program.
[]
Figure 1-3. Preparation Code Segments. During preparation, the Segmenter uses the associations found in the USL to bind the RBMs into one or more code segments. It is important to realize that no segments actually existed in the USL. By associating RBMs with segments, the compiler was, in effect, looking forward to segments which would eventually be created. That creation is the sole responsibility of the Segmenter. As it establishes the necessary linkages between RBMs, the Segmenter creates an "external reference list", which contains information about those RBMs not present in the program file, but which are referred to within it. The Segmenter also generates a Segment Transfer Table (STT) for each code segment it creates. This table contains linkage information, used during execution when control has to transfer from one RBM within the segment to another. If control has to transfer to an RBM in another segment, the STT will keep track of that linkage as well. Code segments may contain only non-modifiable material; that is, material not subject to change during execution. Therefore, code segments may contain program instructions, but they may not contain data. The only exception to this rule is that program constants (which are non-modifiable data) may be contained in code segments. Although you cannot change the code segments themselves, you can manipulate the original copy of the code, which resides in the USL, and re-prepare it into a variation of your first code segment. In summary, each code segment contains the following: * The instructions of the program itself. * Program constants. * Addresses for locating items in the data stack. * An external reference list. * An STT for keeping track of intra-segment and inter-segment transfers. The Skeleton Data Segment, or Stack. The Segmenter is also responsible for creating a skeleton data segment (or stack), based on references in the code, and placing it in the program file. Each program file will have only one data segment. To construct the data segment, the Segmenter uses the initial stack information compiled into the USL. That information defines and initializes storage space for data that is considered global (available to all program units directly). This area, usually referred to as the Primary DB, contains information about and pointers into the other parts of the data segment. A secondary storage area accessible to all program units indirectly through local or global pointers is defined as well, and parts of it may also be initialized. The secondary storage area is called the Secondary DB. Relocatable Libraries. The relocatable library, or RL, is the second of the three libraries which may be accessed during the program development process. RLs contain procedures, in RBM form, needed for program execution. They can be created by the programmer, using Segmenter commands, from the material in a USL. Programmers can also use Segmenter commands to add RBMs from a USL to an already-built RL, to purge RBMs within RLs, and to list the contents of the currently-managed RL. When a program makes a call to some or all of the RBMs kept in an RL file, the Segmenter copies the RBMs at preparation time and binds them to the calling program as a single segment, known as the "RL segment." Different programs will likely ask for different RBMs or combinations of RBMs and will need to use them in unique ways, so the RL segment must be unique to each program. No segmentation information accompanies the code in RL RBMs, as it does those in a USL. Since all required RBMs are added to the calling program file as a single segment, individual segment associations for each RBM are unnecessary. The Segmenter binds the single RL segment to the code segment it is constructing from USL material. Since a copy of requested RL material is prepared into the program file, your program file will have to be re-prepared should the RL code change. In fact, all program files prepared with that code will have to be re-prepared. RLs are used to keep procedures that are likely to be used with some frequency by more than one programmer. Keeping such common procedures in an RL means that programmers can access them more efficiently: they can use a call to the procedure and receive a copy of it for their program file. They do not have to rewrite it each time it is needed in a new program. Different programming languages have different rules for the specific kinds of code that may be placed in an RL; these are discussed in the reference manual for each language. All languages allow you to place either global or non-global procedures in an RL. Global procedures reference the global storage area of a program's data stack, so that the system will have instructions on how to handle the RL code that are appropriate to each particular file in which it is used. Non-global (also called local or dynamic) procedures are more general and can be prepped and run without any knowledge of the program's data stack. EXECUTION. In the third and final step, illustrated in Figure 1-4, the MPE Loader allocates entries in the HP 3000 Code Segment Table (CST) for each of the program file's SL code segments and in the code segment table extension for each of its other code segments. It also allocates an entry in the HP 3000 Data Segment Table for the process's data stack. These two tables keep track of all the segments needed for your program's execution, as well as for the execution of all other programs ready to run at that time. The Loader also searches segmented libraries to resolve any external references remaining in the program file.
[]
Figure 1-4. Execution Segmented Libraries. The Segmented Library, or SL, is the third of the three libraries which may be accessed during the program development process. An already-existing system SL contains procedures applicable to all HP 3000 systems, such as the procedure for program termination. Segmenter subsystem commands also allow the programmer to create SLs from the material in one or more USLs, to add segments to an already-built SL, to purge segments within SLs, to list the contents of the currently-managed SL, and to copy the contents of one SL into another SL. SLs and RLs share three important characteristics. Both: * Contain procedures needed for program execution. * Are created by the programmer, using Segmenter commands, from USL material. * Are used to permit programs to share procedures. However, the two libraries are intended for different purposes, so there are important differences in how and when they are constructed and used. First, as its name indicates, the segmented library contains procedures in segmented form, not in RBM form as in the RL. When you use the segmenter to build an SL file, it uses the USL's segment association information to bind the required RBMs into code segments as it places them into the file. Procedures thus exist in the SL as runnable code segments. SLs are intended for the storage of procedures with wider applicability than those placed in RLs. Examples are general utility procedures such as FOPEN, which are used in exactly the same way by every calling program. Because of this generality, the Segmenter does not have to allow for the unique combinations and uses of procedures that occur when a program calls for procedures from an RL. Instead, it can prepare, or segment, such general procedures at the moment you specify that you want them placed in an SL. Since the segmentation is not altered when different programs reference procedures in an SL, these segments may be shared concurrently by many programs. While RLs contain code that can be copied and bound to each calling program file, SLs contain code that can be shared; that is, every program references the original version of the code. SL code is not copied or in any way combined with the program file. When a program calls an SL procedure, the procedure is read into memory from its place in disc storage. This method makes economical use of system resources, since each SL procedure exists only once in main memory and does not need to be brought in as part of every program file that requires it. As is true of RLs, the various programming languages have different rules for what kinds of code may go into an SL. The general requirement, however, is that SLs can only contain non-global procedures. These are procedures that make no references to the global storage area of the data stack on which they will run: all parameters must be passed in explicitly. SL procedures may not read information about the stack's global storage area. Sharability is the primary feature of SL procedures. If they required knowledge of global storage, they wouldn't be sharable, since each program's global storage area is different. While the Segmenter links RLs to the program file at preparation time, SLs don't enter the program development process until run time. They are used for the final resolution of external references, and their linkage to the program file is handled by the Loader, rather than the Segmenter. The Segmenter reserves space for called SL procedures in the Segment Transfer Table (STT) at preparation time, but the entries are actually made by the Loader when it searches the SL library files at run time. You may build multiple SLs at each of three levels: SL.group.acct: The Group Library SL. It is the library of the group under which the program file is stored and is readable by any user who can access the group. SL.PUB.acct: The account's Public Library SL. It is the library of the public group of the account under which the program file is stored. It is readable by any user who can access the account. SL.PUB.SYS: The System Library SL. It is the library of the public group of the System account. It can be accessed by all users of the system. If your program file is a permanent file, then then group and account refer to the group and account where the program file resides, which may or may not be the same as your log-on group and account. However, if your program file is not a permanent file but is a job/session temporary or passed file, then group and account refer to your log-on group and account. The LOADPROC intrinsic, which you may use at times to dynamically load and unload SL procedures while your program is running, searches the SL libraries according to the user's log-on group and account, or the group and account where the program resides, as specified by the 'LIB' parameter. See the discussion of the LOADPROC intrinsic in the MPE V Intrinsics Reference Manual (32033-90007) for more information. The search order and the number of libraries searched depend on the the ;LIB parameter specified as part of either the :RUN or the :PREPRUN commands. The table below illustrates this relationship. PARAMETER SEARCH ORDER --------------------------------------------------------------------------------------- ;LIB=G SL.group.acct SL.PUB.acct SL.PUB.SYS ;LIB=P SL.PUB.acct SL.PUB.SYS ;LIB=S SL.PUB.SYS (or no LIB parameter) While you can search only one RL during any one program preparation process, you can search one SL at each of the levels (group, account, and system) during any one execution process. The Code Segment Table (CST) and the Data Segment Table (DST) keep track of the loading and unloading of the necessary segments as program execution proceeds. Although their operation is completely invisible to users, some explanation of what they are and how they work will help complete your picture of the Segmenter. The Code Segment Table. The CST is a main memory-resident table which is maintained by the MPE operating system. It contains a list of code segments that are being referenced by executing programs and keeps track of whether these segments are present in main memory or are out on disc. Entries in the CST are dynamically allocated by the operating system as programs are loaded and unloaded. Although it is often referred to as a single table, the CST is actually divided, logically and physically, into two portions: * The CST contains entries for coded segments in segmented libraries (including the system SL, which contains large chunks of the MPE operating system). Some entries or parts of entries in the CST also contain various service procedures for internal interrupts, external interrupts, system intrinsics, and library procedures. * The CST Extension (CSTX) contains blocks of code segment entries, one block for each loaded program. Note that "loaded" as used here does not necessarily mean "loaded into main memory." Rather, it means that since the segment is part of an executing program, information about it has been loaded, or entered, into the CSTX. The segment itself may still be waiting out on disc. The CST contains space for 2048 entries. The number of blocks of entries in the CSTX is configurable and can be set at system configuration time, but any one block has space for no more than 255 code segment entries. Thus, a program may contain as many as 255 code segments. One larger than that would not be runnable, since there would not be enough room in the CSTX to enter all the information the system needs in order to find and manage all the segments needed for execution. Each segment required for the program receives a unique identifying number (the code segment number), and a CST entry which consists of a single 4-word descriptor providing the following information: * Control information (such as whether the segment is present in main memory or is out on disc). * The segment's length. * The segment's disc (or starting) address if it is not present in main memory. When the system needs to read the code segment into main memory, it uses this information to determine where to start reading and how much to read. Since SLs are sharable, two different programs running at the same time may be using one particular SL code segment. If a CST entry has already been made for a segment, a new entry is not made. Instead, the existing entry is used. The Data Segment Table. Like the Code Segment Table, the Data Segment Table is a main-memory resident table which is maintained by the MPE operating system. It contains a list of data segments currently in use by the operating system and user programs. Each segment receives a four-word entry recording its length, location, presence or absence in main memory, and other characteristics. The length of the table is determined at system generation time. Entries in the DST are dynamically allocated by the system as programs are initiated or terminated, or special capability processes request or release additional data segments. Summary: The Program Development Process Events which occur both before and after the Segmenter's part in program development affect the final segmentation of your program. To ensure good results, you need to keep the Segmenter's purpose and operation in mind as you begin developing your programs, even if you are not yet planning to control the process explicitly. For instance, what you compile into your USL will determine what is available to be placed into an SL, which in turn will affect what the loader will need to do at :RUN time to run your program, and how efficiently it will do so.


MPE/iX 5.0 Documentation