HP OpenVMS Systems Documentation |
OpenVMS Programming Concepts Manual
6.6.2 Introducing Local and Common Event Flag Numbers and Event Flag ClustersEach event flag has a unique number; event flag arguments in system service calls refer to these numbers. For example, if you specify event flag 1 in a call to the SYS$QIO system service, then event flag 1 is set when the I/O operation completes. To allow manipulation of groups of event flags, the flags are ordered in clusters of 32 numbers corresponding to bits 0 through 31 (<31:0>) in a longword. The clusters are also numbered from 0 to 4. The range of event flag numbers encompasses the flags in all clusters: event flag 0 is the first flag in cluster 0, event flag 32 is the first flag in cluster 1, and so on. Event flags are divided into five clusters: two for local event flags and two for common event flags. There is also a special local cluster 4 that supports EFN 128.
Table 6-4 summarizes the ranges of event flag numbers and the clusters to which they belong. The same system services manipulate flags in either local and common event flag clusters. Because the event flag number implies the cluster number, you need not specify the cluster number when you call a system service that refers to an event flag. When a system service requires an event flag cluster number as an argument, you need only specify the number of any event flag in the cluster. Thus, to read the event flags in cluster 1, you could specify any number in the range 32 through 63.
6.6.3 Using Event Flag Zero (0)Event flag 0 is the default event flag. Whenever a process requests a system service with an event flag number argument, but does not specify a particular flag, event flag 0 is used. Therefore, event flag 0 is more likely than other event flags to be used incorrectly for multiple concurrent requests.
Code that uses any event flag should be able to tolerate spurious sets,
assuming that the only real danger is a spurious clear that causes a
thread to miss an event. Since any system service that uses an event
flag clears the flag, there is a danger that an event which has occured
but has not been responded to is masked which can result in a hang. For
further information, see the SYS$SYNCH system service in OpenVMS System Services Reference Manual: GETUTC--Z.
The combination of EFN$C_ENF and a status block should be used with the
wait form of system services, or with SYS$SYNCH system service.
EFN$C_ENF does not need to be initialized, nor does it need to be
reserved or freed. Multiple threads of execution may concurrently use
EFN$C_ENF without interference as long as they use a unique status
block for each concurrent asynchronous service. When EFN$C_ENF is used
with explicit event flag system services, it performs as if always set.
You should use EFN$C_ENF to eliminate the chance for event flag overlap.
Local event flags are automatically available to each program. They are not automatically initialized. However, if an event flag is passed to a system service such as SYS$GETJPI, the service initializes the flag before using it. When using local event flags, use the event flag routines as follows:
The following Fortran example uses LIB$GET_EF to choose a local event flag and then uses SYS$CLREF to set the event flag to 0 (clear the event flag). (Note that run-time library routines require an event flag number to be passed by reference, and system services require an event flag number to be passed by value.)
6.6.5.1 Example of Event Flag ServicesLocal event flags are used most commonly with other system services. For example, you can use the Set Timer (SYS$SETIMR) system service to request that an event flag be set either at a specific time of day or after a specific interval of time has passed. If you want to place a process in a wait state for a specified period of time, specify an event flag number for the SYS$SETIMR service and then use the Wait for Single Event Flag (SYS$WAITFR) system service, as shown in the C example that follows:
In this example, the daytim argument refers to a
64-bit time value. For details about how to obtain a time value in the
proper format for input to this service, see Chapter 27.
Common event flags are manipulated like local event flags. However, before a process can use event flags in a common event flag cluster, the cluster must be created. The Associate Common Event Flag Cluster (SYS$ASCEFC) system service creates a common event flag cluster. ( Section 6.6.6.1 explains the format of this string.) By calling SYS$ASCEFC, other processes in the same UIC group can establish their association with the cluster so they can access flags in it. Each process that associates with the cluster must use the same name to refer to it; the SYS$ASCEFC system service establishes correspondence between the cluster name and the cluster number that a process assigns to the cluster. The first program to name a common event flag cluster creates it; all flags in a newly created cluster are clear. Other processes on the same OpenVMS cluster node that have the same UIC group number as the creator of the cluster can reference the cluster by invoking SYS$ASCEFC and specifying the cluster name. Different processes may associate the same name with different common event flag numbers; as long as the name and UIC group are the same, the processes reference the same cluster. Common event flags act as a communication mechanism between images executing in different processes in the same group on the same OpenVMS cluster node. Common event flags are often used as a synchronization tool for other, more complicated communication techniques, such as logical names and global sections. For more information about using event flags to synchronize communication between processes, see Chapter 3. If every cooperating process that is going to use a common event flag cluster has the necessary privilege or quota to create a cluster, the first process to call the SYS$ASCEFC system service creates the cluster. The following example shows how a process might create a common event flag cluster named COMMON_CLUSTER and assign it a cluster number of 2:
Other processes in the same group can now associate with this cluster.
Those processes must use the same character string name to refer to the
cluster; however, the cluster numbers they assign do not have to be the
same.
The name argument to the Associate Common Event Flag Cluster (SYS$ASCEFC) system service identifies the cluster that the process is creating or associating with. The name argument specifies a descriptor pointing to a character string. Translation of the name argument proceeds in the following manner:
For example, assume that you have made the following logical name assignment:
Assume also that your program contains the following statements:
The following logical name translation takes place:
There are two exceptions to the logical name translation method discussed in this section:
6.6.6.2 Temporary Common Event Flag ClustersCommon event flag clusters are either temporary or permanent. The perm argument to the SYS$ASCEFC system service defines whether the cluster is temporary or permanent.
Temporary clusters require an element of the creating process's quota
for timer queue entries (TQELM quota). They are deleted automatically
when all processes associated with the cluster have disassociated.
Disassociation can
be performed explicitly with the Disassociate Common Event Flag Cluster
(SYS$DACEFC) system service, or implicitly when the image that called
SYS$ASCEFC exits.
If you have the PRMCEB privilege, you can create a permanent common event flag cluster (set the perm argument to 1 when you invoke SYS$ASCEFC). A permanent event flag cluster continues to exist until it is marked explicitly for deletion with the Delete Common Event Flag Cluster (SYS$DLCEFC) system service (requires the PRMCEB privilege). Once a permanent cluster is marked for deletion, it is like a temporary cluster; when the last process that associated with the cluster disassociates from it, the cluster is deleted. In the following examples, the first program segment associates common event flag cluster 3 with the name CLUSTER and then clears the second event flag in the cluster. The second program segment associates common event flag cluster 2 with the name CLUSTER and then sets the second event flag in the cluster (the flag cleared by the first program segment).
For clearer code, rather than using a specific event flag number, use one variable to contain the bit offset you need and one variable to contain the number of the first bit in the common event flag cluster that you are using. To reference the common event flag, add the offset to the number of the first bit. The following examples accomplish the same result as the preceding two examples:
Common event flags are often used for communicating between a parent process and a created subprocess. The following parent process associates the name CLUSTER with a common event flag cluster, creates a subprocess, and then waits for the subprocess to set event flag 64:
REPORTSUB, the program executing in the subprocess, associates the name CLUSTER with a common event flag cluster, performs some set of operations, sets event flag 64 (allowing the parent to continue execution), and continues executing:
6.6.7 Wait Form Services and SYS$SYNCHA wait form system service is a variant of an asynchronous service in which there is a service request and then a wait for the completion of the request. The SYS$SYNCH system service checks the completion status of a system service that completes asynchronously. For reliable operation in most applications, the service whose completion status is to be checked must have been called with the efn and iosb arguments specified. The SYS$SYNCH service uses the event flag and I/O status block of the service to be checked.
Compaq recommends that only EFN$C_ENF be used for concurrent use of
event flags.
The following three system services place the process or thread in a wait state until an event flag or a group of event flags is set:
Another system service that accepts an event flag number as an argument is the Queue I/O Request (SYS$QIO) system service. The following example shows a program segment that issues two SYS$QIO system service calls and uses the SYS$WFLAND system service to wait until both I/O operations complete before it continues execution:
|