J3/97-216r2 page 1 of 16 To: X3J3 From: JOR (Bleikamp) Subject: Syntax and Edits for Async I/O Date: Aug 25, 1997 | Issues resolved in this revision: | - changed READ/WRITE statements ASYNCHRONOUS specifer | to ASYNCHRONOUS="YES|NO" form, to avoid ambiguity. | | - scrapped old text about what variables could not be | defined, referenced, passed as actual arg, etc., due | to problems describing which variables the restrictions | applied to. Replaced this with a new term, the | "pending I/O storage sequence", a NON-contiguous collection | of storage units, the actual memory being referenced by the | I/O list items. | | Also added a new term, "pending I/O storage sequence | AFFECTOR". An affector variable is a | variable in a scoping unit where at least one | executable statement | was executed while the I/O operation is pending, and any | "use" of a variable in that scoping unit (if it had been | executed, due to optimizater hoisting the "use" of the | variable), would have referenced or defined any storage | unit in the pending I/O storage sequence. Remaining issues: | - Finish the edits for affector variables, and prohibiting | copyin/copyout procedure calls of affector variables while | the pending I/O is active. "Notes to the reader" are not notes to be included in the standard. Text to be included in the standard is either "quoted" or indented. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: Non-normative NOTES to be included in the standard are delimited by dashed lines. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - J3/97-216r2 page 2 of 16 Edits to 96-007R1: In rule R214 (specification-stmt), add: or asynchronous-stmt In rule R426 (component-attr-spec), add: or ASYNCHRONOUS In rule R503 (attr-spec), add: or ASYNCHRONOUS and add a new section (page 57): 5.1.2.12 ASYNCHRONOUS attribute | All variables which are pending I/O storage sequence affectors | (9.4.1.10) shall have the ASYNCHRONOUS attribute in a scoping | unit in which they appear, if: | 1) they appear in an executable statement or in a | specification expression, and | 2) any executable statement in that scoping unit is executed | while an asynchronous data transfer operation is pending. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: the ASYNCHRONOUS attribute helps a processor determine which variables are associated with a pending I/O storage sequence (the actual memory locations to which asynchronous I/O is being performed). This information is used to disable certain code motion optimizations. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this following block is no longer part of the edits A variable that : 1) appears in an asynchronous data transfer statement input/output list, or 2) is in a namelist group that is used in an asynchronous data transfer statement, and is read or written by that data transfer statement, or 3) is specified in a SIZE= specifier in an asynchronous data transfer statement and all variables associated, via argument or sequence association, with such a variable shall have the ASYNCHRONOUS attribute, or shall be a subobject of an object with the ASYNCHRONOUS attribute, in a given scoping unit, if : 1) the variable is referenced, defined, or used as an actual argument in a scoping unit other than the scoping unit containing the asynchronous data transfer statement, and 2) any executable statement in such a scoping unit might be executed while the asynchronous data transfer operation is pending. J3/97-216r2 page 3 of 16 - - - - - - this preceeding block is no longer part of the edits If a variable with the ASYNCHRONOUS attribute (implicitly or explicitly) is passed as an actual argument, the corresponding dummy argument shall have the ASYNCHRONOUS attribute. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: A data transfer operation is pending when a READ or WRITE statement with an ASYNCHRONOUS= specifier with a value of YES has been executed, but the corresponding wait operation has not yet been executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - The ASYNCHRONOUS attribute may be specified for any variable, whether or not that variable appears in an asynchronous data transfer statement. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: Any variable is permitted to have the asynchronous attribute so users can remove ASYNCHRONOUS= specifiers from data transfer statements, or change the value of ASYNCHRONOUS= specifers to NO, without having to remove the ASYNCHRONOUS attribute from variables used in the asynchronous I/O lists. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: The ASYNCHRONOUS attribute is similar to the VOLATILE attribute provided by some processors, and is intended to facilitate traditional code motion optimizations in the presence of asynchronous input/output. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Add a new section, 5.2.10 (and renumber 5.2.10 and later sections): | 5.2.10 ASYNCHRONOUS statement R5xx asynchronous-stmt is ASYNCHRONOUS [::] The ASYNCHRONOUS statement specifes the ASYNCHRONOUS attribute for a list of objects. In rule R905 (OPEN statement connect-spec), add, after PAD= (on its own line)(pg. 140): or ASYNCHRONOUS = J3/97-216r2 page 4 of 16 Add section 9.3.4.11 (page 142/143): 9.3.4.11 ASYNCHRONOUS= specifier in the OPEN statement The shall evaluate to | YES or NO. If an ASYNCHRONOUS= specifier with a value of YES | is specified, then READ and WRITE statements for the opened unit | may include an ASYNCHRONOUS= specifier with a value of YES in | the control information list. An ASYNCHRONOUS= specifier with | a value of NO is always permitted in READ and WRITE statements. | The presence of an ASYNCHRONOUS= specifier with a value of | YES in a READ or WRITE statement permits, but does not require, a processor to perform the data transfer asynchronously. The WAIT, CLOSE, and file positioning | statements may be used to wait for pending asynchronous data transfer operations to complete, and the INQUIRE statement may | be used to inquire whether or not pending asynchronous data transfer operations have completed. Note to the reader: the above rules imply only external unit input / output (not including the "*" unit) may specify an ASYNCHRONOUS= specifier for READs and WRITEs, since internal files and the "*" external unit are not OPENed. In section 9.3.5 (CLOSE statement), page 143, add the following paragraph and notes after line 5: Execution of a CLOSE statement causes the processor to | wait for all pending asynchronous data transfer operations for the specified unit to complete. If a CLOSE statement is executed for a unit with | pending asynchronous data transfer operations, that CLOSE statement is considered to be the corresponding wait operation for the READ or WRITE statements that initiated those pending asynchronous data transfer operations, and the CLOSE statement is considered to be a data transfer statement for purposes of end of file, end of record, and error processing. In rule 912 (io-control-spec) (page 144), add: | or ASYNCHRONOUS= or ID = J3/97-216r2 page 5 of 16 Add the following constraints after the constraint on line 19, page 145: Constraint: An ASYNCHRONOUS= specifier shall be present if an ID= specifier is present. Constraint: An ASYNCHRONOUS= specifier shall not be specified with a value of YES if the is an or "*". Constraint: The in an ASYNCHRONOUS= specifier shall have the value YES or NO. Note to the reader: an ID= specifier, typically used in a corresponding WAIT statement, is NOT required in an asynchronous READ or WRITE statement. The user would have to CLOSE the unit (or execute another wait operation) before referencing any storage locations in an input list or namelist, and to NOT define any storage locations referenced by an output list or namelist in an output statement. This allows a knowledgeable user to READ or WRITE massive amounts of data to a file, without ever waiting for completion, as long as they close the file or perform some other wait operation before modifying or referencing any storage locations referenced by an input / output list or namelist. In section 9.4.1.9 (page 147), first sentence, insert synchronous before "nonadvancing", and add the following as the last sentence of that paragraph: | If an ASYNCHRONOUS= specifier with a value of YES is present | in a non-advancing input statement, the storage units specified | in the SIZE= specifier become defined with the count of | characters transfered when the wait operation corresponding | to the non-advancing input statement is executed. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: A CLOSE, INQUIRE or a file positioning statement, as well as a WAIT statement, can be a wait operation (9.3.5). - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - J3/97-216r2 page 6 of 16 Insert a new section: 9.4.1.10 Asynchronous specifier | An ASYNCHRONOUS= specifier with a value of YES indicates that this data transfer operation can be performed asynchronously. Records read or written by asynchronous data transfer statements are read, written, and processed in the same order as they would have been if the data transfer statement did not contain the ASYNCHRONOUS specifier. | An ASYNCHRONOUS= specifier with a value of YES shall not be present in a READ or WRITE statement unless the OPEN statement for the unit referenced in the READ or WRITE | statement contained an ASYNCHRONOUS= specifier with a | value of YES. | When a data transfer statement with an ASYNCHRONOUS= | specifier with a value of YES is executed, the set of | storage units specified by the item list or namelist in the | data transfer statememt, as well as the storage units | specified by the SIZE= specifier, is called the | "pending I/O storage sequence" for this asynchronous data | transfer statement. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Note: a "pending I/O storage sequence" is not necessarily | a contiguous set of storage units. | - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | In a scoping unit containing a data transfer statement with | an ASYNCHRONOUS= specifier with a value of YES, all variables: | 1) contained in the input/output list, or | 2) contained in a namelist specified in the data transfer | statement, or | 3) in a SIZE= specifier, | implicitly receive the ASYNCHRONOUS attribute. | A "pending I/O storage sequence affector variable" is a | variable appearing in a scoping unit where at least one | executable statement is executed while an asynchronous I/O | operation is pending, and: | 1) any reference or definition of the variable in that | instance of that scoping unit references or defines | any storage unit in the pending I/O storage sequence for | a pending asynchronous data transfer operation, or | 2) the variable appears as an actual argument of a procedure | which: | a) is referenced while an asynchronous data transfer | operation is pending, or | b) initiates an asynchronous I/O operation that is still | pending when that procedure returns | and the variable is associated or partially associated | with any storage unit in the pending I/O storage sequence | for that asynchronous data transfer operation. J3/97-216r2 page 7 of 16 | Some pending I/O storage sequence affector variables are | required to have the ASYNCHRONOUS attribute, as described in | section 5.1.2.12. **** need some text about the pending I/O storage sequence **** ceasing to exist, sort of as described in 14.7.6. **** need to describe which procedure calls are prohibited **** when a pending data transfer exists, to avoid problems **** with copyin/copyout. **** need to force a dummy arg which is assumed-shape to be **** associated with the actual arg when the async attribute **** is present and the actual arg is not a array section with **** a vector valued subscript. **** All the edits about READ I/O lists becoming undefined **** until the wait operation need to be rewritten to **** take account of the storage units instead. **** All the edits about WRITE I/O list variables not **** being redefinable until the wait operation need to be **** rewritten to take account of the storage units instead. - - - - - - The following text is no longer part of the edits When a data transfer statement with an ASYNCHRONOUS= specifier with a value of YES is executed, the program shall not execute any statements that would cause any variable in the input / output list, namelist, or the variable specified in a SIZE= specifier to become undefined as described in 14.7.6, until the corresponding wait operation is performed. When a namelist group name is specified in an input data transfer statement with an ASYNCHRONOUS= specifier with a value of YES, any variables in the namelist group that are not defined by an input data transfer statement are not subject to the restrictions described in this paragraph. - - - - - - The preceeding text is no longer part of the edits - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: This restriction prohibits, among other things, a RETURN statement, which causes some local stack variables to become undefined, from being executed when asynchronous I/O is pending for those local variables. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - J3/97-216r2 page 8 of 16 - - - - - - this following block is no longer part of the edits When a data transfer statement with an ASYNCHRONOUS= | specifier with a value of YES is executed, the program shall not execute any statements that would cause the pointer association status of any variable in the input / output list, namelist, or a variable specified in the SIZE= specifier to change, or would cause any such variable to become associated with a different target, as described in 14.6.2, until the corresponding wait operation is performed. When a namelist group name is specified in a data transfer | statement, variables in the namelist group not defined by the input data transfer statement are not subject to the restrictions described in this paragraph. - - - - - - this preceeding block is no longer part of the edits - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | Note: The restrictions in this section ensure that certain | variables (the memory locations associated with those variables actually) referenced in asynchronous data transfer statements must still exist when the corresponding wait operation is performed, including the implicit CLOSE for open units when a program terminates. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this following block is no longer part of the edits When an input data transfer statement with an | ASYNCHRONOUS= specifier with a value of YES is executed, the input list or namelist items, and the variable specified in the SIZE= specifier, if any, become undefined until the corresponding wait operation is executed (9.3.5, 9.5). When a namelist group name is specified in an input data transfer statement, variables in the namelist group not defined by the data transfer statement do not become undefined. When a data transfer statement with an | ASYNCHRONOUS= specifier with a value of YES is executed, the item list or namelist items shall not be redefined until the corresponding wait operation is executed (9.3.5, 9.5). - - - - - - this preceeding block is no longer part of the edits - - - - - - this following block is no longer part of the edits After a READ or WRITE statement with an ASYNCHRONOUS= | specifier with a value of YES is executed, but before the corresponding wait operation is executed, the program shall | not invoke any procedure where any variable or subobject thereof: 1) in the input list or namelist, or 2) specified in a SIZE= specifier, is passed as an actual argument, unless : 1) the actual argument is not an array element where the corresponding dummy argument is an array, and the actual argument passed does not include any storage location defined or referenced by the data transfer statement, or J3/97-216r2 page 9 of 16 2) both the actual argument and the corresponding dummy argument have the ASYNCHRONOUS attribute, the actual argument is not an array section with a vector valued subscript, and (a) both the actual argument and corresponding dummy argument have the POINTER attribute, or (b) the corresponding dummy argument is an assumed shape array, or (c) the actual argument is a whole array that is explicit shape, assumed-size, or allocatable, and the corresponding dummy argument is explicit shape or assumed size. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Note: This restriction prevents interactions between actual arguments passed with so-called copyin/copyout semantics and asynchronous I/O. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - this preceeding block is no longer part of the edits Insert a new section 9.4.1.11: 9.4.1.11 ID= specifier The ID= specifier identifies a variable that is assigned a processor dependent value during the execution of an asynchronous data transfer statement. This value can be used in a WAIT statement to force the processor to wait for a particular data transfer operation to complete. In section 9.4.4, list item (5), change "namelist" to namelist, except that if an ASYNCHRONOUS= specifier | with a value of YES was also present, the entities specified in the input/output list or namelist become undefined In section 9.4.4, list item (8), change "defined" to defined, except that a variable specified in a SIZE= specifier becomes undefined if an ASYNCHRONOUS= specifier with a value of YES was also specified J3/97-216r2 page 10 of 16 - - - - - - this following block is no longer part of the edits In section 9.4.4.4, page 152, before the paragraph that starts "On output ...", insert the following paragraphs: | If an ASYNCHRONOUS= specifier with a value of YES is specified on an input statement, the list items or namelist variables, and the variable specified in the SIZE= specifier, if any, become undefined until the corresponding wait operation is executed (9.3.5, 9.5). When a namelist group name is specified in an input data transfer statement, variables in the namelist group not defined by the input statement do not become undefined. - - - - - - this preceeding block is no longer part of the edits - - - - - - this following block is no longer part of the edits In section 9.4.4.4, page 152, after the paragraph that starts "On output ...", insert the following paragraphs: | If an ASYNCHRONOUS= specifier with a value of YES is specified on an output statement, the list items or namelist variables shall not be redefined until the corresponding wait operation is executed (9.3.5, 9.5). - - - - - - this preceeding block is no longer part of the edits | If an ASYNCHRONOUS= specifier with a value of YES is specified in a data transfer statement, data transfers may occur during execution of the statement, during execution of the corresponding wait operation, or anywhere in-between. The data transfer operation is considered to be a pending data transfer operation until a corresponding wait operation is performed. When a data transfer operation is performed asynchronously, any errors that would have caused the ERR= branch on a synchronous READ or WRITE to be taken, and the IOSTAT variable to be defined with a non-zero value, may instead occur during execution of the corresponding wait operation (a WAIT, CLOSE, INQUIRE or file positioning statement) and take the ERR= branch of that wait operation instead. If an ID= specifier is not present in the initiating READ or WRITE statement, the errors may occur during the execution of any subsequent data transfer statement for that same unit, and not just during the corresponding wait operation. J3/97-216r2 page 11 of 16 Insert a new section 9.5, and renumber every section thereafter appropriately: 9.5 WAIT statement Execution of a WAIT statement causes the processor to wait for one of more previously initiated (pending) asynchronous data transfers to complete. R919 is WAIT () R920 is [UNIT = ] or IOSTAT = or ERR =