Discussion:
Simple RPG questions about RETRN
(too old to reply)
ga
2007-01-18 20:24:22 UTC
Permalink
I have some questions regarding "RETRN" coding in an RPG/400 program.

I have a PROGRAM that calls either PROGRAMA or PROGRAMB

Both PROGRAMA and PROGRAMB may call PROGRAMC with 4 variables, IMMI,
IMP#, IMD1 and IMD2.

PROGRAMC opens a very large file (1.6gb) and maintains an index.
Right now PROGRAMC ends with "seton LR". I would like to change that
to "RETRN" to avoid the opening/closing file overhead because on one
screen in PROGRAMB, it might call PROGRAMC 24 times. Opening and
closing the file each time has to be a lot of overhead.

Questions:

1. Assuming I call PROGRAMC from PROGRAMB, and I "RETRN" at the end
of my logic in PROGRAMC, when I call PROGRAMC again from PROGRAMB does
it reinitialize the parms I pass on the subsequent call . For
instance, the first time I Call it, IMMI, IMP#, IMD1 and IMD2 are all
different than the second time I call it. I want to make sure it uses
the new values on the subsequent call. On the subsequent call, does
it start at the *ENTRY PLIST point or at "RETRN"?

2. When does PROGRAMC truly end? When I end PROGRAMA or PROGRAMB
will it close the files used by PROGRAMC and end PROGRAMC as well?

3. If PROGRAMB calls PROGRAMD, which also calls PROGRAMC, is that a
problem?

4. Assuming PROGRAM calls PROGRAMA and then the next time calls
PROGRAMB, do each of the programs have a separate version of PROGRAMC
in memory that they are using? If other users call PROGRAMC from
another program, I assume they have their own separate version of
PROGRAMC and variables as well?

The limited testing I've done would indicate that each subsequent call
does in fact start at the *ENTRY PLIST Point and processes the new
values in the parms. It also appears that if I close PROGRAMB or
PROGRAMA, it closes the version of PROGRAMC it is using along with the
files. Am I missing something or is this essentially the way it
works?

thanks!


George Applegate
***@fscoop.com
Saml
2007-01-19 01:29:17 UTC
Permalink
You ask many things, grasshopper. I believe I have answered them correctly
and if not, I'm sure someone else will step in and correct me. (Barbara
Morris come to mind...)

I assume you are leaving LR off when you return from ProgramC. If so, that
will leave all the files open and when you next enter it the files will not
need to be reopened, saving considerable overhead. If you have an *INZSR
subroutine it will not be invoked. No initialization of variable will be
done, so largely your program will be as you left it. Yes, *ENTRY PLIST
will receive the new parameter values.

ProgramC will go away, and its files will be closed, when the first program
that called it returns with LR on.

Under the scenario you mentioned, for a job there is only one verision of
ProgramC. Another job would have another versions of ProgramC. Remember,
and interactive session is a job.

This applies to OPM model programs, which I'm assuming you are using since
you mentioned RPG/400. Things changes if you go to ILE.

Sam
Post by ga
I have some questions regarding "RETRN" coding in an RPG/400 program.
I have a PROGRAM that calls either PROGRAMA or PROGRAMB
Both PROGRAMA and PROGRAMB may call PROGRAMC with 4 variables, IMMI,
IMP#, IMD1 and IMD2.
PROGRAMC opens a very large file (1.6gb) and maintains an index.
Right now PROGRAMC ends with "seton LR". I would like to change that
to "RETRN" to avoid the opening/closing file overhead because on one
screen in PROGRAMB, it might call PROGRAMC 24 times. Opening and
closing the file each time has to be a lot of overhead.
1. Assuming I call PROGRAMC from PROGRAMB, and I "RETRN" at the end
of my logic in PROGRAMC, when I call PROGRAMC again from PROGRAMB does
it reinitialize the parms I pass on the subsequent call . For
instance, the first time I Call it, IMMI, IMP#, IMD1 and IMD2 are all
different than the second time I call it. I want to make sure it uses
the new values on the subsequent call. On the subsequent call, does
it start at the *ENTRY PLIST point or at "RETRN"?
2. When does PROGRAMC truly end? When I end PROGRAMA or PROGRAMB
will it close the files used by PROGRAMC and end PROGRAMC as well?
3. If PROGRAMB calls PROGRAMD, which also calls PROGRAMC, is that a
problem?
4. Assuming PROGRAM calls PROGRAMA and then the next time calls
PROGRAMB, do each of the programs have a separate version of PROGRAMC
in memory that they are using? If other users call PROGRAMC from
another program, I assume they have their own separate version of
PROGRAMC and variables as well?
The limited testing I've done would indicate that each subsequent call
does in fact start at the *ENTRY PLIST Point and processes the new
values in the parms. It also appears that if I close PROGRAMB or
PROGRAMA, it closes the version of PROGRAMC it is using along with the
files. Am I missing something or is this essentially the way it
works?
thanks!
George Applegate
Barbara Morris
2007-01-19 20:17:55 UTC
Permalink
Post by Saml
ProgramC will go away, and its files will be closed, when the first program
that called it returns with LR on.
Everything else you said is correct, but ProgramC staying active doesn't
depend on the state of its callers. ProgramC will remain active until
it sets on LR. RCLRSC could also make it go away, but that would depend
on the call level.

