Chapter 14. Data-in-virtual. IBM z/OS Version 2 Release 3
Publicitate
Publicitate
Chapter 14. Data-in-virtual
Data-in-virtual simplifies the writing of applications that use large amounts of data from permanent storage. Applications can create, read, and update data without the I/O buffer, blocksize, and record considerations that the traditional GET and
PUT types of access methods require.
By using the services of data-in-virtual, certain applications that access large amounts of data can potentially improve their performance and their use of system resources. Such applications have an accessing pattern that is non-sequential and unpredictable. This kind of pattern is a function of conditions and values that are revealed only in the course of the processing. In these applications, the sequential record subdivisions of conventional access methods are meaningless to the central processing algorithm. It is difficult to adapt this class of applications to conventional record management programming techniques, which require all permanent storage access to be fundamentally record-oriented. Through the DIV macro, data-in-virtual provides a way for these applications to manipulate the data without the constraints of record-oriented processing.
An application written for data-in-virtual views its permanent storage data as a seamless body of data without internal record boundaries. By using the data-in-virtual MAP service, the application can make any portion of the object appear in virtual storage in an area called a virtual storage window. The window can exist in an address space, a data space, or a shared or non-shared standard
hiperspace. (See “Example of mapping a data-in-virtual object to a data space” on
page 314 and “Using data-in-virtual with hiperspaces” on page 328 for more
information.) When the window is in a data space, the application can reference and update the data in the window by using assembler instructions. When the window is in a hiperspace, the application uses the HSPSERV macro to reference and update the data. To copy the updates to the object, the application uses the data-in-virtual SAVE service.
An application written for data-in-virtual might also benefit by using the
IARVSERV macro to share virtual storage, when that storage is in an address space or data space. For information about sharing data in virtual storage through
IARVSERV, particularly the restrictions for using the data-in-virtual MAP and
UNMAP services, see Chapter 20, “Sharing data in virtual storage (IARVSERV macro),” on page 375.
The data-in-virtual services process the application data in 4096-byte (4K-byte) units on 4K-byte boundaries called blocks. The application data resides in what is called a data-in-virtual object, a data object, or simply an object. The data-in-virtual object is a continuous string of uninterrupted data. The data object can be either a
VSAM linear data set or a non-shared standard hiperspace. Choosing a linear data set as an object or a non-shared standard hiperspace as an object depends on your application. If your application requires the object to retain data, choose a linear data set, which provides permanent storage on DASD. A hiperspace object provides temporary storage.
© Copyright IBM Corp. 1988, 2017
257
When to use data-in-virtual
When an application reads more input and writes more output data than necessary, the unnecessary reads and writes impact performance. You can expect improved performance from data-in-virtual because it reduces the amount of unnecessary I/O.
As an example of unnecessary I/O, consider the I/O performed by an interactive application that requires immediate access to several large data sets. The program knows that some of the data, although not all of it, will be accessed. However, the program does not know ahead of time which data will be accessed. A possible strategy for gaining immediate access to all the data is to read all the data ahead of time, reading each data set in its entirety insofar as this is possible. Once read into processor storage, the data can be accessed quickly. However, if only a small percentage of the data is likely to be accessed during any given period, the I/O performed on the unaccessed data is unnecessary.
Furthermore, if the application changes some data in main storage, it might not keep track of the changes. Therefore, to guarantee that all the changes are captured, the application must then write entire data sets back onto permanent storage even though only relatively few bytes are changed in the data sets.
Whenever such an application starts up, terminates, or accesses different data sets in an alternating manner, time is spent reading data that is not likely to be accessed. This time is essentially wasted, and the amount of it is proportional to the amount of unchanged data for which I/O is performed. Such applications are suitable candidates for a data-in-virtual implementation.
Factors affecting performance
When you write applications using the techniques of data-in-virtual, the I/O takes place only for the data referenced and saved. If you run an application using conventional access methods, and then run it a second time using data-in-virtual techniques, you will notice a difference in performance. This difference depends on two factors: the size of the data set and its access pattern (or reference pattern). Size refers to the magnitude of the data sets that the application must process. The access pattern refers to how the application references the data.
In order to improve performance by using the data-in-virtual application, your data sets must be large and the pattern must be scattered throughout the data set.
Engineering and scientific applications often use data access patterns that are suitable for data-in-virtual. Among the applications that can be considered for a data-in-virtual implementation are: v Applications that process large arrays v VSAM relative record applications v BDAM fixed length record applications
Commercial applications sometimes use data access patterns that are not suitable because they are predictable and sequential. If the access pattern of a proposed application is fundamentally sequential or if the data set is small, a conventional
VSAM (or other sequential access method) implementation may perform better than a data-in-virtual implementation. However, this does not rule out commercial applications as data-in-virtual candidates. If the performance factors are favorable, any type of application, commercial or scientific, is suitable for a data-in-virtual implementation.
258
z/OS MVS Assembler Services Guide
Before you can use the DIV macro to process a linear data set object or a
hiperspace object, you must create either the data set or the hiperspace. Chapter 16,
“Data spaces and hiperspaces,” on page 295 explains how to create a hiperspace.
“Creating a linear data set” explains how to create a linear data set.
Creating a linear data set
To create the data set, you need to specify the DEFINE CLUSTER function of
IDCAMS with the LINEAR parameter. When you code the SHAREOPTIONS parameter for DEFINE CLUSTER, the cross-system value must be 3; that is, you may code SHAREOPTIONS as (1,3), (2,3), (3,3), or (4,3). Normally, you should use
SHAREOPTIONS (1,3).
When creating a linear data set for DIV, you can use the LOCVIEW parameter of the DIV macro in conjunction with the other SHAREOPTIONS. LOCVIEW is
described under the topic “The ACCESS service” on page 263. For a complete
explanation of SHAREOPTIONS, see z/OS DFSMS Using Data Sets.
The following is a sample job that invokes Access Method Services (IDCAMS) to create the linear data set named DIV.SAMPLE on the volume called DIVPAK.
When IDCAMS creates the data set, it creates it as an empty data set. Note that there is no RECORDS parameter; linear data sets do not have records.
//JNAME
//
//*
//*
JOB ’ALLOCATE LINEAR’,MSGLEVEL=(1,1),
CLASS=R,MSGCLASS=D,USER=JOHNDOE
ALLOCATE A VSAM LINEAR DATASET
//*
//CLUSTPG EXEC PGM=IDCAMS,REGION=4096K
//SYSPRINT DD SYSOUT=*
//DIVPAK DD UNIT=3380,VOL=SER=DIVPAK,DISP=OLD
//SYSIN DD *
DEFINE CLUSTER (NAME(DIV.SAMPLE) -
VOLUMES(DIVPAK) -
TRACKS(1,1) -
SHAREOPTIONS(1,3) -
LINEAR)
/*
For further information on creating linear VSAM data sets and altering entry-sequenced VSAM data sets, see z/OS DFSMS Access Method Services
Commands.
Using the services of data-in-virtual
Each invocation of the DIV macro requests any one of the services provided by data-in-virtual: v IDENTIFY v ACCESS v MAP v SAVE v SAVELIST v RESET v UNMAP v UNACCESS v
UNIDENTIFY
Chapter 14. Data-in-virtual
259
Identify
An application must use IDENTIFY to tell the system which data-in-virtual object it wants to process. IDENTIFY generates a unique ID, or token, that uniquely represents an application's request to use the given data object. The system returns this ID to the application. When the application requests other kinds of services with the DIV macro, the application supplies this ID to the system as an input parameter. Specify DDNAME for a linear data set object and STOKEN for a hiperspace object.
Access
To gain the right to view or update the object, an application must use the
ACCESS service. You normally invoke ACCESS after you invoke IDENTIFY and before you invoke MAP. ACCESS is similar to the OPEN macro of VSAM. It has a mode parameter of READ or UPDATE, and it gives your application the right to read or update the object.
If the object is a data set and if the SHAREOPTIONS parameter used to allocate the linear data set implies serialization, the system automatically serializes your access to the object. If access is not automatically serialized, you can serialize access to the object by using the ISGENQ, ENQ, DEQ, and the RESERVE macros. If you do not serialize access to the object, you should consider using the LOCVIEW parameter to protect your window data against the unexpected changes that can occur when access to the object is not serialized. LOCVIEW is described under the
topic “The ACCESS service” on page 263.
If the object is a hiperspace, DIV ensures that only one program can write to the object and that multiple users can only read the object. Only the task that owns the corresponding ID can issue ACCESS.
Map
The data object is stored in units of 4096-byte blocks. An application uses the MAP service to specify the part of the object that is to be processed in virtual storage. It can specify the entire object (all of the blocks), or a part of the object (any continuous range of blocks). Because parts of the same object can be viewed simultaneously through several different windows, the application can set up separate windows on the same object. However, a specific page of virtual storage cannot be in more than one window at a time.
After ACCESS, the application obtains a virtual storage area large enough to contain the window. The size of the object, which ACCESS optionally returns, can determine how much virtual storage you need to request. After requesting virtual storage, the application invokes MAP. MAP establishes a one to one correspondence between blocks in the object and pages in virtual storage. A continuous range of pages corresponds to a continuous range of blocks. This correspondence is called a virtual storage window, or a window.
After MAP, the application can look into the virtual storage area that the window contains. When it looks into this virtual storage area, it sees the same data that is in the object. When the application references this virtual storage area, it is referencing the data from the object. To reference the area in the window, the application simply uses any conventional processor instructions that access storage.
Although the object data becomes available in the window when the application invokes MAP, no actual movement of data from the object into the window occurs
260
z/OS MVS Assembler Services Guide
at that time. Actual movement of data from the object to the window occurs only when the application refers to data in the window. When the application references a page in the window for the first time, a page fault occurs. When the page fault occurs, the system reads the permanent storage block into central storage.
When the system brings data into central storage, the data movement involves only the precise block that the application references. The system updates the contents of the corresponding page in the window with the contents of the linear data set object. Thus, the system brings in only the blocks that an application references into central storage. The sole exception to the system bringing in only the referenced blocks occurs when the application specifies LOCVIEW=MAP with the ACCESS service for a data set object.
Notes:
1.
If the application specifies LOCVIEW=MAP with ACCESS, the entire window is immediately filled with object data when the application invokes MAP.
2.
If, when an application invokes MAP, it would rather keep in the window the data that existed before the window was established (instead of having the object data appear in the window), it can specify RETAIN=YES. Specifying
RETAIN=YES is useful when creating an object or overlaying the contents of an object.
3.
An important concept for data-in-virtual is the concept of freshly obtained storage. When virtual storage has been obtained and not subsequently modified, the storage is considered to be freshly-obtained. The storage is also in this state when it has been obtained as a data space by using a DSPSERV
CREATE and not subsequently modified. After a DSPSERV RELEASE, the storage is still considered freshly obtained until it has been modified. When referring to this storage or any of its included pages, this information uses
“freshly obtained storage” and “freshly obtained pages”. If a program stores into a freshly obtained page, only that page loses its freshly obtained-status, while other pages still retain it.
4.
You can map virtual storage pages that are protected only when you specify
RETAIN=YES. When the system establishes the virtual window, you can use the PGSER PROTECT macro to protect the data in the window. However, you must ensure that the data in the window is not protected when you issue the
RESET form of the DIV macro.
Save, savelist, and reset
After using the MAP service, the application can access the data inside the window directly through normal programming techniques. When the application changes some data in the window, however, the data on the object does not consequently change. If the application wants the data changes in the window to appear in the object, it must use the SAVE service. SAVE writes all changed blocks within the range to be saved inside the window to the object. It does not write unchanged blocks. When SAVE completes, the object contains any changes that the application made inside the virtual storage window. If a SAVE is preceded by another SAVE, the second SAVE will pick up only the changes that occurred since the previous SAVE.
Optionally, SAVE accepts a user list as input. To provide a user list, the application uses the SAVELIST service. SAVELIST returns the addresses of the first and last changed pages in each range of changed pages within the window. The application can then use these addresses as the user list for SAVE. The SAVE operation can be
Chapter 14. Data-in-virtual
261
more efficient when using the list of addresses, so an application can improve its performance by using SAVELIST and then SAVE.
When specifying a user list and when a data space or hiperspace contains the window, the caller must use an STOKEN with SAVE to identify the data space or hiperspace.
If the application changes some data in a virtual storage window but then decides not to keep those changes, it can use the RESET service to reload the window with data from the object. RESET reloads only the blocks that have been changed unless you specify or have specified RELEASE=YES.
Unmap
When the application is finished processing the part of the object that is in the window, it eliminates the window by using UNMAP. To process a different part of the object, one not already mapped, the application can use the MAP service again.
The SAVE, RESET, MAP, and UNMAP services can be invoked repeatedly as required by the processing requirements of the application.
If you issued multiple MAPs to different STOKENs, use STOKEN with UNMAP to identify the data space or hiperspace you want to unmap.
Note:
If you do not want to retain the data in the virtual window, use the PGSER
UNPROTECT macro to “unprotect” any protected pages in the window, before you use the UNMAP service.
If you issue UNMAP with RETAIN=NO and there are protected pages in the virtual storage window, the system loses the data in the protected pages and preserves the protection status. If you try to reference the protected pages, the system issues abend X'028'. To access the protected pages again, remove the protection status. Then issue the PGSER RELEASE or DSPSERV RELEASE macro to release all physical paging resources.
Unaccess
If the application has temporarily finished processing the object but still has other processing to perform, it uses UNACCESS to relinquish access to the object. Then other programs can access the object. If the application needs to access the same object again, it can regain access to the object by using the ACCESS service again without having to use the IDENTIFY service again.
Unidentify
UNIDENTIFY ends the use of a data-in-virtual object under a previously assigned
ID that the IDENTIFY service returned.
The IDENTIFY service
Your program uses IDENTIFY to select the data-in-virtual object that you want to process. IDENTIFY has four parameters: ID, TYPE, DDNAME, and STOKEN.
The following examples show two ways to code the IDENTIFY service:
For a hiperspace object:
DIV IDENTIFY,ID=DIVOBJID,TYPE=HS,STOKEN=HSSTOK
262
z/OS MVS Assembler Services Guide
|
|
For a data set object:
DIV IDENTIFY,ID=DIVOBJID,TYPE=DA,DDNAME=DDAREA
The parameters are as follows:
ID
The ID parameter specifies the address where the IDENTIFY service returns a unique eight-byte name that connects a particular user with a particular object.
This name is an output value from IDENTIFY, and it is also a required input value to all other services.
Simultaneous requests for different processing activities against the same data-in-virtual object can originate from different tasks or from different routines within the same task or the same routine. Each task or routine requesting processing activity against the object must first invoke the identify service. To correlate the various DIV macro invocations and processing activities, the eight-byte IDs generated by IDENTIFY are sufficiently unique to reflect the individuality of the IDENTIFY request, yet they all reflect the same data-in-virtual object.
TYPE
The TYPE parameter indicates the type of data-in-virtual object, either a linear data set (TYPE=DA) or a hiperspace (TYPE=HS). DIV does not support VSAM extended format linear data sets for use as a DIV object for which the size is greater than 4GB.
DDNAME
When you specify TYPE=DA for a data set object, you must specify DDNAME to identify your data-in-virtual object. If you specify TYPE=HS with IDENTIFY, do not specify DDNAME. (Specify STOKEN instead.) Do not specify a
DDNAME that corresponds to a VSAM extended format linear data set for which the size is greater than 4GB, because DIV does not support them for use as a DIV object.
Encrypted linear VSAM data sets are supported. For more information, see
z/OS DFSMS Using Data Sets.
STOKEN
When you specify TYPE=HS for a hiperspace object, you must specify
STOKEN to identify that hiperspace. The STOKEN must be addressable in your primary address space. The hiperspace must be a non-shared standard hiperspace and must be owned by the task issuing the IDENTIFY. The system does not verify the STOKEN until your application uses the associated ID to access the object.
The ACCESS service
Your program uses the ACCESS service to request permission to read or update the object. ACCESS has two required parameters: ID and MODE, and two optional parameters: SIZE and LOCVIEW.
The following example shows one way to code the ACCESS service.
DIV ACCESS,ID=DIVOBJID,MODE=UPDATE,SIZE=OBJSIZE
ID: When you issue a DIV macro that requests the ACCESS service, you must also specify, on the ID parameter, the identifier that the IDENTIFY service returned. The
ID parameter tells the system what object you want access to. When you request permission to access the object under a specified ID, the system checks the following conditions before it grants the access:
Chapter 14. Data-in-virtual
263
v You previously established the ID specified with your ACCESS request by invoking IDENTIFY.
v
You have not already accessed the object under the same unique eight-byte ID.
Before you can reaccess an already-accessed object under the same ID, you must first invoke UNACCESS for that ID.
v If your installation uses RACF
® and the object is a linear data set, you must have the proper RACF authorization to access the object.
v If you are requesting read access, the object must not be empty. Use the MODE parameter to request read or update access.
v If the data object is a hiperspace, the system rejects the request if the hiperspace:
– Has ever been the target of an ALESERV ADD.
– Has one or more readers and one updater. (That is, the hiperspace can have readers and it can have one updater, but it can't have both.) v If the data object is a linear data set, the system rejects the request if the linear data set:
– Is a VSAM extended format linear data set for which the size is greater than
4GB.
MODE: The MODE parameter specifies how your program will access the object.
You can specify a mode parameter of READ or UPDATE. They are described as follows: v READ lets you read the object, but prevents you from using SAVE, to change the object.
v UPDATE, like READ, lets you read the object, but it also allows you update the object with SAVE.
Whether you specify READ or UPDATE, you can still make changes in the window, because the object does not change when you change the data in the window.
SIZE: The SIZE parameter specifies the address of the field where the system stores the size of the object. The system returns the size in this field whenever you specify SAVE or ACCESS with SIZE. If you omit SIZE or specify SIZE=*, the system does not return the size.
If you specified TYPE=DA with IDENTIFY for a data set object, SIZE specifies the address of a four-byte field. When control is returned to your program after the
ACCESS service executes, the four-byte field contains the current size of the object.
The size is the number of blocks that the application must map to ensure the mapping of the entire object.
If you specified TYPE=HS with IDENTIFY for a hiperspace object, ACCESS returns two sizes. The first is the current size of the hiperspace (in blocks). The second is the maximum size of the hiperspace (also in blocks). When specifying SIZE with an ID associated with a hiperspace object, you must provide an eight-byte field in which the system can return the sizes (4 bytes each).
LOCVIEW: The LOCVIEW parameter allows you to specify whether the system is to create a local copy of the data-in-virtual object.
If your object is a hiperspace, you cannot specify LOCVIEW=MAP.
If your object is a data set, you can code the LOCVIEW parameter two ways:
264
z/OS MVS Assembler Services Guide
v LOCVIEW=MAP v
LOCVIEW=NONE (the default if you do not specify LOCVIEW)
If another program maps the same block of a data-in-virtual object as your program has mapped, a change in the object due to a SAVE by the other program can sometimes appear in the virtual storage window of your program. The change can appear when you allocate the data set object with a SHAREOPTIONS(2,3),
SHAREOPTIONS(3,3), or SHAREOPTIONS(4,3) parameter, and when the other program is updating the object while your program is accessing it.
If the change appears when your program is processing the data in the window, processing results might be erroneous because the window data at the beginning of your processing is inconsistent with the window data at the end of your processing. The relationship between SHAREOPTIONS and LOCVIEW is as follows: v When you allocate the data set object by SHAREOPTIONS(2,3),
SHAREOPTIONS(3,3), or SHAREOPTIONS(4,3), the system does not serialize the accesses that programs make to the object. Under these options, if the programs do not observe any serialization protocol, the data in your virtual storage window can change when other programs invoke SAVE. To ensure that your program has a consistent view of the object, and protect your window from changes that other programs make on the object, use LOCVIEW=MAP. If you do not use LOCVIEW=MAP when you invoke ACCESS, the system provides a return code of 4 and a reason code of hexadecimal 37 as a reminder that no serialization is in effect even though the access was successful.
v
When you allocate the object by SHAREOPTIONS(1,3), object changes made by the other program cannot appear in your window because the system performs automatic serialization of access. Thus, when any program has update access to the object, the system automatically prevents all other access. Use
LOCVIEW=NONE when you allocate the data set by SHAREOPTIONS(1,3).
Note:
The usual method of programming data-in-virtual is to use
LOCVIEW=NONE and SHAREOPTIONS(1,3). LOCVIEW=MAP is provided for programs that must access a data object simultaneously. Those programs would not use SHAREOPTIONS(1,3).
LOCVIEW=MAP requires extra processing that degrades performance. Use
LOCVIEW=NONE whenever possible although you can use LOCVIEW=MAP for small data objects without significant performance loss. When you write a program that uses LOCVIEW=MAP, be careful about making changes in the object size.
Consider the following: v When a group of programs, all using LOCVIEW=MAP, have simultaneous access to the same object, no program should invoke any SAVE or MAP that extends or truncates the object unless it informs the other programs by some coding protocol of a change in object size. When the other programs are informed, they can adjust their processing based on the new size.
v All the programs must create their maps before any program changes the object size. Subsequently, if any program wants to reset the map or create a new map, it must not do so without observing the protocol of a size check. If the size changed, the program should invoke UNACCESS, followed by ACCESS to get the new size. Then the program can reset the map or create the new map.
Chapter 14. Data-in-virtual
265
The MAP service
The MAP service makes an association between part or all of an object, the portion being specified by the OFFSET and SPAN parameters, and your program's virtual storage. This association, which is called a virtual storage window, takes the form of a one-to-one correspondence between specified blocks on the object and specified pages in virtual storage. After the MAP is complete, your program can then process the data in the window. The RETAIN parameter specifies whether data that is in the window when you issue MAP is to remain or be replaced by the data from the associated object.
Note:
You cannot map virtual storage pages that are page-fixed into a virtual storage window. Once the window exists, you can page-fix data inside the window so long as it is not fixed when you issue SAVE, UNMAP, or RESET.
If your window is in an address space, you can map either a linear data set or a
hiperspace object. See Figure 62.
Permanent Object
Address Space
Linear Data Set window
OR
Address Space
Temporary Object
Hiperspace window
Figure 62. Mapping from an address space
If your window is in a data space or a hiperspace, you can map only a linear data
set. See Figure 63 on page 267.
266
z/OS MVS Assembler Services Guide
Data Space or Hiperspace window
Permanent Object
Linear Data Set
Figure 63. Mapping from a data space or hiperspace
If your window is in a data space or hiperspace, you can issue multiple MAPs under the same ID to different data spaces or hiperspaces. You cannot mix data space maps or hiperspace maps with address space maps under the same ID at any one time. However, you can mix data space maps and hiperspace maps. See
The MAP service has two required parameters: ID and OFFSET, and five optional parameters: SPAN, AREA, RETAIN, STOKEN, and PFCOUNT.
The following examples show two ways to code the MAP service.
Hiperspace or data set object:
DIV MAP,ID=DIVOBJID,AREA=MAPPTR1,SPAN=SPANVAL,OFFSET=*,PFCOUNT=7
Data set object:
DIV MAP,ID=DIVOBJID,AREA=MAPPTR1,SPAN=SPANVAL,OFFSET=*,STOKEN=DSSTOK,PFCOUNT=7
ID: The ID parameter specifies the storage location containing the unique eight-byte value that was returned by IDENTIFY. The map service uses this value to determine which object is being mapped under which request.
If you specify the same ID on multiple invocations of the MAP service, you can create simultaneous windows corresponding to different parts of the object.
However, an object block that is mapped into one window cannot be mapped into any other window created under the same ID. If you use different IDs, however, an object block can be included simultaneously in several windows.
OFFSET and SPAN: The OFFSET and SPAN parameters indicate a range of blocks on the object. Blocks in this range appear in the window. OFFSET indicates the first object block in the range, while SPAN indicates how many contiguous blocks make up the range. An offset of zero indicates the beginning of the object. For example, an offset of zero and a span of ten causes the block at the beginning of the object to appear in the window, together with the next nine object blocks. The window would then be ten pages long.
Chapter 14. Data-in-virtual
267
Data Space or Hiperspace window
Data Space or Hiperspace window
Permanent Object
Linear Data Set
Data Space or Hiperspace window
Figure 64. Multiple mapping
Specifying OFFSET=* or omitting OFFSET causes the system to use a default
OFFSET of zero. Specifying SPAN=0, SPAN=*, or omitting SPAN results in a default SPAN of the number of blocks needed to MAP the entire object, starting from the block indicated by OFFSET. Specifying both OFFSET=* and SPAN=* or omitting both causes the entire object to appear in the window.
You may use the OFFSET and SPAN parameters to specify a range spanning any portion of the object, the entire object, or extending beyond the object. Specifying a range beyond the object enables a program to add data to the object, increasing the size of the object. If data in a mapped range beyond the object is saved (using the
SAVE service), the size of the object is updated to reflect the new size.
To use the OFFSET parameter, specify the storage location containing the block offset of the first block to be mapped. The offset of the first block in the data object is zero. To use the SPAN parameter, specify the storage location containing the number of blocks in the mapped range.
Note:
Data-in-virtual always allocates an extra block beyond the requested block number range to ensure that there is enough space for an end-of-file (EOF) record.
268
z/OS MVS Assembler Services Guide
Therefore, when a DIV object is created without extents, the largest possible span value is the total number of blocks contained in the DIV object minus one.
AREA: When you specify MAP, you must also specify an AREA parameter. AREA indicates the beginning of a virtual storage space large enough to contain the entire window. Before invoking MAP, you must ensure that your task owns this virtual storage space. The storage must belong to a single, pageable private area subpool.
It must begin on a 4096-byte boundary (that is, a page boundary) and have a length that is a multiple of 4096 bytes.
Note that any virtual storage space assigned to one window cannot be simultaneously assigned to another window. If your MAP request specifies a virtual storage location, via the AREA parameter, that is part of another window, the system rejects the request.
You cannot free virtual storage that is mapped into a window as long as the map exists. Attempts to do this will cause your program to abend. Subsequent attempts to reference the mapped virtual space will cause an ABEND.
RETAIN: The RETAIN parameter determines what data you can view in the window. It can be either the contents of the virtual storage area (that corresponds to the window) the way it was before you invoked MAP, or it can be the contents of the object. The following table shows how using the RETAIN parameter with
MAP affects the contents of the window.
RETAIN=
NO (default)
YES
Window view
Contents of mapped object
Contents of virtual storage
If you specify RETAIN=NO, or do not specify the RETAIN parameter at all (which defaults to RETAIN=NO), the contents of the object replace the contents of the virtual storage whenever your program references a page in the window. Virtual storage that corresponds to a range beyond the end of the object appears as binary zeroes when referenced. You can use RETAIN=NO to change some data and save it back to the object.
If you specify RETAIN=YES, the window retains the contents of virtual storage.
The contents of the window are not replaced by data from the object. If you issue a subsequent SAVE, the data in the window replaces the data on the object. If the window extends beyond the object and your program has not referenced the pages in the extending part of the window, the system does not save the extending pages. However, if your program has referenced the extending pages, the system does save them on the object, extending the object so it can hold the additional data.
You can also use RETAIN=YES to reduce the size of (truncate) the object. If the part you want to truncate is mapped with RETAIN=YES and the window consists of freshly obtained storage, the data object size is reduced at SAVE time.
If you want to have zeroes written at the end of the object, the corresponding virtual storage must be explicitly set to zero prior to the SAVE.
STOKEN: To reference an entire linear data set through a single window, a program might require a considerable amount of virtual storage. In this case, the program can use a data space or hiperspace to contain the window. If you want
Chapter 14. Data-in-virtual
269
the virtual storage window to be in a data space or hiperspace, specify STOKEN when you invoke MAP. When you specify STOKEN, you provide an eight-byte input parameter that identifies the data space or hiperspace, and that was returned from DSPSERV CREATE.
However, do not place the window in a data space or hiperspace under the following circumstances: v If the data space is a disabled reference (DREF) data space.
v If the object is accessed with LOCVIEW=MAP.
v If the data space or hiperspace belongs to another task. However, if your program is in supervisor state or has a system storage key, it can use a data space or hiperspace that belongs to another task provided that the other task is in the same primary address space as your program.
PFCOUNT: PFCOUNT is useful for referencing sequential data. Because you get a page fault the first time you reference each page, preloading successive pages decreases the number of page faults.
The PFCOUNT parameter (nnn) is an unsigned decimal number up to 255. When an application references a mapped object, PFCOUNT tells the system that the program will be referencing this object in a sequential manner. PFCOUNT might improve performance because it asks the system to preload nnn pages, if possible.
The system reads in nnn successive pages only to the end of the virtual range of the mapped area containing the originally referenced page, and only as resources are available.
You can use REFPAT INSTALL to define a reference pattern for the mapped area.
In response to REFPAT, the system brings multiple pages into central storage when referenced. In this case, the PFCOUNT value you specify on DIV is not in effect as long as the reference pattern is in effect. When REFPAT REMOVE removes the definition of the reference pattern, the PFCOUNT you specify on DIV is again in
effect. For information on the REFPAT macro, see “Defining the reference pattern
The SAVE service
The SAVE service writes changed pages from the window to the object if the changed pages are within the range to be saved. When you invoke SAVE, you specify one of the following: v A single and continuous range of blocks in the data-in-virtual object with the use of OFFSET and SPAN. Any virtual storage windows inside this range are eligible to participate in the save.
v A user list supplied through the use of LISTADDR and LISTSIZE. The list must contain the addresses of the first and last changed pages for each range of changed pages within the window. The SAVELIST service can provide these addresses for the user list.
For a SAVE request to be valid, the object must currently be accessed with
MODE=UPDATE, under the same ID as the one specified on this SAVE request.
Because you can map an object beyond its current end, the object might be extended when the SAVE completes if there are changed pages beyond the current end at the time of the ACCESS. On the other hand, the SAVE truncates the object if freshly obtained pages are being saved that are mapped in a range that extends to or beyond the end of the object and additional non-freshly obtained pages beyond
270
z/OS MVS Assembler Services Guide
the object area are not also being saved. In either case, the new object size is returned to your program if you specify the SIZE parameter.
When the system writes the pages from the window to the object, it clears (sets to zeroes) blocks in the object that are mapped to freshly obtained pages in the window if either one of the following conditions is true: v There are subsequent pages in the range being saved that are not freshly obtained v The blocks mapped to the freshly obtained pages are not at the end of the object.
That is, they are imbedded in the object somewhere before the last block of the object. If the blocks mapped to freshly obtained pages do extend to the end of the object and no subsequent non-freshly obtained pages are being saved, then the object is truncated by that number of blocks.
If you specified RETAIN=YES with MAP, SAVE treats pages in the window that you have not previously saved as changed pages and will write them to the object.
Notes:
1.
Do not specify SAVE for a storage range that contains DREF or page fixed storage.
2.
If data to be saved has not changed since the last SAVE, no I/O will be performed. The performance advantages of using data-in-virtual are primarily because of the automatic elimination of unnecessary read and write I/O operations.
3.
The range specified with SAVE can extend beyond the end of the object.
4.
The system does not save pages of an object that is not mapped to any window.
5.
The system does not save pages in a window that lies outside the specified range.
The following example shows how to code the SAVE service for a hiperspace or data set object.
DIV SAVE,ID=DIVOBJID,SPAN=SPAVAL,OFFSET=*,SIZE=OBJSIZE
ID: The ID parameter tells the SAVE service which data object the system is writing to under which request. Use ID to specify the storage location containing the unique eight-byte name that was returned by IDENTIFY. You must have previously accessed the object with MODE=UPDATE under the same ID as the one specified for SAVE.
OFFSET and SPAN: Use the OFFSET and SPAN parameters to select a continuous range of object blocks within which the SAVE service can operate. OFFSET indicates the first block and SPAN indicates the number of blocks in the range. As in the MAP service, the offset and span parameters refer to object blocks; they do not refer to pages in the window. You cannot specify OFFSET and SPAN when you specify LISTADDR and LISTSIZE.
Specifying OFFSET=* or omitting OFFSET causes the system to use the default offset (zero). The zero offset does not omit or skip over any of the object blocks, and it causes the range to start right at the beginning of the object. Specifying
SPAN=0, SPAN=*, or omitting SPAN gives you the default span. The default span includes the first object block after the part skipped by the offset, and it includes the entire succession of object blocks up to and including the object block that corresponds to the last page of the last window.
Chapter 14. Data-in-virtual
271
When SAVE executes, it examines each virtual storage window established for the object. In each window, it detects every page that corresponds to an object block in the selected range. Then, if the page has changed since the last SAVE, the system writes the page on the object. (If the page has not changed since the last SAVE, it is already identical to the corresponding object block and there is no need to save it.)
Although SAVE discriminates between blocks on the basis of whether they have changed, it has the effect of saving all window pages that lie in the selected range.
Specifying both OFFSET=* and SPAN=* or omitting both causes the system to save all changed pages in the window without exceptions.
To use the OFFSET parameter, specify the storage location containing the block offset of the first block to be saved. The offset of the first block in the object is zero.
To use the SPAN parameter, specify the storage location containing the number of blocks in the range to be saved.
SIZE: When you specify SIZE after the SAVE completes, the system returns the size of the data object in the virtual storage location specified by the SIZE parameter. If you omit SIZE or specify SIZE=*, the system does not return the size value. If TYPE=DA, invoking SAVE can change the size of the object. If TYPE=HS, invoking SAVE has no effect on the size of the object.
LISTADDR: The LISTADDR parameter specifies the address of the first entry in the user list. Use this parameter and the LISTSIZE parameter when you specify a user list as input for SAVE.
LISTSIZE: The LISTSIZE parameter specifies the number of entries in the user list.
Use this parameter and the LISTADDR parameter when you specify a user list as input for SAVE.
STOKEN: If you specify a user list as input for SAVE and a data space or hiperspace contains the window, you must specify STOKEN when you invoke
SAVE. When you specify STOKEN, you provide an eight-byte input parameter that identifies the data space or hiperspace, and that was returned from DSPSERV
CREATE.
The SAVELIST service
The advantage of using SAVELIST with SAVE is improved performance, especially for applications that manipulate graphic images. The SAVELIST service allows the application to inspect and verify data only in pages that have been changed. In a user list provided by the application, SAVELIST returns the addresses of the first and last page in each range of changed pages within the window. The mapped ranges may be either address spaces, data spaces or hiperspaces. If more than one data space or hiperspace is mapped onto a DIV object, the selected range must be contained within a single data space or hiperspace.
The application must set up a user list before issuing SAVELIST. Upon return from
SAVELIST, the first word of each list entry holds the virtual storage address of the first page in a range of changed pages. The second word of the entry holds the virtual storage address of the last changed page in that range. In the last valid entry of the user list, the high-order bit of the first word is set to one.
If the reason code indicates that there are more changed pages that can fit in this list, the first word of the last entry in the list contains an offset (in block number format) into the DIV object from which more changed pages might exist. The second word of the last entry contains the span from the new offset to the block
272
z/OS MVS Assembler Services Guide
pointed to by the original OFFSET/SPAN combination. If more changed pages can fit in the user list, you can issue SAVE with the current list, and then issue
SAVELIST and SAVE again to obtain the additional changed pages and to save them.
ID: Use ID to specify the storage location containing the unique eight-byte name that was returned by IDENTIFY, which connects a particular user with a particular object.
LISTADDR: The LISTADDR parameter specifies the address of the first entry in the user list.
LISTSIZE: The LISTSIZE parameter specifies the number of entries in the list. The size of the list must be a minimum of three entries and a maximum of 255 entries.
The SAVELIST service can place addresses in all but the last two entries, which the macro uses as a work area.
The RESET service
At times during program processing, your program might have made changes to pages in the virtual storage window, and might no longer want to keep those changes. RESET, which is the opposite of SAVE, replaces data in the virtual storage window with data from the object. As with SAVE and MAP, the range to be reset refers to the object rather than the virtual storage. RESET resets only windows that are within the specified range, and it resets all the windows in the range that your program changed.
Do not specify RESET for a storage range that contains DREF storage.
Effect of RETAIN mode on RESET
You actually specify RETAIN on MAP, not on RESET, but the RETAIN mode of each individual window affects how the system resets the window. The following table shows the effect that issuing RETAIN with MAP has on RESET.
RETAIN=
NO (default)
YES
RESET results
The data in the window matches the object data as of the last
SAVE.
Unless saved, the data in the window become freshly obtained.
Any pages previously saved re-appear in their corresponding window. All other pages appear freshly obtained.
The system resets the window as follows: v If you specified RETAIN=NO with MAP, after the RESET, the data in the window matches the object data as of the last SAVE. This applies to all the pages in the window.
v If you specified RETAIN=YES with MAP, the pages in the window acquire a freshly obtained status after the RESET unless you have been doing SAVE operations on this window. Individual object blocks changed by those SAVE operations re-appear after the RESET in their corresponding window pages, together with the other pages. However, the other pages appear freshly obtained.
Chapter 14. Data-in-virtual
273
Note:
Regardless of the RETAIN mode of the window, any window page that corresponds to a block beyond the end of the object appears as a freshly obtained page.
The following example shows how to code the RESET service for a hiperspace or data set object:
DIV RESET,ID=DIVOBJID,SPAN=SPANVAL,OFFSET=*,RELEASE=YES
ID: The ID parameter tells the RESET service what data object is being written to.
Use ID to specify the storage location containing the unique eight-byte name that was returned by IDENTIFY and used with previous MAP requests. You must have previously accessed the object (with either MODE=READ or MODE=UPDATE) under the same ID as the one currently specified for RESET.
OFFSET and SPAN: The OFFSET and SPAN parameters indicate the RESET range, the part of the object that is to supply the data for the RESET. As with MAP and
SAVE, OFFSET indicates the first object block in the range, while SPAN indicates how many contiguous blocks make up the range, starting from the block indicated by OFFSET. The first block of the object has an offset of zero.
To use OFFSET, specify the storage location containing the block offset of the first block to be reset. To use SPAN, specify the storage location containing the number of blocks in the range to be RESET. Specifying OFFSET=* or omitting OFFSET causes the system to use a default OFFSET of zero. Specifying SPAN=* or omitting
SPAN sets the default to the number of blocks needed to reset all the virtual storage windows that are mapped under the specified ID starting only with the block number indicated by OFFSET. Specifying both OFFSET=* and SPAN=* or omitting both resets all windows that are currently mapped under the specified ID.
RELEASE: RELEASE=YES tells the system to release all pages in the reset range.
RELEASE=NO does not replace unchanged pages in the window with a new copy of pages from the object. It replaces only changed pages. Another ID might have changed the object itself while you viewed data in the window. Specify
RELEASE=YES to reset all pages. Any subsequent reference to these pages causes the system to load a new copy of the data page from the object.
The UNMAP service
Your program uses the UNMAP service to remove the association between a window in virtual storage and the object. Each UNMAP request must correspond to a previous MAP request. Note that UNMAP has no effect on the object. If you made changes in virtual storage but have not yet saved them, the system does not save them on the object when you issue UNMAP. UNMAP has two required parameters: ID and AREA, and two optional parameters: RETAIN and STOKEN.
The following examples show two ways to code the UNMAP service.
Hiperspace or data set object:
DIV UNMAP,ID=DIVOBJID,AREA=MAPPTR1
Data set object:
DIV UNMAP,ID=DIVOBJID,AREA=MAPPTR1,STOKEN=DSSTOK
ID: The ID parameter you specify is the address of an eight-byte field in storage.
That field contains the identifier associated with the object. The identifier is the
274
z/OS MVS Assembler Services Guide
same value that the IDENTIFY service returned, which is also the same value you specified when you issued the corresponding MAP request.
AREA: The AREA parameter specifies the address of a four-byte field in storage that contains a pointer to the start of the virtual storage to be unmapped. This address must point to the beginning of a window. It is the same address that you provided when you issued the corresponding MAP request.
RETAIN: RETAIN specifies the state that virtual storage is to be left in after it is unmapped, that is, after you remove the correspondence between virtual storage and the object.
Specifying RETAIN=NO with UNMAP indicates that the data in the unmapped window is to be freshly obtained.
If your object is a hiperspace, you cannot specify RETAIN=YES. If your object is a data set, you can specify RETAIN=YES.
Specifying RETAIN=YES on the corresponding UNMAP transfers the data of the object into the unchanged pages in the window. In this case, RETAIN=YES with
UNMAP specifies that the virtual storage area corresponding to the unmapped window is to contain the last view of the object. After UNMAP, your program can still reference and change the data in this virtual storage but can no longer save it on the object unless the virtual area is mapped again.
Notes:
1.
If you issue UNMAP with RETAIN=NO, and there are unsaved changes in the virtual storage window, those changes are lost.
2.
If you issue UNMAP with RETAIN=YES, and there are unsaved changes in the window, they remain in the virtual storage.
3.
Unmapping with RETAIN=YES has certain performance implications. It causes the system to read unreferenced pages, and maybe some unchanged ones, from the object. You must not unmap with RETAIN=YES if your object is a hiperspace.
4.
If the window is in a deleted data space, UNMAP works differently depending on whether you specify RETAIN=YES or RETAIN=NO. If you specify
RETAIN=YES, the unmap fails and the program abends. Otherwise, the unmap is successful.
STOKEN: If you issued multiple maps under the same ID with different STOKENs, use STOKEN with UNMAP. If you do not specify STOKEN in this case, the system will scan the mapped ranges and unmap the first range that matches the specified virtual area regardless of the data space it is in. Issuing UNACCESS or
UNIDENTIFY automatically unmaps all mapped ranges.
The UNACCESS and UNIDENTIFY services
Use UNACCESS to terminate your access to the object for the specified ID.
UNACCESS automatically includes an implied UNMAP. If you issue an
UNACCESS with outstanding virtual storage windows, any windows that exist for the specified ID are unmapped with RETAIN=NO. The ID parameter is the sole parameter of the UNACCESS service, and it designates the same ID that you specified in the corresponding ACCESS. As in the other services, use ID to specify the storage location containing the unique eight-byte name that was returned by
IDENTIFY.
Chapter 14. Data-in-virtual
275
Use UNIDENTIFY to notify the system that your use of an object under the specified ID has ended. If the object is still accessed as an object under this ID,
UNIDENTIFY automatically includes an implied UNACCESS. The UNACCESS, in turn, issues any necessary UNMAPs using RETAIN=NO. The ID parameter is the only parameter for UNIDENTIFY, and it must designate the same ID as the one specified in the corresponding ACCESS. As in the other services, use ID to specify the storage location containing the unique eight-byte name that was returned by
IDENTIFY.
The following example shows how to code the UNACCESS and UNIDENTIFY services for a hiperspace or data set object:
DIV UNACCESS,ID=DIVOBJID
DIV UNIDENTIFY,ID=DIVOBJID
Sharing data in an object
When a user issues IDENTIFY, the system returns an ID and establishes an association between the ID and the user's task. All data-in-virtual services for a specific ID must be requested by the task that issued the IDENTIFY and obtained the ID.
Any task can reference or change the data in a mapped virtual storage window, even if the window was mapped by another task, and even if the object was identified and accessed by another task. Any task that has addressability to the window can reference or change the included data. However, only the task that issued the IDENTIFY can issue the SAVE to change the object.
When more than one user has the ability to change the data in a storage area, take the steps necessary to serialize the use of the shared area.
Miscellaneous restrictions for using data-in-virtual
v When you attach a new task, you cannot pass ownership of a mapped virtual storage window to the new task. That is, you cannot use the GSPV and GSPL parameters on ATTACH and ATTACHX to pass the mapped virtual storage.
v You cannot invoke data-in-virtual services in cross memory mode. There are no restrictions, however, against referencing and updating a mapped virtual storage window in cross memory mode.
v
You cannot specify a non-shared standard hiperspace as a DIV object (DIV
ACCESS) if you have issued ALESERV ADD for that hiperspace. You cannot issue ALESERV ADD for a non-shared standard hiperspace while it is a DIV object.
DIV macro programming examples
The programming examples illustrate how to code and execute a program that processes a data-in-virtual object. You can find additional examples, including illustrations, in: v
“Example of mapping a data-in-virtual object to a data space” on page 314
v
“Using data-in-virtual with hiperspaces” on page 328
General program description
This is a description of the program shown in “Data-in-virtual sample program code” on page 277.
276
z/OS MVS Assembler Services Guide
1.
The program issues a DIV IDENTIFY and DIV ACCESS for the data-in-virtual object. The ACCESS returns the current size of the object in units of 4K bytes.
2.
If the object contains any data (the size returned by ACCESS is non-zero), the program issues a DIV MAP to associate the object with storage the program acquires using GETMAIN. The size of the MAP (and the acquired storage area) is the same as the size of the object.
3.
The program now processes the input statements from SYSIN. The processing depends upon the function requests (S, D, or E). If the program encounters an end-of-file, it treats it as if an “E” function was requested.
S function — Set a character in the object:
4.
If the byte to change is past the end of the mapped area, the user asked to increase the size of the object. Therefore: a.
If any changes have been made in the mapped virtual storage area but not saved to the object, the program issues a DIV SAVE. This save writes the changed 4K pages in the mapped storage to the object.
b.
The program issues a DIV UNMAP for the storage area acquired with
GETMAIN, and then releases that area using FREEMAIN. The program skips this is step if the current object size is 0.
c.
The program acquires storage using GETMAIN to hold the increased size of the object, and issues a DIV MAP for this storage.
5.
The program changes the associated byte in the mapped storage. Note that this does not change the object. The program actually writes the changes to the object when you issue a DIV SAVE.
D function — Display a character in the object:
6.
If the requested location is within the MAP size, the program references the specified offset into the storage area. If the data is not already in storage, a page fault occurs. Data-in-virtual processing brings the required 4K block from the object into storage. Then the storage reference is re-executed. The contents of the virtual storage area (i.e. the contents of the object) are displayed.
E function — End the program:
7.
If the program has made any changes in the mapped virtual storage area but has not saved them to the object, the program issues a DIV SAVE.
8.
The program issues a DIV UNIDENTIFY to terminate usage of the object. Note that data-in-virtual processing internally generates a DIV UNMAP and
DIV UNACCESS.
9.
The program terminates.
Data-in-virtual sample program code
The first part of DIVSAMPL identifies the linear data set and accesses the object. If the object is not empty, the program obtains the virtual storage required to view
(MAP) the entire object. Then it opens the input and message sequential data sets.
Chapter 14. Data-in-virtual
277
DIV TITLE ’Data-in-Virtual Sample Program’
DIVSAMP CSECT ,
DIVSAMP AMODE 31
DIVSAMP RMODE 24
Program runs in 31-bit mode
Program resides in 24-bit storage
SAVE (14,12),,’DIVSAMP -- Sample Program’
LR R11,R15 Establish base register
USING DIVSAMP,R11
LA R2,VSVEAREA
*
Chain save areas together
ST
ST
R13,4(,R2)
R2,8(,R13)
*
*
LR R13,R2 *
* IDENTIFY and ACCESS the object pointed to by DD ’DIVDD’.
* Save the object’s token in VTOKEN, and its size in VSIZEP.
DIV IDENTIFY,TYPE=DA,ID=VTOKEN,DDNAME=CDIVDD Specify DDNAME
LA R2,1
LTR R15,R15
Error code
IDENTIFY work ok ?
BNZ LERROR * No -- quit
DIV ACCESS,ID=VTOKEN,MODE=UPDATE,SIZE=VSIZEP Open the object
LA R2,2
LTR R15,R15
Error code
ACCESS work ok ?
BNZ LERROR * No -- quit
* If object not empty (VSIZEP > 0), get workarea to hold the object,
* and issue a MAP to it. The area must start on page boundary.
* Referencing byte "n" of this workarea gets byte "n" of the object.
L R2,VSIZEP
SLA R2,12
ST R2,VSIZEB
Current size (in 4K blocks)
Current size (in bytes)
VSIZEB = object size in bytes
BZ LEMPTY If object not empty, get MAP area =
GETMAIN RU,LV=(R2),LOC=(ANY,ANY),BNDRY=PAGE object size
ST R1,VAREAPTR Save MAP area
DIV MAP,ID=VTOKEN,AREA=VAREAPTR,SPAN=VSIZEP
LA R2,3
LTR R15,R15
BNZ LERROR
LEMPTY EQU *
Error code
MAP work ok ?
* No -- quit
Mapped, unless empty
* OPEN the SYSIN input data set, and SYSPRINT listing data set.
* Must be in 24-bit mode for this.
Then return to 31-bit mode.
LA
LA
R4,L31B01
R1,L24B01
Return to L31B01 in 31-bit mode
Go to L24B01 in 24-bit mode
BSM R4,R1 R4 = A(X’80000000’+L31B01)
L24B01 OPEN (VSYSIN,(INPUT),VSYSPRT,(OUTPUT)) OPEN SYSIN/SYSPRINT
BSM 0,R4
L31B01 LA R2,4
Return to 31-bit mode at next instr
Error code from SYSIN OPEN
LTR R15,R15
BNZ LERROR
OPEN ok ?
* No -- quit
Data-in-virtual sample program code (continued)
The program reads statements from SYSIN until it reaches end-of-file, or encounters a statement with an “E” in column 1. The program validates the location in the object to set or display, and branches to the appropriate routine to process the request.
278
z/OS MVS Assembler Services Guide
*
* Loop reading from SYSIN. Process the statements.
* Treat EOF as if the user specified "E" as the function to perform.
*
LREAD EQU *
MVI VCARDF,C’E’
Read first/next card
EOF will appear as "E" function
LA
LA
R4,L31B02
R1,L24B02
BSM R4,R1
L24B02 GET VSYSIN,VCARD
LEOF EQU *
BSM 0,R4
Return to L31B02 in 31-bit mode
Go to L24B02 in 24-bit mode
R4 = A(X’80000000’+L31B02)
Get the next input request.
End-of-file branches here
Return to 31-bit mode at next instr
Get here in 31-bit mode L31B02 EQU *
*
* Process request:
* E
* S aaaaaaaa v
* D aaaaaaaa
*
- End processing
- Set location X’aaaaaaaa’ to v
- Display location X’aaaaaaaa’
CLI VCARDF,C’E’
BE LCLOSE
TRT VCARDA,CTABTRT
BNZ LINVADDV
EOF function or EOF on data set ?
* Yes -- go cleanup and terminate
Ensure A-F, 0-9
* If not, is error
MVC VTEMP8,VCARDA
TR VTEMP8,CTABTR
Save address
Convert to X’0A’-X’0F’, X’00’-X’09’
PACK VCHGADDR(5),VTEMP8(9) Make address
L R1,VCHGADDR Address
LA
ST
R1,0(,R1)
R1,VCHGADDR
CLI VCARDF,C’D’
BE LDISP
CLI VCARDF,C’S’
BNE LINVFUNC
Clear hi-bit
Save address to change/display
Display requested ?
* Yes -- go process
Set requested ?
* No -- is invalid statement
Data-in-virtual sample program code (continued)
For a set request, the program determines whether the location to change does not extend past the maximum object size allowed. If the location is past the end of the current window, the program saves any existing changes to the object, and creates a window containing the page to be changed. It then changes the data in storage
(but not in the linear data set).
For a display request, the program ensures the location to display is in the linear object (that is, within the mapped area).
Chapter 14. Data-in-virtual
279
* SET: See if the location to change is within the range of the current
* MAP. If not, save any changes, get a larger area and issue a new MAP.
C
BL
R1,VSIZEB
LGUPDCHR
Area to change within current MAP?
* Yes -- continue
C R1,CSIZEMX
BNL LINVADDR
CLI VSWUPDT,0
BE LNOSVE1
Area to change within max allowed?
* No -- is error
Any updates to current MAP ?
* Yes -- then
DIV SAVE,ID=VTOKEN
LA R2,5
LTR R15,R15
BNZ LERROR
MVI VSWUPDT,0
LNOSVE1 L R3,VSIZEB
LTR R3,R3
BZ LNOFREE
Save any changes
Error code from SAVE
SAVE ok ?
* No -- quit
Clear update flag
Eliminate old map and storage
Any to free ?
* Yes -- then
DIV UNMAP,ID=VTOKEN,AREA=VAREAPTR Release the MAP
LA R2,6 Error code from UNMAP
LTR R15,R15
BNZ LERROR
UNMAP ok ?
* No -- quit
L R1,VAREAPTR R1 -> acquired storage
FREEMAIN RU,A=(1),LV=(R3) Free the storage
LNOFREE L R2,VCHGADDR
SRL R2,12
Address of byte to change
R2 = page number - 1
LA R2,1(,R2)
ST R2,VSIZEP
SLL R2,12
R2 = page number to use
VSIZEP = MAP area in 4K units
R2 = size in bytes
ST R2,VSIZEB VSIZEB = MAP area in bytes
GETMAIN RU,LV=(R2),LOC=(ANY,ANY),BNDRY=PAGE get MAP area
ST R1,VAREAPTR Save MAP area
DIV MAP,ID=VTOKEN,AREA=VAREAPTR,SPAN=VSIZEP
LA R2,3
LTR R15,R15
BNZ LERROR
LGUPDCHR L R1,VCHGADDR
Error code
MAP work ok ?
* No -- quit
R1 = byte to change
LDISP
A R1,VAREAPTR
MVC 0(1,R1),VCARDV
MVI VSWUPDT,X’FF’
B LGOODINP
EQU *
L R1,VCHGADDR
C R1,VSIZEB
BNL LINVADDR
A R1,VAREAPTR
MVC VCARDV,0(R1)
R1 -> byte to change
Change the byte
Show change made
Go print accept message
Display location contents
R1 = location to display
Ensure within current MAP
* If not, is error
R1 -> location to display
Put into the card
Data-in-virtual sample program code (continued)
For both the set and display requests, the program displays the character at the specified location. For an invalid request, the program displays an error message.
For all requests, the program then goes to process another statement.
When requested to terminate, the program saves any changes in the linear data set, terminates its use of the object (using UNIDENTIFY), and returns to the operating system.
280
z/OS MVS Assembler Services Guide
LGOODINP EQU *
MVC
MVC M1B,VCARDV
CLI
BNE LGOODIN1
MVI
LGOODIN1 LA
B
LINVFUNC LA
B
LINVADDV LA
B
LINVADDR LA
LTELL
L24B03
L31B03
EQU
LA
LA
PUT
B
M1A,VCARDA
M1B,X’00’
M1B,C’?’
R2,M1
LTELL
R2,M2
LTELL
R2,M3
LTELL
R2,M4
*
R4,L31B03
R1,L24B03
BSM R4,R1
VSYSPRT,(R2)
BSM 0,R4
LREAD
Address changed/displayed
Storage value
If X’00’ (untouched),
* change to "?".
*
R2 -> message to print
Go tell user status
Unknown function
Go tell user status
Invalid address
Go tell user status
Address out of range
R2 -> message to print
Return to L31B03 in 31-bit mode
Go to L24B03 in 24-bit mode
R4 = A(X’80000000’+L31B03)
Print the message
Return to 31-bit mode at next instr
Continue
* End-of-file on SYSIN, or "E" function requested.
* Save any changes (DIV SAVE). Then issue UNIDENTIFY, which internally
* issues UNMAP and UNIDENTIFY.
LCLOSE EQU *
CLI VSWUPDT,0
BE LCLOSE1
DIV SAVE,ID=VTOKEN
Any updates outstanding ?
* No -- skip SAVE
Save any changes
LA R2,5
LTR R15,R15
Error code from SAVE
SAVE ok ?
BNZ LERROR * No -- quit
LCLOSE1 DIV UNIDENTIFY,ID=VTOKEN All done with object
LA R2,6
LTR R15,R15
BNZ LERROR
L R13,4(,R13)
Error code from UNIDENTIFY
UNIDENTIFY ok ?
* No -- quit
Unchain save areas and return
LM
SR
R14,R12,12(R13)
R15,R15
BR R14
LERROR ABEND (R2),DUMP
*
*
*
Take a dump
Data-in-virtual sample program code (continued)
These are the program's variables.
Chapter 14. Data-in-virtual
281
R10
R11
R12
R13
R14
R15
R6
R7
R8
R9
R2
R3
R4
R5
* Variables and constants for the program
VSVEAREA DC 18A(0) Save area
VTOKEN DC
VAREAPTR DC
XL8’00’
A(*-*)
Object token
-> MAP area
VSIZEP DC
VSIZEB DC
VSWUPDT DC
VCHGADDR DC
F’0’
F’0’
X’00’
A(*-*),C’ ’
Size of MAP area, in pages (4K)
Size of MAP area, in bytes
X’FF’ -> map area updated
Address of byte to change/display
VTEMP8 DC
VCARD DC
CL8’ ’,C’ ’
CL80’ ’
VCARDF EQU VCARD+0,1
VCARDA EQU VCARD+2,8
Temp area with buffer
Input card
+ Function (E/S/D)
+ Address to change/display
VCARDV EQU VCARD+11,1
CDIVDD DC X’5’,C’DIVDD’
+ Character to change
Linear Data Set DD pointer
* CTABTRT to verify string only has A thru F and 0 thru 9 (hex chars)
CTABTRT DC (C’A’)X’FF’,6X’00’,(C’0’-C’F’-1)X’FF’,10X’00’,6X’FF’
* CTABTR & next line convert chars A:F,0:9 -> X’0A0B...0F000102...09’
CTABTR EQU *-C’A’
DC
CSIZEMX DC
X’0A0B0C0D0E0F’,(C’0’-C’F’)X’00’,X’010203040506070809’
A(4096*1000) Max size allowed for the DIV object
M1
M1A
M1B
M1E
M2
M2E
M3
DC
DC
DC
EQU
DC
Y(M1E-*,0),C’ Location ’
CL8’ ’,C’ contains: ’
C’ ’
*
Y(M2E-*,0),C’ Unknown function (not E/S/D)’
EQU *
DC Y(M3E-*,0),C’ Address not 8 hex characters’
M3E
M4
EQU *
DC Y(M4E-*,0),C’ Address too big to set or display’
M4E EQU *
VSYSIN DCB MACRF=GM,DSORG=PS,RECFM=FB,LRECL=80,DDNAME=SYSIN,
EODAD=LEOF
VSYSPRT DCB MACRF=PM,DSORG=PS,RECFM=VA,LRECL=133,DDNAME=SYSPRINT
R0
R1
EQU
EQU
0
1
Registers
*
EQU 2
EQU 3
EQU 4
EQU 5
EQU 6
EQU 7
EQU 8
EQU 9
EQU 10
EQU 11
EQU 12
EQU 13
EQU 14
EQU 15
END ,
Executing the program
The following JCL executes the program called DIVSAMPL. The function of
DIVSAMPL is to change and display bytes (characters) in the data-in-virtual object,
DIV.SAMPLE, that was allocated in “Creating a linear data set” on page 259.
282
z/OS MVS Assembler Services Guide
//DIV JOB .....
//DIV EXEC PGM=DIVSAMPL
//STEPLIB DD DISP=SHR,DSN=DIV.LOAD
//DIVDD DD DISP=OLD,DSN=DIV.SAMPLE
//SYSABEND DD SYSOUT=*
//SYSPRINT DD SYSOUT=*
//SYSIN DD *
S 00001000 A Changes byte X’1000’ to "A"
D 00000F00 Displays "?" since byte X’F00’ contains X’00’
S 00000F00 B Changes byte X’F00’ to "B"
S 00010000 C Saves previous changes, gets new map, changes byte X’10000’
D 00001000 Displays "A" which was set by first statement
D 00000F00 Displays "B" which was set by third statement
E
/*
Saves changes since last save (stmt 4), and terminates pgm
DIVSAMPL reads statements from SYSIN that tell the program what to do. The format of each statement is f aaaaaaaa v, where:
f
Function to perform:
S
Set a character in the object.
D
E
Display a character in the object.
End the program.
aaaaaaaa
The hexadecimal address of the storage to set or display. Leading 0s are required. The value must be less than X'003E8000'.
v
For Set, the character to put into the object.
Note:
The program actually saves the change requested by the S function when either the user asks to change a byte past the current size of the object, or the user asks to terminate the program (E function).
Chapter 14. Data-in-virtual
283
284
z/OS MVS Assembler Services Guide
Descarcă
Publicitate