|
There is a field in the CVT (Contents Vector Table) control block that can be used to point to a user defined area (CVTUSER). Under normal circumstances this field contains binary zeros, however, it can be used to
point to a user area that you can use to hold system wide user information. It should be noted that this area needs to be recreated after an IPL.
So what can this area be used for, and how do you use it?
The area can basically be used for anything, but in practice it should only be used to information that needs to be saved system wide for other programs or functions that can't be achieved by other means. For example in
the past it was used to maintain a table of cartridges that were used by a drive with hoppers to help indicate to the operator that a cartridge may still be in a drive hopper.
With the technology advancements this is probably no longer required. Indeed many of the past uses of a user CVT have been superseded by automation products, however, if you don't have any automation products it can still be an option.
In the past it has been used for many things like preventing run away jobs, runaway RJE lines etc., the setting system wide flags etc.
In truth there are not many reasons to still use a user CVT, but it is fun to play around with the possibilities.
Remember that any storage obtained by your user CVT will have to be able to be addressed by programs using it.
In other words if a program that uses the your USER CVT is 24 bit addressed then the corresponding address stored in your user CVT must be 24 bit.
The recommendation for a user CVT is that it points to an area (it really has to as it is only a fullword (4 bytes) long). The address should then point to your own area
that is a table of more addresses (as many as needed but we always leave room for expansion). Another recommendation is that the user CVT gets created as soon as possible after an IPL. We use a Message Processing Exit to create the USER CVT anchor.
So that is the why, now onto the how.
The usual disclaimers apply to all our code samples (including the MACROs).
Please, please do not implement any system changes without the full involvement of your site System Programmer.
Always take a backup before starting and please, if you don't understand the details and process described below, don't do it!
|
Step 1 : Decide on the Structure of Your User CVT. |
|
|
* This DSECT defines the fields that are in the area
* pointed to by the CVTUSER field in the system CVT.
*
* To ENQUEUE on this table specify:
USERCVTQ DC CL8'USERCVT' -- QNAME
USERCVTR DC C'USERCVT.TABLE' -- RNAME
*
* You must enqueue with the options "EXCLUSIVE,SYSTEMS"
* for updating and with the options "SHARED,SYSTEMS"
* for reading.
*
USERCVT DSECT
CSAEYECT DS D Eyecatcher location
TAPESTKR DS A Address of tape stacker area
USERCVTS DS A Address of USERCVT work area
DS 3D Reserved for future expansion
SPACE 1
USERCVTL EQU (((*-USERCVT)/8)+1)*8 Length of the USER CVT area |
The mapping DSECT for a user CVT isn't actually required as such, but it does help prevent confusion
and programs using the incorrect area and messing up other functions.
Notice that we have defined a 6 fullword expansion area, which is way more than we would ever need but
has plenty of extra room. You can change this to whatever suits your needs. An expansion area means that you don't need to
rebuild the user CVT to add function.
There are two functions that were using the user CVT area. These were for:
- TAPESTKR: Display which drive a cartridge (or tape) was last used on.
- HASPLINE: Cancel a runaway job producing too much output.
Map your area out according to your own requirements.
A copy of our USERCVT macro is available from here.
|
|
|
|
|
|
Define and Anchor Your User CVT Table |
|
|
START DS 0H Start of program
R8,CVTPTR Get CVT Pointer ...
USING CVT,R8 ... and establish addressability
L R9,CVTUSER Get the CVTUSER field
LTR R9,R9 Do we already have one created?
BNZ EXIT Yes - Skip to exit
STORAGE OBTAIN,LENGTH=USERCVTL,ADDR=(R11),LOC=ANY, X
RELATED=GETCSA,SP=241
USING USERCVT,R11 Establish addressability
MVC CSAEYECT,=C'MPFEUCVT' Set up table eyecatcher
CS R9,R11,CVTUSER Use CS to update CVT
BE Looks_Good Did it work? Yes - Skip
|
Once you have mapped the layout of your user CVT the next step is to write and assemble the program to build your CVT control block and anchor its address into the
operating system's CVT field, CVTUSER.
It is up to the individual site to decide when is the best time to build the user CVT but it is normally done
as close to the IPL as possible. We chose to have a message processing exit do this when a certain message is displayed.
This message should really be a unique message and the exit should really check for an existing CVTUSER value (just in case).
The code snippet alongside is just an example of how to check for an existing user CVT control block.
A full working copy of a MPF exit that will create and anchor a user CVT is available from here.
|
|
|
|
|
|
Using Your User CVT Table |
|
|
L R8,CVTPTR Get CVT Pointer and ...
USING CVT,R8 ... establish addressability to CVT
L R9,CVTUSER USERCVT address into R9
LTR R9,R9 Is there a USERCVT?
BNZ GOOD_TO_GO No - Go and do something about it.
WTO 'ASLUSR1E - NO USER CVT. USERCVTS'
B EXIT Go and exit
USING USERCVT,R9 Establish Addressabilty to USERCVT
L R10,USERCVTS Get address of our CVT
LTR R10,R10 Is it there?
BZ GETMAIN No - Go and build it
USING CSATABLE,R10 Addressabilty to our USERCVT
CLC =C'USERCVTS',CSAEYECC Is it really ours?
BE GOOD_TO_GO Yes - Keep going
WTO 'ASLUSR2E - INCORRECT CVT ENTRY USERCVTS'
B EXIT Go and exit
GETMAIN DS 0H
STORAGE OBTAIN,LENGTH=192,ADDR=(R10),LOC=ANY, X
RELATED=GETCSA,SP=241
MVC CSAEYECC,=C'USERCVTS' Move in eyecatcher
XR R2,R2 Clear R2
CS R2,R10,USERCVTS Save it into CSA
BE KEEPON Yes - Keep going
WTO 'ASLUSR3E - BEATEN TO IT. USERCVTS'
B EXIT Go and exit
GOOD_TO_GO DS 0H
|
Now that you have your 'anchor' in the CVT the next step is to start to use it.
How you want to use this is entirely up
to your own site requirements and, in truth, there is very little need to use it these days. Automation products and advancements in both
hardware and software have all but removed the need to use a user CVT, but you may think of some use for it.
In this example we will only show the bare bones of an old use of the user CVT.
Any system that build a user CVT should always ensure that the programs check to see if a user CVT has already been established for the system and
deal with that situation accordingly. You also need to consider what to do if the addresses or storage areas get corrupted.
In any event
an invalid or corrupted user CVT is not going to affect the integrity of the system.
The code alongside shows how to check if your usercvt is already created or not. If it isn't, the program creates it. If it is already existing, the program uses it.
We have provided a sample program (USERCVTS) which demonstrates how to use a user CVT.
The code is available from here.
The code is provided purely as an example of how to use the user CVT. You should carefully consider the implication to your site before running the code. It is designed to
be an MPF exit that gets called when an RJE line issues error messages. |
|
|
|