See the programs below.
If I call PGM1 twice, then PGM2 displays the following. The variable
NUM in PGM2 keeps incrementing 1 2 3 4, even though its calling program
returned with LR on.
===> call PGM1
DSPLY call 1
DSPLY 1
DSPLY call 2
DSPLY 1
===> call PGM1
DSPLY call 1
DSPLY 3
DSPLY call 2
DSPLY 4
At this point, DSPJOB OPTION(*OPNF) shows that TESTFILE is open.

PGM1:
C CALL 'PGM2'
C PARM 'call 1' PARM 10
C CALL 'PGM2'
C PARM 'call 2' PARM 10
C SETON LR

PGM2:
FTESTFILEIF E DISK
C *ENTRY PLIST
C PARM MSG 10
C READ TESTFILE 10
C MSG DSPLY
C ADD 1 NUM 50
C NUM DSPLY
C RETRN
ga
2007-01-19 22:06:44 UTC
Permalink
Barbara (and everyone else who replied)

Thanks for taking the time to help me understand this better. The
example you provided showed me exactly how this works and was very
helpful.

I do have one follow-up question which maybe you will know:

I have some rpg/400 programs that are run under the s/36 environment.
Will they behave differently with your example below? The reason I
ask is that usually, in S/36E, you select an option on a menu which
calls an OCL procedure. I think perhaps when running under S/36E IBM
does some stuff "automagically"??

