tirsdag den 25. august 2015

At blive reentable

I den seneste blog skrev jeg sidst i artiklen “Det er altså op til programmøren, at styre ændringerne i modulets kode eller værdier”. Jeg vil nu vise, hvordan det gøres. Vi skal opnå, at intet i programmet bliver ændret. Det betyder, at alle variable skal ligge i storage, som tilhører den enkelte process uden for programmet; vi skal altså lave en såkaldt Getmain, - altså hente main storage.

        GETMAIN RC,LV=STOR_LGD
        OR      R1,R1
        BZ      NO_STORAGE_OBTAINED
        LR      R10,R1
        USING   STORAGE,R10
        MVC     EC,=CL(L’EC)’PGM2-STORAGE’

Et sted i programmet, uden for kontrolsektionen (CSECTen, den med instruktioner), lægger du en DSECT, der beskriver dit arbejdsareal.
STORAGE  DSECT
EC       DS CL16 EYE CATCHER
VALUE1   DS F
VALUE2   DS H
VALUE3   CL120
VALUE4   DS F
STOR_LGD EQU *-STORAGE

Du starter altså med at getmaine arealet med en længde, som er beregnet af sidste instruktion i DSECT’en. Derefter tjekker du, om der er en adresse i Register 1 (R1) med OR-instruktionen. Hvis ikke, så går du til fejlrutinen NO_STORAGE_OBTAINED. I næste instruktion flytter du adressen over i R10 og siger derefter, at når du refererer til felterne i dette storage, så skal R10 bruges. Til sidst flytter du en såkaldt Eye Catcher forrest i arealet. Det er rart, hvis programmet skulle dumpe sit storage. Så kan du lave en “Find” på Eye Catcheren, for at finde arealet.

DSECT’en beskriver udseenet af dit areal. Den starter med DSECT og navnet på denne DSECT, så du kan referere til den i USING. Derefter kommet dine variable og til sidst beregnes arealets længde. Så er vi kørende….

Linkage Conventions
Eller, det vil sige, - det var den nemme del. Der kommer meget mere, men lige nu tager vi lige endnu en Getmain, som skal komme allerførst i programmet. Det skal bruges, hvis vi kalder andre programmer, så disse kan gemme vore registre (R14 til R12), så den kan genetablere dem inden den vender tilbage til os. I andre oprerativsystemer kalder man det at putte på stakken og hente fra stakken. I z/OS kaldes det, at overholde Linkage Conventions
Vi er jo imidlertid jo selv et program, der er kaldt, - måske af operativsystemet, måske af et andet program. Vi skal derfor gemme kalderens registre. Heldigvis findes der en Macro til det:
          SAVE  (14,12),,'PGM2 - &SYSDATE..&SYSTIME'
Det sidste er en kommentar, som fortæller programnavnet (PGM2) og programmets assembleringstidspunkt. Det skal ikke bare anbefales, men kræves, at du bruger det!. Det hjælper i uhyre mange tilfælde til at sikre, at vi har fat i den rigtige version af programmet i en fejlfindingssituation.

Efter at have gemt kalderens registre, skal vi have et storageareal til vore registre, hvis vi skulle finde på at kalde et andet program.
RSA      GETMAIN RC,LV=72
         OR      R1,R1
         BZ      NO_STORAGE_OBTAINED
         ST      R1,8(,R13)
         ST      R13,4(,R1)
         LR      R13,R1
         USING   SA,R13

SA       DSECT
SAVEAREA DS      18F
Vi henter 72 bytes, svarende til 18 fuldord (18F). Det er alt vi skal bruge.
De to Storeinstruktioner (ST) laver en sammenkædning af registersavearealerne og til sidste lader vi R13 pege på vort Register Save Area og skaber adressability til det med USING.
Lige inden vi forlader programmet skal vi genetablere kalderens registre. Det gøres således:
         L       R13,SAVEAREA+4
         LM      R14,R12,12(R13)
         RETURN  RC=0
Først skal R13 peger på kalderens Registe Save Area. Derefter hentes alle registre fra dette areal, - undtagen R13 selvfølgelig. Til slut returnerer vi til kalderen.
Dit program er fuldt reentable og kan lægges i Link Pack Area (LPA). Det er et ReadOnly-areal, som er tilgængeligt for alle address spaces (regioner). Det kan også bruges samtidig at flere tasks/threads.
I næste artikel skal vi snakke om at kalde andre programmer, hvis du stadig vil have dit program til at være reentable. Det er ikke så lige til, som det lyder.
Læsestof:

Ingen kommentarer:

Send en kommentar