MainframeSupports
tip uge 28/2005:

Der findes et hav af forskellige MVS services, der kan gøre livet lettere for os mainframe tosser. Desværre skal de stort set allesammen kaldes fra assembler og det reducerer deres brugbarhed betragteligt for de fleste af os inklusive mig. En kollega gjorde mig for nylig opmærksom på den såkaldte name/token MVS service og til min store overraskelse fandt jeg ud af, at den kan kaldes direkte fra COBOL, PL/1 og REXX og andre sprog, hvorfra man kan kalde moduler, der overholder standard linkage konventionerne.

Name/token servicen gør dig i stand til at lave små globale variable på tværs af næsten alting. MVS'en administrerer dine variable og du skal bare sørge for at give din variabel et unikt navn. Det minder ret meget om ISPF pool variable. Name/token servicen opererer med to typer variable, task (TCB) relaterede variable og address space relaterede variable. Task relaterede variable lever så længe dit task lever, mens address space relaterede variable lever, så længe dit address space lever. Afhængigt af dit behov skal du vælge een af disse to typer. Vær opmærksom på, at CICS har sin helt egen definition af task, som ikke har noget med MVS at gøre. Derfor vil jeg fraråde dig at benytte name/token servicen under CICS, selvom den faktisk virker uden problemer.

Og hvordan bruger man så name/token servicen? Her er et eksempel i PL/1:

DCL ntType fixed bin(31);
DCL ntName char(16);
DCL ntToken char(16);
DCL ntLife fixed bin(31);
DCL ntRC fixed bin(31);
DCL ieantcr EXT ENTRY OPTIONS(ASM);
DCL ieantrt EXT ENTRY OPTIONS(ASM);
DCL ieantdl EXT ENTRY OPTIONS(ASM);

ntType = 1;
ntLife = 0;
ntName = 'MYMVSVARIABLE';
ntToken = 'KILROY WAS HERE';
CALL ieantcr(ntType, ntName, ntToken, ntLife, ntRC);
if ntRC = 0
then do;
  put skip list(ntname !! ' created');
  ntToken = '';
  CALL ieantrt(ntType, ntName, ntToken, ntRC);
  if ntRC = 0
  then do;
    put skip list(ntname !! ' = ' !! ntToken);
    CALL ieantdl(ntType, ntName, ntRC);
    if ntRC = 0
    then
      put skip list(ntname !! ' deleted');
  end;
end;

Jeg håber, at de af jer, der koder COBOL, REXX eller andet er i stand til at oversætte ovenstående, ellers må I kontakte mig.

Variablen ntType sættes til 1 for task relaterede variable og 2 for address space relaterede variable. Variablen ntName sættes til et unikt navn, som ingen andre i task'et eller address spacet benytter. Hold dig fra navne, der begynder med 'A' til 'I' og hex '00', da de er reserveret af MVS. Jeg benytter typisk programnavnet i de første 8 tegn og noget sigende i de næste 8. Variablen ntToken sættes så til den værdi, variablen skal have. Der er kun 16 bytes til rådighed, så hvis du har behov for at gemme mere, så må du finde på andre metoder. Variablen ntLife skal altid være 0. Variablen ntRC sættes af service kaldet til 0, når kaldet går godt og til 4, når ntName ikke findes eller findes i forvejen.

Servicekaldet IEANTCR opretter en variabel med navnet i ntName og værdien i ntToken. IEANTRT kopierer værdien af variablen i ntName over i ntToken. IEANTDL sletter variablen i ntName.

En metode til at gemme mere end 16 bytes vha. et enkelt token er at gemme en pointer til et areal, der indeholder de interessante data. Denne metode duer typisk kun for task relaterede variable, da arealer tilknyttet programmer har det med at forsvinde, når det task, programmet afvikles under, forsvinder. Derfor kan det være svært at lave globale variable med mere end 16 bytes information, der er address space relaterede. Det kræver nemlig, at man allokerer storage, som ikke frigives, når task'et terminerer.

Forrige danske tip        Last tip in english        Tip oversigten