taskarray Task control array
5.2 SCOPES AND PROTECTION
This subsection discusses CFT77 and CFT implementations of COMMON and TASK COMMON, private data, and locks.
5.2.1 SHARED DATA
Multitasked programs written in Fortran should keep shared data in COMMON blocks. Space for such data is statically allocated at load time, and the variable contents are available for the life of the program. When a subroutine is called, any COMMON variables maintained in registers are stored into memory before the call. (Local data can remain in registers.)
*******************************************************
CAUTION
You should not pass COMMON variables as parameters between subroutines in a multitasking system. These variables, even if they are located in COMMON blocks in a calling subroutine, are not treated as COMMON
variables in the called subroutine, and the compiler may perform optimizations that lead to unexpected problems.
*******************************************************
5.2.2 TASK COMMON DATA
Data that is global between subroutines, but private to a task, should be kept in TASK COMMON blocks. TASK COMMON is a Cray Fortran language
extension that operates to ensure that, when a program unit with TASK COMMON blocks is compiled, each task has its own copy of each TASK COMMON block used in the task. These blocks are set up when the task begins and are released when the task completes. Be sure to specify stack storage when using TASK COMMON (see subsection 5.2.3, Private Data); with static allocation, TASK COMMON blocks are treated the same as regular COMMON blocks. The format for a TASK COMMON declaration in Fortran is as follows:
TASK COMMON Icbnamel
nlist
cbname Task common block name. TASK COMMON must be named.
SR-0222 D 5-9
nlist
List of variable names, array names, and array declarators, separated by commas.Variables in TASK COMMON blocks cannot be used in SAVE or DATA statements or with NAMELIST I/O. Except for these restrictions, these variables can be used-in the same way as any other variables declared in COMMON.
5.2.3 PRIVATE DATA
Multitasked programs written in Fortran should keep private data in a stack. You can accomplish this by compiling these programs with the following parameter on the CFT or CFT77 control statement:
CFT,ALLOC=STACK, ..•
CFT77,ALLOC=STACK, ..•
or the corresponding UNICOS command line:
cft -a stack •••
cft77 -a stack •.•
When compiling in this mode, the compiler allocates and accesses private variables from a stack frame specific to the subroutine invocation. In this manner, private variables are truly private to the task executing the subroutine; they do not conflict with any other task executing the subroutine. (Not all private variables will necessarily reside on the stack; the compiler may choose to use registers during the subroutine and never store the variable in memory. This is especially true for CFT77.)
•• *.* •••••••• * •••••••••••••••••••••••••• * ••••••••••••••
CAUTION
Using SAVE or DATA statements causes the referenced variables to be assigned to static m~mory locations, regardless of the setting of the ALLOe parameter.
CFT77 and CFT generate a warning message for each
variable in a DATA statement that is not also in a SAVE statement if stack allocation is in effect •
• ** •• ***.* •• *** ••• ** •••• * •• *.*.*** •••••• * •••• *.* •••• ***
Ensure that CRI and user libraries used in multitasking mode have been compiled or assembled to use a stack. The CRI site analyst handles the CRI libraries, but you are responsible for correctly compiling or
assembling your own libraries.
5-10 SR-0222 D
Stack mode introduces some additional overhead to subroutine linkages.
This overhead results from the need to allocate the stack space at run time. The stack management routines may be required to make expensive system requests to obtain more space. LDR and SEGLDR support several parameters that can reduce the possibility and number of such calls at the expense of obtaining memory space before i t is needed. (See
subsection 5.4, Tuning, for more information.)
Not all code needs to have its private variables allocated on a stack.
For example, subroutines that are nonreentrant or serially reusable can be compiled with the STATIC option.
Code with statically allocated private variables can be combined with stack-allocated private variables in a user program, but you should do this carefully. If two tasks use a subroutine with statically allocated private variables at the same time, unpredictable results and
intermittent errors can occur. You should completely compile and test a program with stack-allocated private variables before making the effort to introduce modules recompiled with statically allocated private
variables.
5.2.4 LOCKS
Locks are the macrotasking facility for monitoring critical regions of code. The operation of locks follows the general description provided in section 2, Concepts.
Integer variables representing locks are called
lock variables.
Lock variables should be kept in COMMON blocks to ensure their residency in Central Memory across subroutine calls. Henceforth, the termslock
andlock variable
are used interchangeably.Example:
PROGRAM MULTI
INTEGER LKINPUT,LKOUTPUT,LKCALL REAL INDATA(20000),OUTDATA(20000) COMMON ICBINPUTI LKINPUT,INDATA COMMON ICBOUTPUTI LKOUTPUT,OUTDATA COMMON IMISCI LKCALL
END
In this example, two locks were placed in the same C01~ON blocks- as the data to which they correspond. This is not necessary, but i t makes the program more understandable.
SR-0222 D 5-11
5.2.5 LOCKASGN
LOCKASGN identifies an integer variable that the program intends to use as a lock. You must call the LOCKASGN subroutine for each lock variable before the lock variable is used with any of the other lock subroutines.
A lock is given an initial state of cleared or off.
The optional second argument is for use by library subroutines that require a lock variable internally. The argument ensures that a lock variable is assigned only the first time LOCKASGN is called for that lock. Hence, if multiple tasks call the subroutine, the different invocations do not reassign the same lock.
Format:
CALL LOCKASGN
(name[,value)
name
value
Integer variable to be used as a lock. The library stores an identifier into this variable. You must not modify a lock variable after the call to LOCKASGN until that variable is released by a call to LOCKREL.
The initial integer value of the lock variable. LOCKASGN stores an identifier into a variable only if the variable still contains the value. If
you
do not specifyvalue,
an identifier is unconditionally stored into the variable.
Example:
5-12
PROGRAM MULTI
INTEGER LKINPUT,LKOUTPUT,LKCALL,ITID(2) REAL INDATA(20000),OUTDATA(20000) COMMON
COMMON
ICBINPUTI LKINPUT,INDATA ICBOUTPUTI LKOUTPUT,OUTDATA COMMON IMISCI
EXTERNAL SUBl
LKCALL
CALL LOCKASGN (LKINPUT) CALL LOCKASGN (LKOUTPUT) CALL LOCKASGN (LKCALL) ITID(l)
=
2CALL TSKSTART(ITID,SUBl) CALL SUB1
END
SR-0222 D
SUBROUTINE SUB1 COMMON ILOCK11 LOCK1 DATA LOCK1 1-11
CALL LOCKASGN (LOCK1,-1) END
*******************************************************
CAUTION
If a lock variable is not assigned before use in any of the other lock subroutines, the results are
unpredictable. One common symptom is an abort with an ERROR EXIT and a P address of zero.
*******************************************************
5.2.6 LOCKON
LOCKON sets a lock and returns control to the calling task. If the lock is already set, the task is suspended until the lock is cleared by
another task. In either case, the task sets the lock when i t next
resumes execution of user code. This means that placing LOCKON before a critical region ensures that the code in that region is executed only when the task has unique access to the lock.
Format:
CALL LOCKON
(name)
name
Integer variable used as a lock5.2.7 LOCKOFF
LOCKOFF clears a lock and returns control to the calling task. The act of clearing the lock may allow another task to resume execution, but this is transparent to the task calling LOCKOFF.
SR-0222 D 5-13