Yesterday when I was testing, using your example, I actually called
PGM0 in the S/36 OCL procedure (yes I am getting rid of S/36 too, but
that's another story). Anyway, PGM0 called PGM1, which called PGM2.
To verify what you said, when PGM1 ended and returned to PGM0, with
INLR on, it didn't matter, PGM2 files were still open as you show
below. However, when PGM0 ended and the job returned to the menu, now
the files were all closed. I am curious if in the S/36 procedure, if
I had not returned to a menu, but did some more steps in the called
procedure (not to be confused with an ILE procedure), if those files
would remain open. I am wondering if S/36E handles the program any
differently with the open files...I tested this just now and this is
what I found:

Once that original program, PGM0, concludes in the S/36 OCL it then
has closed the files opened under PGM2. even though there might be
more job steps in the OCL. Is that the way it always works in rpg -
when the very first caller program ends, then the files are closed??
Or is this something unique to S/36 OCL?

I guess I really don't need to know the definitive answer here, just
kind of curious.

I guess the question is this, if not in S/36E, if I just did "Call
PGM0" from a command line, when PGM0 ended, would the files be open or
not. Is there a difference bewteen S/36E and non-S36E. Because once
PGM0 - the first level program was ended under S/36E, the files did in
fact close.

thanks again,
ga
Post by Barbara Morris
Post by Saml
ProgramC will go away, and its files will be closed, when the first program
that called it returns with LR on.
Everything else you said is correct, but ProgramC staying active doesn't
depend on the state of its callers. ProgramC will remain active until
it sets on LR. RCLRSC could also make it go away, but that would depend
on the call level.
See the programs below.
If I call PGM1 twice, then PGM2 displays the following. The variable
NUM in PGM2 keeps incrementing 1 2 3 4, even though its calling program
returned with LR on.
===> call PGM1
DSPLY call 1
DSPLY 1
DSPLY call 2
DSPLY 1
===> call PGM1
DSPLY call 1
DSPLY 3
DSPLY call 2
DSPLY 4
At this point, DSPJOB OPTION(*OPNF) shows that TESTFILE is open.
C CALL 'PGM2'
C PARM 'call 1' PARM 10
C CALL 'PGM2'
C PARM 'call 2' PARM 10
C SETON LR
FTESTFILEIF E DISK
C *ENTRY PLIST
C PARM MSG 10
C READ TESTFILE 10
C MSG DSPLY
C ADD 1 NUM 50
C NUM DSPLY
C RETRN
ga
***@nospam.fmctc.com
Barbara Morris
2007-01-22 16:07:31 UTC
Permalink
Post by ga
I have some rpg/400 programs that are run under the s/36 environment.
Will they behave differently with your example below? The reason I
ask is that usually, in S/36E, you select an option on a menu which
calls an OCL procedure. I think perhaps when running under S/36E IBM
does some stuff "automagically"??
Interesting. I started S36 and when I just call PGM0 from the command
line, the file remains open. But if I //LOAD //RUN PGM0, the file gets
closed. It looks like running an S36 procedure does a reclaim resource
when the procedure ends.

There may be some way to define the file using the //FILE proc that will
prevent the file from being closed. I'm not familiar enough with //FILE
to know.

This manual
http://publib.boulder.ibm.com/infocenter/iseries/v5r3/topic/books/sc414730.pdf
discusses the closing of files in detail. From skimming it, it looks
like the exact behaviour might depend on the type of file.

GB
2007-01-19 05:53:59 UTC
Permalink
Post by ga
PROGRAMC opens a very large file (1.6gb) and maintains an index.
Right now PROGRAMC ends with "seton LR". I would like to change that
to "RETRN" to avoid the opening/closing file overhead because on one
screen in PROGRAMB, it might call PROGRAMC 24 times. Opening and
closing the file each time has to be a lot of overhead.
Good idea - BTW the size of the file is largely irrelevant in this scenario.
Post by ga
1. Assuming I call PROGRAMC from PROGRAMB, and I "RETRN" at the end
of my logic in PROGRAMC, when I call PROGRAMC again from PROGRAMB does
it reinitialize the parms I pass on the subsequent call . For
instance, the first time I Call it, IMMI, IMP#, IMD1 and IMD2 are all
different than the second time I call it. I want to make sure it uses
the new values on the subsequent call. On the subsequent call, does
it start at the *ENTRY PLIST point or at "RETRN"?
The called program "fetches" the values of the parameters as part of the
processing - you can think of it occurring just before the top of the C
specs - which is where processing will commence during each call.
Post by ga
2. When does PROGRAMC truly end? When I end PROGRAMA or PROGRAMB
will it close the files used by PROGRAMC and end PROGRAMC as well?
Er, no. Program C will stay open in the stack (and its files) until you
explicitly close it during a CALL or by executing a RCLRSC command.

If A calls C repeatedly, then you can pass a parameter to C to request
it to SETON LR and RETRN as part of shutting down A. With the more
complex logic you describe it won't easily be possible to know when
program C is to be shut down. The alternative of issuing a RCLRSC after
exiting the main program will clear *any* unclosed programs and files...
Post by ga
3. If PROGRAMB calls PROGRAMD, which also calls PROGRAMC, is that a
problem?
Not necessarily - RPG doesn't like recursive calls e.g. A calls B, calls
C calls B - or A calls B calls A i.e. twice in the same stack.
Post by ga
4. Assuming PROGRAM calls PROGRAMA and then the next time calls
PROGRAMB, do each of the programs have a separate version of PROGRAMC
in memory that they are using? If other users call PROGRAMC from
another program, I assume they have their own separate version of
PROGRAMC and variables as well?
There is only ever one copy of the OBJECT CODE in memory for an AS/400
program - regardless of how many jobs/users there are. Each job using
the programs as described has a copy of the DATA/VARIABLES. This data is
unchanged on second and subsequent calls (IN THE SAME JOB) so you might
need to put some initialisation code at the top of the C specs.
Post by ga
The limited testing I've done would indicate that each subsequent call
does in fact start at the *ENTRY PLIST Point and processes the new
values in the parms. It also appears that if I close PROGRAMB or
PROGRAMA, it closes the version of PROGRAMC it is using along with the
files. Am I missing something or is this essentially the way it
works?
Er, no. Program C will stay open in the stack (and its files) until you
close it. Other than that, you are correct!

HTH

GB

P.S. The above is true for OPM pgms, ILE has a few other considerations,
but my gut feel is that you are coding good old OPM.
Loading...