Answer to question 25

The question is related to following procedures:


2 procedures manipulating program stack.
 /* Procedure A */            |  /* Procedure B */
 address command              |  address command
 oldqueue=queued()            |  parse pull fn ft fm .
                              |  'MAKEBUF'
 'MAKEBUF'                    |  'IDENTIFY (STACK'
 'LISTFILE PROFILE * (STACK'  |  parse pull userid . nodeid .
 do queued()-oldqueue         |  'QUERY DISK R/W (STACK'
    parse pull fileid         |  pull .      /* get rid of header */
    'EXEC B' fileid           |  parse pull . . FirstRWMode .
 end                          |  if ft=userid then exit
 'DROPBUF'                    |  ...        /* process file */
 exit                         |  'DROPBUF'
                              |  exit

If the lines stacked by the LISTFILE command are in the order as listed in the description of the exercise, then this is what happens (suppose there are no records in the stack when A is started):

  1. Procedure A pulls the first line of the stack (PROFILE your-id) and decrements the DO-counter from 3 (queued()-oldqueue) to 2.
  2. Procedure B gets called
  3. Procedure B stacks the user identity (IDENTIFY)
  4. Procedure B pulls the record from the stack.  Note that due to the MAKEBUF the correct identity record is pulled from the just created buffer.  Without a MAKEBUF, the next fileid stacked by procedure A would be pulled, and the identity record would be left on the stack.
  5. Procedure B stacks all disks with R/W attribute.
  6. The header of the QUERY DISK is pulled from the stack.
  7. The first R/W disk is pulled from the stack.  Same remark as above, the correct record gets pulled due to the MAKEBUF.
  8. Procedure B detects that the filetype corresponds to your-id, and exits.

We have now following records on the stack

   Buffer 2 : DISK-B 193  B   R/W    17 3390 4096  ...
   Buffer 1 : PROFILE  EXEC     A1
              PROFILE  XEDIT    A1

Procedure A now pulls the first of these records from the stack, decrements the DO-counter to 1, and calls procedure B again with parameters DISK-B 193 B R/W...

Procedure B creates a new stack buffer (3) and now no longer brutally exits (but probably has problems with the strange input) and exits after it drops buffer 3.  We then have on the stack:

Buffer 2 : ----empty----             (has never been dropped)
Buffer 1 : PROFILE  EXEC     A1
           PROFILE  XEDIT    A1

The DO of procedure A has one more iteration to go and issues a read to the stack.

And this is where we too, have learned something !

From the description of MAKEBUF:

When reading a line from the most recently created buffer, if this buffer is empty, it will be dropped and the line will be read from the next buffer (or terminal). 

So, the pull in procedure A provokes a DROPBUF 2 and A reads PROFILE EXEC from buffer 1.  Then, procedure B runs (creates and drops a new buffer 2) and exits properly.

The DO-counter is now at zero, though there is still one record on the stack.  This gets cleared by the DROPBUF of procedure A.

Conclusions:

  1. The correct answer to the question was: 4-none of above.
  2. If there were three R/W disks, procedure B would have left one line more in the stack and buffer 2 would not be empty.  In this case the last DROPBUF of procedure A would clear buffer 2 and not its own buffer 1, and thus, records would remain in the stack, after the exit of procedure A.  Now CMS has trouble executing the lines in the stack...
  3. Even with what we learned above, the general rule whereby MAKEBUF and DROPBUF should be paired remains very important !

Use backward navigation to return to the lesson text.